/*******************************************************************************
Copyright by Telesoft Europe AB 1990, 1991.
Copyright by Telelogic Malmoe AB 1991, 1992, 1993, 1994.
Copyright by Telelogic AB 1994 - 2002.
This Program is owned by Telelogic and is protected by national
copyright laws and international copyright treaties. Telelogic
grants you the right to use this Program on one computer or in
one local computer network at any one time.
Under this License you may only modify the source code for the purpose
of adapting it to your environment. You must reproduce and include
any copyright and trademark notices on all copies of the source code.
You may not use, copy, merge, modify or transfer the Program except as
provided in this License.
Telelogic does not warrant that the Program will meet your
requirements or that the operation of the Program will be
uninterrupted and error free. You are solely responsible that the
selection of the Program and the modification of the source code
will achieve your intended results and that the results are actually
obtained.
*******************************************************************************/

/*
# clearcase sctmon.c@@/main/113 : 2002/04/15 pon
*/

/*---+---------------------------------------------------------------
     Include Files
-------------------------------------------------------------------*/

#include "scttypes.h"
#include "sctlocal.h"

#define XNOTINCLUDEFILE (XSYSD CommandFile == NULL)

/************************ XREADANDWRITEF ***************************/
#ifdef XREADANDWRITEF


/*---+---------------------------------------------------------------
     xInitReadAndWrite
-------------------------------------------------------------------*/
void xInitReadAndWrite (void)
{
  xSysD.InteractionLog.Active = (xbool)0;
  xSysD.InteractionLog.File = NULL;
  xSysD.CommandLog.Active = (xbool)0;
  xSysD.CommandLog.File = NULL;
  xSysD.CommandFile = (xCommandFileNode)0;
  xSysD.WriteSortLevel = 0;
  xSysD.xInputLine = xSysD.xInputLineVar;
  xSysD.xInputLine[0] = '\0';
  xInputPos = xSysD.xInputLine;
  xSysD.xSaveLine = (char *)0;
  xSysD.First_Call = (xbool)1;
  xSysD.xUse_ASN1_Syntax = (xbool)0;
  xSysD.xUse_NewRef_Syntax = (xbool)0;
  xSysD.xUse_DeRef_Syntax = (xbool)0;
  xSysD.xValue_Syntax = (xbool)0;
  xSysD.xIntegerOutputMode = 0;
#ifdef X_LONG_INT
  strcpy(xSysD.xPrintIntFormat, "%ld");
  strcpy(xSysD.xScanIntFormat, "%ld");
#else
  strcpy(xSysD.xPrintIntFormat, "%d");
  strcpy(xSysD.xScanIntFormat, "%d");
#endif
#if defined (XTRACE) || defined (THREADED_XTRACE)
  xSysD.xSilent = 0;
#endif
  xSysD.SystemName = "";

  /* Set up trace default values */
#if defined(XTRACE) || defined(XGRTRACE)
  xSysD.xNoTraceOn = 0;
#endif
#if defined (XTRACE) || defined (THREADED_XTRACE)
  xSysD.Trace_Default = 4;
#endif
#ifdef XGRTRACE
  xSysD.GRTrace = 0;
#endif
#ifdef XMSCE
  xSysD.MSCETrace = 1;
  xSysD.MSCLogStarted = 0;
  xSysD.GlobalProcessInstanceId = 0;
  xSysD.GlobalSignalInstanceId = 0;
  xSysD.VoidProcessInstanceId = 0;
  xSysD.DoingReset = 0;
#ifdef XMSCEINIT
  if (! xSysD.MSCLogStarted)  {
    if (xStartMSC ()) {
      xSysD.MSCLogStarted = 1;
      xMSCEInit ();
      xSysD.MSCSymbolLevel = 0;    /* could probably be defined as argv[] */
    }
  }
#endif
#endif

  /* Set up trace default values if target simulation */
#if defined(TARGETSIM) && defined(XCONNECTPM)
  if (xSysD.xNoticeBoard.TargetParam == 3 ||
      xSysD.xNoticeBoard.TargetParam == 2) {
#if defined(XTRACE) || defined(XGRTRACE) || defined (THREADED_XTRACE)
  xSysD.xNoTraceOn = 1;
#endif
#if defined (XTRACE) || defined (THREADED_XTRACE)
  xSysD.Trace_Default = 0;
#endif
#ifdef XGRTRACE
  xSysD.GRTrace = 0;
#endif
#ifdef XMSCE
  xSysD.MSCETrace = 0;
#endif
  }
#endif
      /* TARGETSIM && XCONNECTPM */

#ifdef XMONITOR
#ifndef XNOSELECT
  xSysD.xDoLoopForInput = (xbool)1;
  xSysD.xDoCheckForInput = (xbool)1;
#else
  xSysD.xDoLoopForInput = (xbool)0;
#endif
#endif
#ifdef XSIMULATORUI
  xSysD.SESIMUICOMFlag = 0;
  xSysD.SESIMUICOMStr[0] = '\0';
  if (xSysD.xNoticeBoard.SimulatorUIStarted != 0)
    xSysD.SESIMUICOMInput = 1;
  else
    xSysD.SESIMUICOMInput = 0;
#endif
}

#ifdef XSIMULATORUI
static char *xTrStr = (char *)0;
static char *xTrStrP = (char *)0;

/* Macros to print on xTrStr */
#define xStrToAppend(p,s,to) \
 {\
    char *xxi = (s);\
    while (*xxi != '\0' && p != to) *p++ = *xxi++; \
    *p = '\0';\
 }
#define xStrAppend(p,s) \
 {\
    char *xxxi = (s);\
    while (*xxxi != '\0') *p++ = *xxxi++; \
    *p = '\0';\
 }
#define MAX_PRINT_BUFF 5000    /* size of xTrStr */
#define TRESET {xTrStrP = &xTrStr[0];xTrStr[0] = 0;}
#define TPRINTF(str) \
 { \
  if (xTrStrP - xTrStr + (int)strlen(str) < MAX_PRINT_BUFF) { \
    xStrAppend(xTrStrP,str); \
  } \
  else { \
    char *to = xTrStr + MAX_PRINT_BUFF - 4; \
    if (to > xTrStrP) \
      xStrToAppend(xTrStrP,str,to); \
    xTrStrP = to; \
    xStrAppend(xTrStrP, "..."); \
  } \
 }

static int PrintToxTrStr = 0; /* used to save output on xTrStr */
static int CommandSourcePId = 0;

/*---+---------------------------------------------------------------
     xHandlePMInternCommand
-------------------------------------------------------------------*/
char *xHandlePMInternCommand(
  int   sender,
  char *mess,
  int   size)
{
  xSortIdNode   SortNode;
  tSDLTypeInfo *TypeNode;
  xbool         EmptyInput;

  if ( ! mess )
    return "Empty message";

  if (mess[size - 1] != '\0')  /* Should end with extra character */
    mess[size - 1] = '\0';
  if (xTrStr == (char *)0)
    xTrStr = (char *)xAlloc((xptrint)MAX_PRINT_BUFF);
  PrintToxTrStr = 1;
  TRESET;
  TPRINTF("0 ");
  if (mess[0] != '[') {
    xHandleSimUIMessage(sender, mess, size);
    CommandSourcePId = sender;
    return (char *)0;
  }
  if (mess[1] == '1') {
    xSignalIdNode SignalNode;
    xIdNode       xIdNodeSigPar;
    int           count = 0;

    xChangeInputLine((mess + 2));
    /* Read signal name */
    SignalNode = (xSignalIdNode)xGetIdNodeInECSet("Signal name : ",
                                                  xSignalOrTimer,
                                                  xSymbolTableRoot,
                                                  &EmptyInput, (xbool)0, NULL);
    if (SignalNode) {
      if (SignalNode->EC == xRemotePrdEC)
        SignalNode = (xSignalIdNode)SignalNode->Suc;  /* Go to pCALL signal */
      for (xIdNodeSigPar = SignalNode->First;
           xIdNodeSigPar != (xIdNode)0;
           xIdNodeSigPar = xIdNodeSigPar->Suc) {
        PRINTF3("%d.(%s)\n", ++count,
                xWriteEntity((xIdNode)((xVarIdNode)xIdNodeSigPar)->TypeNode->
                             SortIdNode));
      }
#ifdef DEBUG
      if (count == 1 && ((xVarIdNode)(SignalNode->First))->
                                     TypeNode->TypeClass == type_SDL_Struct) {
        /* If the only parameter is a struct show struct attributes instead */
        TRESET;
        TPRINTF("0 ");
        for (xIdNodeSigPar = ((xVarIdNode)(SignalNode->First))->
               TypeNode->SortIdNode->First;
             xIdNodeSigPar != (xIdNode)0;
             xIdNodeSigPar = xIdNodeSigPar->Suc) {
          PRINTF3("%s.(%s)\n", ((xVarIdNode)xIdNodeSigPar)->Name,
                  xWriteEntity((xIdNode)((xVarIdNode)xIdNodeSigPar)->
                               TypeNode->SortIdNode));
        }
      }
#endif
    }
    xRestoreInputLine();
  }
  else if (mess[1] == '2') {
    void       *TempVar;

    xChangeInputLine((mess + 2));
    /* Read sort name */
    SortNode = (xSortIdNode)xGetIdNodeInECSet("Sort name : ", 
                                              1L<<((long)xSortEC),
                                              (xIdNode)xSymbolTableRoot,
                                              &EmptyInput, (xbool)0, NULL);
    if (SortNode) {
      TypeNode = SortNode->TypeInfo;
      TempVar = (void *)XALLOC((xptrint)TypeNode->SortSize, TypeNode);
#ifdef __cplusplus
      if (TypeNode->TypeClass == type_SDL_Struct &&
          TypeNode->OpFuncs != 0 &&
          TypeNode->OpFuncs->ReadFunc != 0) {
	PRINTF2("1 /*%s()*/ ", TypeNode->Name);
      }
#endif
      xxWriteSort(TempVar, TypeNode);
      XFREE(&TempVar,TypeNode->SortSize);
    }
    xRestoreInputLine();
  }
  else if (mess[1] == '3') {
    xChangeInputLine((mess + 2));
    /* Read sort name */
    SortNode = (xSortIdNode)xGetIdNodeInECSet("Sort name : ", 
                                              1L<<((long)xSortEC),
                                              (xIdNode)xSymbolTableRoot,
                                              &EmptyInput, (xbool)0, NULL);
    if (SortNode) {
      TypeNode = SortNode->TypeInfo;
      while (TypeNode->TypeClass == type_SDL_Syntype)
        TypeNode = ((tSDLGenInfo *)TypeNode)->CompOrFatherSort;
      xMonListIdNodeECSet(1L<<((long)xLiteralEC), (xIdNode)TypeNode->SortIdNode,
                          (xIdNode)0, (xbool)0);
    }
    xRestoreInputLine();
  }
  else if (mess[1] == '4') {
    int         i;

    xChangeInputLine((mess + 2));
    /* Read sort name */
    SortNode = (xSortIdNode)xGetIdNodeInECSet("Sort name : ", 
                                              1L<<((long)xSortEC),
                                              (xIdNode)xSymbolTableRoot,
                                              &EmptyInput, (xbool)0, NULL);
    if (SortNode) {
      TypeNode = SortNode->TypeInfo;
      if (TypeNode->TypeClass == type_SDL_Struct) {
        PRINTF("(.\n.)\n");
        for (i = 0; i < ((tSDLStructInfo *)TypeNode)->NumOfComponents; i++) {
          PRINTF3("%s.(%s)\n", ((tSDLStructInfo *)TypeNode)->Components[i].Name,
                  xWriteEntity((xIdNode)((tSDLStructInfo *)TypeNode)->
                               Components[i].CompSort->SortIdNode));
        }
      }
      else if (TypeNode->TypeClass == type_SDL_Array ||
               TypeNode->TypeClass == type_SDL_Carray) {
        long int I;
        PRINTF("(: \n :)\n");
        for (I = 0; I < ((tSDLArrayInfo *)TypeNode)->Length; I++) {
          PRINTF3("%ld.(%s)\n",
                  I + ((tSDLArrayInfo *)TypeNode)->LowestValue,
                  xWriteEntity((xIdNode)(((tSDLArrayInfo *)TypeNode)->CompSort->
                                         SortIdNode)));
        }
      }
    }
    xRestoreInputLine();
  }
  PrintToxTrStr = 0;
  return xTrStr;
}
#endif


/*---+---------------------------------------------------------------
     xPrintString
-------------------------------------------------------------------*/
void xPrintString (char * Str)
{
#ifdef XMONITOR
  if (xSysD.xRestoringState)
    return;
#endif

#ifdef XSIMULATORUI
  if (PrintToxTrStr) {
    TPRINTF(Str);
    return;
  }

  if (xSysD.InteractionLog.Active &&
      ! strcmp(xSysD.InteractionLog.Filename, "xNoEcho.log") &&
                                    /* No output if logging on "xNoEcho.log" */
      strcmp(Str, "\nCommand : ") ) /* but do output Command-prompt */
    ;
  else if (xSysD.xNoticeBoard.SimulatorUIStarted) {
#ifdef XMONITOR
    if ( ! xSysD.xSavingState )
#endif
      xSendPrintString(Str);
  } else {
#endif
#ifdef XMONITOR
    if ( ! xSysD.xSavingState ) {
      printf("%s", Str);
#ifdef GCCWIN
      fflush(stdout);
#endif
    }
#else  /* XMONITOR */
    printf("%s", Str);
#ifdef GCCWIN
    fflush(stdout);
#endif
#endif /* XMONITOR */
#ifdef XSIMULATORUI
  }
#endif
  if (xSysD.InteractionLog.Active)
    fprintf(xSysD.InteractionLog.File, "%s", Str);
}


#ifndef XNOSELECT
#if defined(XENV) || defined(XCONNECTPM)
/*---+---------------------------------------------------------------
     xLoopForInput
-------------------------------------------------------------------*/
void xLoopForInput (void)
{
  long KeyboardTimeout = 100000;   /* Wait 100 milliseconds */

#ifndef XENV
  if ( ! xSysD.xNoticeBoard.PMConnected )
    return;
#endif
#ifdef XSIMULATORUI
  if (xSysD.xNoticeBoard.SimulatorUIStarted) {
    if (xSysD.SESIMUICOMFlag) /* Command already received */
      return;
    xLoopForMessage();
    return;
  }
  while ( ! xCheckForKeyboardInput(KeyboardTimeout) &&
          ! xSysD.SESIMUICOMFlag) {
#else
#ifndef THREADED_XTRACE
  while ( ! xCheckForKeyboardInput(KeyboardTimeout) ) {
#endif /* THREADED_XTRACE */
#endif
#ifdef XENV
# ifdef XMONITOR
    if ( xSysD.xInEnvOn )
# endif
      xInEnv(SDL_Time_Lit( (xint32)0, (xint32)0 ));
#endif
#if defined(XCONNECTPM)
    xInPM();
#endif
#ifndef THREADED_XTRACE
  }
#endif /* THREADED_XTRACE */
  return;
}
#endif
        /* XENV || XCONNECTPM */
#endif
        /* XNOSELECT */


#ifdef XSIMULATORUI
/*---+---------------------------------------------------------------
     xHandleSimUIMessage
-------------------------------------------------------------------*/
void xHandleSimUIMessage(
  int   sender,
  char *mess,
  int   size)
{
  int len;

  if (xSysD.SESIMUICOMFlag) {  /* Command already received */
    xPrintString("******* Previous command is lost:\n");
    xPrintString(xSysD.SESIMUICOMStr);
#ifdef XDEBUGPM
    printf("ERROR in xHandleSimUIMessage: previous command is lost:\n");
    printf("%s", xSysD.SESIMUICOMStr);
#endif
  }
  len = strlen(xSysD.SESIMUICOMStr);
  if (len > 0) {
    xSysD.SESIMUICOMStr[len++] = ' ';
    xSysD.SESIMUICOMStr[len] = '\0';
  }
  if (len+size >= MAX_READ_LENGTH) {
    xPrintString("******* Command too long\n");
    xPrintString(mess);
#ifdef XDEBUGPM
    printf("ERROR in xHandleSimUIMessage: command too long\n");
    printf("%s", mess);
#endif
    size = MAX_READ_LENGTH - len - 1;
    if (size > 0) {
      memcpy(xSysD.SESIMUICOMStr + len, mess, size);
      xSysD.SESIMUICOMStr[len+size-1] = '\n';
      xSysD.SESIMUICOMStr[len+size] = '\0';
    }
    xSysD.SESIMUICOMFlag = 1;
    return;
  }

  memcpy(xSysD.SESIMUICOMStr + len, mess, size);
  if (sender != XSYSD xNoticeBoard.SimulatorUIStarted) {
    /* Message from e.g. dynamic menues in SDL Editor */
    if (xSysD.SESIMUICOMStr[len+size-2] != '\n') {
      xSysD.SESIMUICOMStr[len+size-1] = '\n';
      xSysD.SESIMUICOMStr[len+size] = '\0';
    }
    xSysD.SESIMUICOMFlag = 1;
#ifdef XDEBUGPM
    printf("%s", xSysD.SESIMUICOMStr);
#endif
  }
  else if (xSysD.SESIMUICOMStr[len+size-2] == '\n')
    xSysD.SESIMUICOMFlag = 1;
}
#endif


/*---+----------------------------------------------------------------
     Sim_Script_Macro_Expander
---------------------------------------------------------------------*/
static int Sim_Script_Macro_Expander(void)
{
  int   ArrayPos = 0;     /*Position where substitute variable is stored*/
  char  Buffer1[MAX_READ_LENGTH];
  char  *str = xSysD.xInputLine;
  char  *str2 = Buffer1;
  char  *str3;
  int   Index2 = 0;
  int   isMacro = 0;

  while ((Index2 < MAX_READ_LENGTH - 1 ) && *str != '\0') {
    if (*str != '$') {
      *(str2++) = *(str++);
      Index2++;
    }
    else {
      isMacro = 0;
      if (*(str+1) >= '1' && *(str+1) <= '9') {
        if (*(str+2) < '0' || *(str+2) > '9') {
          ArrayPos = *(str+1) -'0';
          isMacro = 1;
        }
        else if (*(str+3) < '0' || *(str+3) > '9') {
          ArrayPos = *(str+1) - '0';
          ArrayPos = (ArrayPos * 10) + *(str+2) - '0';
          isMacro = 1;
        }
      }
      if (isMacro && xSysD.CommandFile->A[ArrayPos-1]) {
        str3 = xSysD.CommandFile->A[ArrayPos-1];
        while ((Index2 < MAX_READ_LENGTH - 1 ) && *str3 != '\0') {
          *(str2++) = *(str3++);
          Index2++;
        }
        if (ArrayPos < 10) {
          str = str + 2;
        }
        else {
          str = str + 3;
        }
      }
      else {
        *(str2++) = *(str++);
        Index2++;
      }
    }
  }
  *str2 = '\0';
  strcpy(xSysD.xInputLine, Buffer1);
  return Index2;
}


/*---+---------------------------------------------------------------
     xNextLine
-------------------------------------------------------------------*/
void xNextLine (void)
{
  int              Index = 0;
  int              MetaChar = 0;
  xCommandFileNode RemCF;
  int              i = 0;

#ifndef XSIMULATORUI
  TryAgain :
#endif
  if (xSysD.CommandFile) {
    while ((Index < MAX_READ_LENGTH - 1) &&
           (MetaChar = fgetc(xSysD.CommandFile->File)) != '\n' &&
           MetaChar != EOF)
      xSysD.xInputLine[Index++] = (char)MetaChar;
    xSysD.xInputLine[Index] = '\0';
    if (strchr(xSysD.xInputLine, '$')) {
      Index = Sim_Script_Macro_Expander();
    }
    if ( MetaChar == '\n' ) {
      if (Index > 0 && xSysD.xInputLine[Index - 1] == '\r')
        Index--;                               /* PC file => skip extra CR */
      xSysD.xInputLine[Index++] = '\n';
    }
    else if ( MetaChar == EOF ) {
      fclose(xSysD.CommandFile->File);
      RemCF = xSysD.CommandFile;
      xSysD.CommandFile = RemCF->Next;
      for (i=0; i<99; i++) {
        if (RemCF->A[i])
          xFree((void **)&RemCF->A[i]);
      }
      xFree((void **)&RemCF);
#ifdef XSIMULATORUI
      /* Use line read so far */
      xSysD.xInputLine[Index++] = '\n';
      xSysD.xInputLine[Index] = '\0';
      xPrintString(xSysD.xInputLine);
      if (xSysD.CommandLog.Active)
        fprintf(xSysD.CommandLog.File, "%s", xSysD.xInputLine);
      /* Test if last line read is all white space */
      xInputPos = xSysD.xInputLine;
      while (*xInputPos == '\n' || *xInputPos == ' ' || *xInputPos == '\t')
        xInputPos++;
      if (*xInputPos == '\0') {
        Index = 0;
        xSysD.xInputLine[Index++] = '-';
        xSysD.xInputLine[Index++] = '\n';
        xSysD.xInputLine[Index] = '\0';
      }
      xInputPos = xSysD.xInputLine;
      return;
#else
      goto TryAgain;
#endif
    }
  }
#ifdef XSIMULATORUI
  else if (xSysD.SESIMUICOMFlag) {
    Index = strlen(xSysD.SESIMUICOMStr);
    strcpy(xSysD.xInputLine, xSysD.SESIMUICOMStr);
    xSysD.SESIMUICOMFlag = 0;
    xSysD.SESIMUICOMStr[0] = '\0';
    xSysD.SESIMUICOMInput = 1;
  }
  else if (xSysD.SESIMUICOMInput) {
#ifndef XNOSELECT
#if defined(XENV) || defined(XCONNECTPM)
    if (xSysD.xDoLoopForInput)
      xLoopForInput();
    if ( ! xSysD.SESIMUICOMFlag)    /* Input to monitor */
      xSysD.SESIMUICOMInput = 0;
    xNextLine();
    return;
#endif
#endif
  }
#endif
  else {
    while ( ((MetaChar = fgetc(stdin)) != '\n') && (MetaChar != EOF) )
      xSysD.xInputLine[Index++] = (char)MetaChar;
    if ( MetaChar == '\n' )
      xSysD.xInputLine[Index++] = '\n';
    if ( MetaChar == EOF ) {
      xPrintString("End-Of-File found, terminating ...\n\n");
      SDL_Halt();
    }
  }
  xSysD.xInputLine[Index] = '\0';
  if (xSysD.CommandFile)
    xPrintString(xSysD.xInputLine);
  else if (xSysD.InteractionLog.Active)
    fprintf(xSysD.InteractionLog.File, "%s", xSysD.xInputLine);
  xInputPos = xSysD.xInputLine;
  if (xSysD.CommandLog.Active)
    fprintf(xSysD.CommandLog.File, "%s", xSysD.xInputLine);
#ifdef XSIMULATORUI
  /* To prevent UI from trigger on "\nCommand : " check if read last line
     in Include file, in that case close file already now */
  if (xSysD.CommandFile) {
    if ((MetaChar = fgetc(xSysD.CommandFile->File)) == EOF) {
      fclose(xSysD.CommandFile->File);
      RemCF = xSysD.CommandFile;
      xSysD.CommandFile= RemCF->Next;
      for (i=0; i<99; i++){
        if (RemCF->A[i])
          xFree((void **)&RemCF->A[i]);
      }
      xFree((void **)&RemCF);
      /* Test if last line read is all white space */
      while (*xInputPos == '\n' || *xInputPos == ' ' || *xInputPos == '\t')
        xInputPos++;
      if (*xInputPos == '\0') {
        Index = 0;
        xSysD.xInputLine[Index++] = '-';
        xSysD.xInputLine[Index++] = '\n';
        xSysD.xInputLine[Index] = '\0';
      }
      xInputPos = xSysD.xInputLine;
    }
    else
      ungetc(MetaChar, xSysD.CommandFile->File);
  }
#endif
}


/*---+---------------------------------------------------------------
     xRead_SDL_PId
-------------------------------------------------------------------*/
int xRead_SDL_PId (void  * Result)
{
  xPrsNode    PrsNode;
  xPrsIdNode  ProcessId;

#ifdef XPMCOMM
  if ( xSysD.xRaW_use_Global_PId ) {
    return xPM_Read_SDL_PId((SDL_PId *)Result);
  }
#endif

  PrsNode = xReadProcess(" (PId) : ", &ProcessId, (xIdNode)0);
  if (ProcessId == xNullId) {
    *(SDL_PId *)Result = SDL_NULL;
    return 1;
  }
  if (PrsNode == (xPrsNode)0)
    return 0;
  *(SDL_PId *)Result = PrsNode->Self;
  return 1;
}


/*---+---------------------------------------------------------------
     xWri_SDL_PId
-------------------------------------------------------------------*/
char *xWri_SDL_PId (void  * C)
{
  static WriteBuf *Buf = 0;
  
  if (!Buf)
    Buf = WriteBuf_New(20);
  else
    WriteBuf_Clear(Buf);
  xGenericWriteSort(Buf, C, (tSDLTypeInfo *)&ySDL_SDL_PId);
  WriteBuf_Terminate(Buf);
  return WriteBuf_Data(Buf);
}


/*---+---------------------------------------------------------------
     xWri_SDL_PId_No_Qua
-------------------------------------------------------------------*/
char *xWri_SDL_PId_No_Qua (void  * C)
{
  static char str[256];
  if ( (*(SDL_PId *)C).GlobalNodeNr != xGlobalNodeNumber() ) {
     sprintf(str, "%d %p", (*(SDL_PId *)C).GlobalNodeNr,
             (void *)(*(SDL_PId *)C).LocalPId);
    return str;
  }

  if (xEq_SDL_PId_NULL(*(SDL_PId *)C))
    return "null";

#ifndef XPRSOPT
     /* Process instance alive? */
  if (xEq_SDL_PId(XPID_TO_PRS((*(SDL_PId *)C))->Self, *(SDL_PId *)C))
#else
#ifdef XNRINST
  if ( XPID_INSTNR((*(SDL_PId *)C)) != 0 )
#else
  if ( ! (*(SDL_PId *)C).LocalPId->InAvailList )
#endif
#endif

#ifdef XNRINST
    sprintf(str, "%s:%d",
            XPID_TO_PRS((*(SDL_PId *)C))->NameNode->Name,
            XPID_INSTNR((*(SDL_PId *)C)) );
  else
    sprintf(str, "%s:%d+",
            XPID_TO_PRS((*(SDL_PId *)C))->NameNode->Name,
            XPID_INSTNR((*(SDL_PId *)C)) );
#else
    sprintf(str, "%s",
                             XPID_TO_PRS((*(SDL_PId *)C))->NameNode->Name);
  else
    sprintf(str, "%s+",
                             XPID_TO_PRS((*(SDL_PId *)C))->NameNode->Name);
#endif
  return str;
}


/*---+---------------------------------------------------------------
     xWriteNow
-------------------------------------------------------------------*/
static char * xWriteNow (SDL_Time T)
{
  static WriteBuf *NowBuf = 0;
  
  if (!NowBuf)
    NowBuf = WriteBuf_New(20);
  else
    WriteBuf_Clear(NowBuf);
  xGenericWriteSort(NowBuf, (void *)&T, (tSDLTypeInfo *)&ySDL_SDL_Time);
  WriteBuf_Terminate(NowBuf);
  return WriteBuf_Data(NowBuf);
}


#ifdef XBREAKBEFORE
/*---+---------------------------------------------------------------
     xGetSymbolRef
-------------------------------------------------------------------*/
static void xGetSymbolRef (int SymbolNumber)
{
  xPrsNode    P;
  xPrsIdNode  PrsId;
  xPrdIdNode  PrdId;
#ifndef XNOUSEOFSERVICE
  xSrvIdNode  SrvId;
#endif
  char       *SymbolRef;
  xSymbolType SymbolType;

  P = XREADYQ_FIRST;
#ifndef XNOUSEOFSERVICE
  if (P->ActiveSrv != (xSrvNode)0) {
    if (P->ActiveSrv->ActivePrd == (xPrdNode)0) {
      SrvId = P->ActiveSrv->NameNode;
      while (SrvId->PAD_Function != P->ActiveSrv->RestartPAD)
        SrvId = SrvId->Super;
      SymbolRef = SrvId->GRrefFunc(SymbolNumber, &SymbolType);
    } else {  /* In procedure */
      PrdId = P->ActiveSrv->ActivePrd->NameNode;
      while (PrdId->Assoc_Function != P->ActiveSrv->ActivePrd->RestartPRD)
        PrdId = PrdId->Super;
      SymbolRef = PrdId->GRrefFunc(SymbolNumber, &SymbolType);
    }
  }
  else
#endif
  if (P->ActivePrd == (xPrdNode)0) {
    PrsId = P->NameNode;
    while (PrsId->PAD_Function != P->RestartPAD)
      PrsId = PrsId->Super;
    SymbolRef = PrsId->GRrefFunc(SymbolNumber, &SymbolType);
  } else {  /* In procedure */
    PrdId = P->ActivePrd->NameNode;
    while (PrdId->Assoc_Function != P->ActivePrd->RestartPRD)
      PrdId = PrdId->Super;
    SymbolRef = PrdId->GRrefFunc(SymbolNumber, &SymbolType);
  }
#ifdef XGRTRACE
  if (xSysD.xNoticeBoard.PMConnected)
    xGRTraceSymbol(SymbolRef);
  else {
#endif
    PRINTF2("SDT reference: %s\n", SymbolRef);
#ifdef XGRTRACE
  }
#endif
}
#endif


/*---+---------------------------------------------------------------
     xInformalDecision
-------------------------------------------------------------------*/
void xInformalDecision(char *Question)
{
  PRINTF2("Informal decision: '%s'\n", ++Question);
#ifdef XGRTRACE
  if ( xIsGRTraced((xPrsNode)0) >= 1 )
    xGRTraceSymbol(xSysD.xCurrentSymbolRef);
#endif
}


/*---+---------------------------------------------------------------
     xInformalPath
-------------------------------------------------------------------*/
void xInformalPath(
  int   PathNo,
  char *Answer,
  int   SymbolNo,
  int   PathSymbolNo[],
  char *PathAnswer[])
{
  PRINTF3("'%s'  %d\n", ++Answer, PathNo);
  PathSymbolNo[PathNo - 1] = SymbolNo;
  PathAnswer[PathNo - 1] = Answer;
}


/*---+---------------------------------------------------------------
     xAnyDecision
-------------------------------------------------------------------*/
void xAnyDecision (void)
{
  xPrintString("Decision with ANY\n");
#ifdef XGRTRACE
  if ( xIsGRTraced((xPrsNode)0) >= 1 )
    xGRTraceSymbol(xSysD.xCurrentSymbolRef);
#endif
}


/*---+---------------------------------------------------------------
     xAnyPath
-------------------------------------------------------------------*/
void xAnyPath(
  int   PathNo,
  int   SymbolNo,
  int   PathSymbolNo[])
{
  PRINTF2("%d   go\n", PathNo);
  PRINTF2("%d ? show\n", PathNo);
  PathSymbolNo[PathNo - 1] = SymbolNo;
}


#ifdef XMONITOR
static xbool WasBreakAfter = (xbool)0;
#endif

/*---+---------------------------------------------------------------
     xReadPath
-------------------------------------------------------------------*/
void xReadPath(
  SDL_Integer *Result_Addr,
  int          NoPaths,
  int          PathSymbolNo[],
  char        *PathAnswer[],
  xbool        Informal)
{
  xxToken  Token;
  char     strVar[256];
  int      intVar;
  int      Path;
  xbool    GotValue = (xbool)0;
#if defined(XMONITOR) && defined(XCLOCK)
  SDL_Time xTimeEnteringReadPath;

  xTimeEnteringReadPath = SDL_Clock();
#endif

  while ( ! GotValue ) {
#ifdef XSIMULATORUI
    if (xSysD.CommandFile) {
                 /* Prevent UI from trigger on ": " */
      xPrintString("Enter path :");
      xPrintString(" ");
    }
    else
#endif
      xPrintString("Enter path : ");
    Token = xScanToken(strVar);
    while (Token == xxQuestionMark || Token == xxEoln) {
      if (Informal) {      /* Informal decision */
        for (Path = 1; Path < NoPaths; Path++)
          PRINTF3("%d /* \"%s\" */ \n", Path, PathAnswer[Path - 1]);
        PRINTF3("%d /* \"%s\" */ ", NoPaths, PathAnswer[NoPaths - 1]);
      } else {               /* Decision with ANY */
        for (Path = 1; Path <= NoPaths; Path++)
          PRINTF2("%d ", Path);
      }
      xPrintString(": ");  /* Extra xPrintString for UI */
      if (Token != xxEoln) xSkipLine();
      Token = xScanToken(strVar);
    }
    if (Token == xxId) {
      if (sscanf(strVar, "%d", &intVar) != 1) {
        xPrintString("Error in value\n");
      } else if (intVar > 0 && intVar <= NoPaths) {
        Token = xScanToken(strVar);
        if (Token == xxQuestionMark) {
#ifdef XBREAKBEFORE
          xGetSymbolRef(PathSymbolNo[intVar - 1]);
#endif
        } else {
          GotValue = (xbool)1;
          *Result_Addr = (SDL_Integer)intVar;
#ifdef XMONITOR
          if (Token == xxId && xfEqualIdString(strVar, "break") == 2) {
            xSysD.Interrupted = 1;
            WasBreakAfter = (xbool)1;
          }
#endif
        }
      } else {
        PRINTF2("Error in value, must be in range 1..%d\n", NoPaths);
      }
    } else {
      PRINTF2("Illegal value, must be in range 1..%d\n", NoPaths);
    }
    if (Token != xxEoln) xSkipLine();
  }
#if defined(XMONITOR) && defined(XCLOCK)
  xSysD.xTimeInMonitor = xPlus_SDL_Duration(xSysD.xTimeInMonitor,
                  xMinusD_SDL_Time(SDL_Clock(), xTimeEnteringReadPath));
#endif
  return;
}


/*---+---------------------------------------------------------------
     xWriteSignalParameters
-------------------------------------------------------------------*/
void xWriteSignalParameters(
  xSignalNode Signal,
  char * Str)
{
  xIdNode xIdNodeSigPar;
  xbool   First = (xbool)1;

  if (XSIGNAL_IDNODE(Signal)->First == (xIdNode)0)
    return;

  PRINTF2("%sParameter(s) :", Str);
  /* Prevent UI from trigger on ": " */
  PRINTF(" ");
  for (xIdNodeSigPar = XSIGNAL_IDNODE(Signal)->First;
       xIdNodeSigPar != (xIdNode)0;
       xIdNodeSigPar = xIdNodeSigPar->Suc) {
    if (First)
      First = (xbool)0;
    else
      PRINTF(", ");
    xxWriteSort(
      (void *)((xptrint)XSIGNAL_DATA(Signal)+((xVarIdNode)xIdNodeSigPar)->Offset),
      ((xVarIdNode)xIdNodeSigPar)->TypeNode);
  }
  PRINTF("\n");
}


/*---+---------------------------------------------------------------
     xGetState
-------------------------------------------------------------------*/
xStateIdNode xGetState(
  xPrsNode      PrsP,
  xPrdNode      PrdP,
  xStateIdNode *StateList,
  int           InState)
{
#ifndef XNOUSEOFSERVICE
  if (PrsP->ActiveSrv != (xSrvNode)0) {
    if (PrdP != (xPrdNode)0 && PrsP->ActiveSrv->ActivePrd == PrdP &&
        PrsP->ActiveSrv->pREPLY_Waited_For != (XSIGTYPE)0)
      return &xRPCWaitStateIdRec;
    if (PrdP == (xPrdNode)0 && PrsP->ActiveSrv->ActivePrd == (xPrdNode)0 &&
        PrsP->ActiveSrv->pREPLY_Waited_For != (XSIGTYPE)0)
      return &xRPCWaitStateIdRec;
  } else {
#endif
    if (PrdP != (xPrdNode)0 && PrsP->ActivePrd == PrdP &&
        PrsP->pREPLY_Waited_For != (XSIGTYPE)0)
      return &xRPCWaitStateIdRec;
    if (PrdP == (xPrdNode)0 && PrsP->ActivePrd == (xPrdNode)0 &&
        PrsP->pREPLY_Waited_For != (XSIGTYPE)0)
      return &xRPCWaitStateIdRec;
#ifndef XNOUSEOFSERVICE
  }
#endif
#ifdef XERRORSTATE
  if (InState == ERROR_STATE)
    return xSysD.xErrorStateId;
#endif
  if (InState == START_STATE)
    return xStartStateId;
  return StateList[InState];
}


/*---+---------------------------------------------------------------
     xGetSystemIdNode
-------------------------------------------------------------------*/
xSystemIdNode xGetSystemIdNode (xIdNode IdNode)
{
  xIdNode Tmp;
  if (IdNode == (xIdNode)0 || IdNode->Parent == (xIdNode)0)
    Tmp = xSymbolTableRoot;
  else
    Tmp = IdNode;
  while (Tmp != xSymbolTableRoot && Tmp->EC != xSystemEC)
    Tmp = Tmp->Parent;
  if (Tmp == xSymbolTableRoot) {
    for (Tmp = (xSymbolTableRoot)->First;
         Tmp->EC != xSystemEC;
         Tmp = Tmp->Suc) ;
  }
  return (xSystemIdNode)Tmp;
}
#endif
/********************** END XREADANDWRITEF *************************/



/********************** XMONITOR || XTRACE *************************/
#if defined(XMONITOR) || defined(XTRACE) || defined (THREADED_XTRACE)
/*---+---------------------------------------------------------------
     xIdentifyTransition
-------------------------------------------------------------------*/
void xIdentifyTransition(
  xPrsNode Process,
  char *   Str)
{
  xPrsIdNode  PrsId;
#ifndef XNOUSEOFSERVICE
  xSrvIdNode  SrvId;
#endif
  xPrdIdNode  PrdId;
  xSignalNode Signal = XPRS_NEXT_REC_SIG(Process);

  PRINTF3("%sPId    : %s\n", Str, xWri_SDL_PId(&Process->Self));
  PrsId = Process->NameNode->Super;
  if (PrsId != (xPrsIdNode)0 && PrsId->Super != (xPrsIdNode)0) {
#ifndef XNOUSEOFSERVICE
    if  (Process->NameNode->Contents == (xIdNode *)0 ||
         Process->NameNode->Contents[0] == (xIdNode)0 ||
         Process->NameNode->Contents[0]->EC != xServiceEC ) {
#endif
      if (XPRS_STATEID(Process) == START_STATE) {
        while (PrsId->StateList[0] != xStartStateId)
          PrsId = PrsId->Super;
      }
      else {
        while (PrsId->PAD_Function != Process->RestartPAD)
          PrsId = PrsId->Super;
      }
      PRINTF3("%sIn type: %s\n", Str, xWriteEntity((xIdNode)PrsId));    
#ifndef XNOUSEOFSERVICE
    }
#endif
  }

#ifndef XNOUSEOFSERVICE
  if (Process->ActiveSrv != (xSrvNode)0) {
    PRINTF3("%sService: %s\n", Str,
             xWriteEntity((xIdNode)Process->ActiveSrv->NameNode));
    SrvId = Process->ActiveSrv->NameNode->Super;
    if (SrvId != (xSrvIdNode)0 && SrvId->Super != (xSrvIdNode)0) {
      if (XPRS_STATEID(Process->ActiveSrv) == START_STATE) {
        while (SrvId->StateList[0] != xStartStateId)
          SrvId = SrvId->Super;
      }
      else {
        while (SrvId->PAD_Function != Process->ActiveSrv->RestartPAD)
          SrvId = SrvId->Super;
      }
      PRINTF3("%sIn type: %s\n", Str, xWriteEntity((xIdNode)SrvId));    
    }
    if (Process->ActiveSrv->ActivePrd != (xPrdNode)0) {
      PRINTF3("%sPrd    : %s\n", Str, xPrdInstance(Process->ActiveSrv->ActivePrd));
      PrdId = Process->ActiveSrv->ActivePrd->NameNode;
      if (PrdId->Super != (xPrdIdNode)0) {
        while (PrdId->Assoc_Function != Process->ActiveSrv->ActivePrd->RestartPRD)
          PrdId = PrdId->Super;
      }
      if (PrdId != Process->ActiveSrv->ActivePrd->NameNode) {
        PRINTF3("%sIn type: %s\n", Str, xWriteEntity((xIdNode)PrdId))
      }
      xWriteBuf_Fmt("%sState  : %s*, %s%c\n",
        Str,
        xGetState(Process, (xPrdNode)0,
           Process->ActiveSrv->NameNode->StateList, XPRS_STATEID(Process->ActiveSrv)
        )->Name,
        xGetState(Process, Process->ActiveSrv->ActivePrd,
          Process->ActiveSrv->ActivePrd->NameNode->StateList,
          Process->ActiveSrv->ActivePrd->State
        )->Name,
        Process->ActiveSrv->InTransition ? '*' : ' ');
    } else {
      PRINTF4("%sState  : %s%c\n", Str,
          xGetState(Process, (xPrdNode)0, Process->ActiveSrv->NameNode->StateList,
                    XPRS_STATEID(Process->ActiveSrv)
          )->Name,
          Process->ActiveSrv->InTransition ? '*' : ' ');
    }
  } else {
#endif
    if (Process->ActivePrd != (xPrdNode)0) {
      PRINTF3("%sPrd    : %s\n", Str, xPrdInstance(Process->ActivePrd));
      PrdId = Process->ActivePrd->NameNode;
      if (PrdId->Super != (xPrdIdNode)0) {
        while (PrdId->Assoc_Function != Process->ActivePrd->RestartPRD)
          PrdId = PrdId->Super;
      }
      if (PrdId != Process->ActivePrd->NameNode) {
        PRINTF3("%sIn type: %s\n", Str, xWriteEntity((xIdNode)PrdId))
      }
      xWriteBuf_Fmt("%sState  : %s*, %s%c\n",
        Str,
        xGetState(Process, (xPrdNode)0, Process->NameNode->StateList,
          XPRS_STATEID(Process)
        )->Name,
        xGetState(Process, Process->ActivePrd,
          Process->ActivePrd->NameNode->StateList,
          Process->ActivePrd->State
        )->Name,
        Process->InTransition ? '*' : ' ');

    } else {
      PRINTF4("%sState  : %s%c\n", Str,
          xGetState(Process, (xPrdNode)0, Process->NameNode->StateList,
                    XPRS_STATEID(Process)
          )->Name,
          Process->InTransition ? '*' : ' ');
    }
#ifndef XNOUSEOFSERVICE
  }
#endif

#ifndef XNOUSEOFSERVICE
  if (Process->ActiveSrv != (xSrvNode)0) {
    if ( ( ( Process->ActiveSrv->ActivePrd == (xPrdNode)0 &&
             ( XPRS_STATEID(Process->ActiveSrv) != START_STATE ||
               Process->ActiveSrv->pREPLY_Waited_For != (XSIGTYPE)0
             )
           ) ||
           ( Process->ActiveSrv->ActivePrd != (xPrdNode)0 &&
             ( Process->ActiveSrv->ActivePrd->State != START_STATE ||
               Process->ActiveSrv->pREPLY_Waited_For != (XSIGTYPE)0
             )
           )
         ) &&
         Signal != (xSignalNode)0
       ) {
      PRINTF3("%sInput  : %s", Str,
              xWriteEntity((xIdNode)XSIGNAL_IDNODE(Signal)));
      if (XSIGNAL_IDNODE(Signal) == xContSigId)
        PRINTF2(" Prio %d\n", XCONT_SIG_PRIO(Signal))
      else {
        xPrintString("\n");
        PRINTF3("%sSender : %s\n", Str, xWri_SDL_PId(&XSIGNAL_SENDER(Signal)));
      }
    }
  } else {
#endif
    if ( ( ( Process->ActivePrd == (xPrdNode)0 &&
             (XPRS_STATEID(Process) != START_STATE ||
              Process->pREPLY_Waited_For != (XSIGTYPE)0
             )
           ) ||
           ( Process->ActivePrd != (xPrdNode)0 &&
             (Process->ActivePrd->State != START_STATE ||
              Process->pREPLY_Waited_For != (XSIGTYPE)0
             )
           )
         ) &&
         Signal != (xSignalNode)0
       ) {
      PRINTF3("%sInput  : %s", Str,
              xWriteEntity((xIdNode)XSIGNAL_IDNODE(Signal)));
      if (XSIGNAL_IDNODE(Signal) == xContSigId)
        PRINTF2(" Prio %d\n", XCONT_SIG_PRIO(Signal))
      else {
        xPrintString("\n");
        PRINTF3("%sSender : %s\n", Str, xWri_SDL_PId(&XSIGNAL_SENDER(Signal)));
      }
    }
#ifndef XNOUSEOFSERVICE
  }
#endif
  PRINTF3("%sNow    : %s\n", Str, xWriteNow(SDL_Now()));
}


#endif
/******************** END XMONITOR || XTRACE ***********************/



/*************************** XGRTRACE ******************************/
#ifdef XGRTRACE
/*---+---------------------------------------------------------------
     xIsGRTraced
-------------------------------------------------------------------*/
int xIsGRTraced (xPrsNode PrsNode)
{
  xIdNode IdNode;

  if (xSysD.xNoTraceOn)
    return (xbool)0;
  if (PrsNode == (xPrsNode)0)
    PrsNode = XREADYQ_FIRST;

  /* Test PId */
  if (PrsNode->GRTrace >= 0)
    return PrsNode->GRTrace;

  /* Test Process Instance set */
  if (PrsNode->NameNode->GRTrace >= 0)
    return PrsNode->NameNode->GRTrace;

  /* Test blocks */
  for (IdNode = PrsNode->NameNode->Parent;
       IdNode != (xIdNode)0 && IdNode->EC != xSystemEC;
       IdNode = IdNode->Parent) {
    if (IdNode->EC == xBlockEC)
      if (((xBlockIdNode)IdNode)->GRTrace >= 0)
        return ((xBlockIdNode)IdNode)->GRTrace;
  }

  /* Test system */
  if (IdNode != xSymbolTableRoot && ((xSystemIdNode)IdNode)->GRTrace > 0)
    return ((xSystemIdNode)IdNode)->GRTrace;

  /* Take default value */
  if (xSysD.GRTrace > 0)
    return xSysD.GRTrace;
  return 0;
}


#endif
/************************* END XGRTRACE ****************************/



/**************************** XTRACE *******************************/
#if defined (XTRACE) || defined (THREADED_XTRACE)

static int xProcessTraceLimit[] = {
  3, 5, 6, 4, 6,
  4, 3, 3, 6,
  3, 6, 3,
  5, 6, 5, 3, 5,
  6, 2, 5, 6,
  3, 5, 6, 3,
  5, 6, 5,
  6, 2, 6,
  3,
  1,
  1, 2, 3, 4, 5, 6, 7, 8,
  9, 10
};

/*---+---------------------------------------------------------------
     xShouldBeTraced
-------------------------------------------------------------------*/
xbool xShouldBeTraced(
  xTraceType TraceType,
  xPrsNode   Process)
{
#ifndef THREADED_XTRACE
  xIdNode IdNode;

  if (xSysD.xNoTraceOn)
    return (xbool)0;
  if (xSysD.xSilent > 0)
    return (xbool)0;

  if (Process == (xPrsNode)0) {
    if (XREADYQ_EMPTY)
      return xSysD.Trace_Default >=
             xProcessTraceLimit[(int)TraceType];
    Process = XREADYQ_FIRST;
  }

  /* Test PId */
  if (Process->Trace_Default >= 0)
    return Process->Trace_Default >= xProcessTraceLimit[(int)TraceType];

  /* Test Process Instance Set */
  if (Process->NameNode->Trace_Default >= 0)
    return Process->NameNode->Trace_Default >=
           xProcessTraceLimit[(int)TraceType];

  /* Test block levels */
  for (IdNode = Process->NameNode->Parent;
       IdNode != (xIdNode)0 && IdNode->EC != xSystemEC;
       IdNode = IdNode->Parent) {
    if (IdNode->EC == xBlockEC)
      if (((xBlockIdNode)IdNode)->Trace_Default >= 0)
        return ((xBlockIdNode)IdNode)->Trace_Default >=
               xProcessTraceLimit[(int)TraceType];
  }

  /* Test system */
  if (IdNode != xSymbolTableRoot && ((xSystemIdNode)IdNode)->Trace_Default >= 0)
    return ((xSystemIdNode)IdNode)->Trace_Default >=
           xProcessTraceLimit[(int)TraceType];

  /* Take default value */
  return xSysD.Trace_Default >=
         xProcessTraceLimit[(int)TraceType];
#endif /* THREADED_XTRACE */
#ifdef THREADED_XTRACE
  return 4;
#endif /* THREADED_XTRACE */
}


/*---+---------------------------------------------------------------
     ShouldOneTrace
-------------------------------------------------------------------*/
static xbool ShouldOneTrace(
  SDL_PId PId1,
  SDL_PId PId2)
{
  xIdNode IdNode, IdNode2;
  xbool Found;

  if (xSysD.xNoTraceOn)
    return (xbool)0;
  if (xSysD.xSilent > 0)
    return (xbool)0;
  #ifndef THREADED_XTRACE
  if (xSysD.Trace_Default == 1 ||
      xGetSystemIdNode((xIdNode)XPID_TO_PRS(PId2)->NameNode)->Trace_Default == 1)
    if (XPID_TO_PRS(PId1)->NameNode == xEnvId)
      return (xbool)1;
  if (XPID_TO_PRS(PId1)->Trace_Default == 1)
    if ( ! xEq_SDL_PId(PId1, PId2))
      return (xbool)1;
  if (XPID_TO_PRS(PId1)->NameNode->Trace_Default == 1)
    if (XPID_TO_PRS(PId1)->NameNode != XPID_TO_PRS(PId2)->NameNode)
      return (xbool)1;
  for (IdNode = XPID_TO_PRS(PId1)->NameNode->Parent;
       IdNode != (xIdNode)0;
       IdNode = IdNode->Parent) {
    if (IdNode->EC == xBlockEC)
      if (((xBlockIdNode)IdNode)->Trace_Default == 1) {
        Found = (xbool)0;
        for (IdNode2 = XPID_TO_PRS(PId2)->NameNode->Parent;
             IdNode2 != (xIdNode)0;
             IdNode2 = IdNode2->Parent) {
          if (IdNode2->EC == xBlockEC)
            if (IdNode == IdNode2) {
              Found = (xbool)1;
              break;
            }
        }
        if ( ! Found)           /* Not in same traced block */
          return (xbool)1;
      }
  }
  #endif /* THREADED_XTRACE */
#ifdef THREADED_XTRACE
  return (xbool)1;
#endif /* THREADED_XTRACE */
  return (xbool)0;
}


/*---+---------------------------------------------------------------
     xTraceOutput
-------------------------------------------------------------------*/
void xTraceOutput (xSignalNode  S)
{
  SDL_PId  Receiver;
  SDL_PId  Sender;
  XSIGTYPE SignalId;

  Sender = XSIGNAL_SENDER(S);
  if (xEq_SDL_PId_NULL(Sender))     /* Static create */
    return;
  Receiver = XSIGNAL_RECEIVER(S);
  SignalId = XSIGNAL_IDNODE(S);
  if (! XIS_PID_IN_SYSTEM(Sender) ) {
    if (ShouldOneTrace(xEnv, Receiver) || ShouldOneTrace(Receiver, xEnv)) {
      xWriteBuf_Fmt("\n*** OUTPUT of %s to %s from ",
		   xWriteEntity((xIdNode)SignalId),
		   xWri_SDL_PId(&Receiver));
      xWriteBuf_Fmt("%s\n", xWri_SDL_PId(&Sender));
      if (SignalId != xContSigId)
        if (SignalId->First != (xIdNode)0)
          xWriteSignalParameters(S, "***    ");
    }
    if (xShouldBeTraced(xtOutput, XPID_TO_PRS(xEnv))) {
      xWriteBuf_Fmt("\n*** OUTPUT of %s to %s from ",
		   xWriteEntity((xIdNode)SignalId),
		   xWri_SDL_PId(&Receiver));
      xWriteBuf_Fmt("%s\n", xWri_SDL_PId(&Sender));
    }
    if (SignalId != xContSigId)
      if (SignalId->First != (xIdNode)0)
        if (xShouldBeTraced(xtOutputPara, XPID_TO_PRS(xEnv)))
          xWriteSignalParameters(S, "***    ");
  }
  else if (! XIS_PID_IN_SYSTEM(Receiver) ) {
    if (ShouldOneTrace(Sender, xEnv) || ShouldOneTrace(xEnv, Sender)) {
      PRINTF2("*   OUTPUT of %s", xWriteEntity((xIdNode)SignalId));
      PRINTF2(" to %s", xWri_SDL_PId(&Receiver));
      PRINTF2(" from %s\n", xWri_SDL_PId(&Sender));
      if (SignalId != xContSigId)
        if (SignalId->First != (xIdNode)0)
          xWriteSignalParameters(S, "*      ");
    }
    if (xShouldBeTraced(xtOutput, XPID_TO_PRS(Sender))) {
      PRINTF2("*   OUTPUT of %s", xWriteEntity((xIdNode)SignalId));
      PRINTF2(" to %s", xWri_SDL_PId(&Receiver));
      PRINTF2(" from %s\n", xWri_SDL_PId(&Sender));
    }
    if (SignalId != xContSigId)
      if (SignalId->First != (xIdNode)0)
        if (xShouldBeTraced(xtOutputPara, XPID_TO_PRS(Sender)))
          xWriteSignalParameters(S, "*      ");
  }
  else {
    if (ShouldOneTrace(Sender, Receiver) || ShouldOneTrace(Receiver, Sender)) {
      PRINTF2("*   OUTPUT of %s", xWriteEntity((xIdNode)SignalId));
      PRINTF2(" to %s", xWri_SDL_PId(&Receiver));
      PRINTF2(" from %s\n", xWri_SDL_PId(&Sender));
      if (SignalId != xContSigId)
        if (SignalId->First != (xIdNode)0)
          xWriteSignalParameters(S, "*      ");
    }
    if (xShouldBeTraced(xtOutput, XPID_TO_PRS(Sender))) {
      PRINTF2("*   OUTPUT of %s", xWriteEntity((xIdNode)SignalId));
      PRINTF2(" to %s\n", xWri_SDL_PId(&Receiver));
    }
    if (SignalId != xContSigId)
      if (SignalId->First != (xIdNode)0)
        if (xShouldBeTraced(xtOutputPara, XPID_TO_PRS(Sender)))
          xWriteSignalParameters(S, "*      ");
  }
#ifdef THREADED_XTRACE
 /* printf("*   OUTPUT of %s", (xIdNode)SignalId);
  printf(" to %s\n", &Receiver);*/
#endif /* THREADED_XTRACE */
#ifdef XMONITOR
  if (xSysD.xSilent == 0)
    if (xCheckBreakpointOutput(S)) {
      xSysD.StopInMonitor = 1;
      xSysD.StepStatement = 1;
    }
#endif
}


/*---+---------------------------------------------------------------
     xTraceOutputDiscard
-------------------------------------------------------------------*/
void xTraceOutputDiscard (xSignalNode  S)
{
  if (! XIS_PID_IN_SYSTEM(XSIGNAL_SENDER(S)) ) {
    if (xShouldBeTraced(xtOutputDiscard, XPID_TO_PRS(xEnv)))
      xPrintString("***    The signal caused an immediate null transition\n");
    return;
  }
  if (xShouldBeTraced(xtOutputDiscard, XPID_TO_PRS(XSIGNAL_SENDER(S))))
    xPrintString("*      The signal caused an immediate null transition\n");
}


/*---+---------------------------------------------------------------
     xTraceTimerOutput
-------------------------------------------------------------------*/
void xTraceTimerOutput (xSignalNode  S)
{
  SDL_PId Receiver;

  Receiver = XSIGNAL_RECEIVER(S);
  if (xShouldBeTraced(xtTimerOutput, XPID_TO_PRS(Receiver))) {
    xPrintString("\n*** TIMER signal was sent\n");
    PRINTF2("*   Timer    : %s\n", 
            xWriteEntity((xIdNode)XSIGNAL_IDNODE(S)));
    PRINTF2("*   Receiver : %s\n", xWri_SDL_PId(&Receiver));
    PRINTF2("*** Now      : %s\n", xWriteNow(SDL_Now()));
  }
  if (XSIGNAL_IDNODE(S)->First != (xIdNode)0)
    if (xShouldBeTraced(xtTimerOutputPara, XPID_TO_PRS(Receiver)))
      xWriteSignalParameters(S, "*      ");
#ifdef XMONITOR
  if (xSysD.xSilent == 0)
    if (xCheckBreakpointOutput(S)) {
      xSysD.StopInMonitor = 1;
      xSysD.StepStatement = 1;
    }
#endif
}


/*---+---------------------------------------------------------------
     xTraceTimerOutputDiscard
-------------------------------------------------------------------*/
void xTraceTimerOutputDiscard (xSignalNode  S)
{
  if (xShouldBeTraced(xtTimerOutputDiscard, XPID_TO_PRS(XSIGNAL_RECEIVER(S))))
    xPrintString("*      The signal caused an immediate null transition\n");
}


/*---+---------------------------------------------------------------
     xWriteFPars
-------------------------------------------------------------------*/
static void xWriteFPars (
  xPrsIdNode   Prs,
  xSignalNode  Signal,
  xbool       *First )
{
  xIdNode  IdNode;

  /* Treat first FPar:s in inherited process types. */
  if (Prs->Super != (xPrsIdNode)0)
    xWriteFPars(Prs->Super, Signal, First);

  /* Loop for formal parameters in this type (or ProcessEC) */
  for (IdNode = Prs->First; IdNode != (xIdNode)0; IdNode = IdNode->Suc ) {
    if (IdNode->EC == xFormalParEC) {
      if (*First) {
        PRINTF("*      Parameter(s) :");
        /* Prevent UI from trigger on ": " */
        PRINTF(" ");
        *First = (xbool)0;
      }
      else
        PRINTF(", ");
      xxWriteSort((void *)((xptrint)(XSIGNAL_DATA(Signal)) +
			  ((xVarIdNode)IdNode)->Offset2),
		 ((xVarIdNode)IdNode)->TypeNode);
    }
  }
}


/*---+---------------------------------------------------------------
     xTraceCreate
-------------------------------------------------------------------*/
void xTraceCreate (xSignalNode StartUpSig)
{
  xbool    First = (xbool)1;
  SDL_PId  P;

/*  P = Created->Self; */
  P = XSIGNAL_RECEIVER(StartUpSig);
  if (xShouldBeTraced(xtCreate, (xPrsNode)0)) {
    PRINTF2("*   CREATE %s\n", xWri_SDL_PId(&P));
  }
  if (xShouldBeTraced(xtCreatePara, (xPrsNode)0)) {
    xWriteFPars(XPID_TO_PRS(P)->NameNode, StartUpSig, &First);
    if ( ! First)
      xPrintString("\n");
  }
}


/*---+---------------------------------------------------------------
     xTraceUnsuccessfulCreate
-------------------------------------------------------------------*/
void xTraceUnsuccessfulCreate (xPrsIdNode  PrsId)
{
  if (xShouldBeTraced(xtCreate, (xPrsNode)0))
     PRINTF2("*   Attempt to CREATE %s was unsuccessful\n",
            xWriteEntity((xIdNode)PrsId));
}


/*---+---------------------------------------------------------------
     xTraceSet
-------------------------------------------------------------------*/
void xTraceSet(
  SDL_Time     T,
  xSignalNode  S)
{
  if (xShouldBeTraced(xtSet, (xPrsNode)0))
     PRINTF3("*   SET on timer %s at %s\n",
            xWriteEntity((xIdNode)XSIGNAL_IDNODE(S)), xWriteNow(T));
  if (XSIGNAL_IDNODE(S)->First != (xIdNode)0)
    if (xShouldBeTraced(xtSetPara, (xPrsNode)0))
      xWriteSignalParameters(S, "*      ");
  if (xLT_SDL_Time(T, SDL_Now()))
    if (xShouldBeTraced(xtSetChangeTime, (xPrsNode)0))
      xPrintString(
           "*     Time value given in SET less than Now. Replaced by Now\n");
}


/*---+---------------------------------------------------------------
     xTraceReset
-------------------------------------------------------------------*/
void xTraceReset (xSignalNode  S)
{
  if (xShouldBeTraced(xtReset, (xPrsNode)0))
     PRINTF2("*   RESET on timer %s\n", 
             xWriteEntity((xIdNode)XSIGNAL_IDNODE(S)));
  if (XSIGNAL_IDNODE(S)->First != (xIdNode)0)
    if (xShouldBeTraced(xtResetPara, (xPrsNode)0))
      xWriteSignalParameters(S, "*      ");
}


/*---+---------------------------------------------------------------
     xTraceResetAction
-------------------------------------------------------------------*/
void xTraceResetAction(
  int Code,
  xSignalNode  S)
{
  switch (Code) {

  case 0:      /* Timer removed in Reset */
    if (xShouldBeTraced(xtResetAction, (xPrsNode)0))
      PRINTF2("*   Timer of type %s was removed\n", 
              xWriteEntity((xIdNode)XSIGNAL_IDNODE(S)));
    break;

  case 1:      /* Timer signal removed in Reset */
    if (xShouldBeTraced(xtResetAction, (xPrsNode)0))
      PRINTF2("*   Timer signal of type %s was removed\n",
              xWriteEntity((xIdNode)XSIGNAL_IDNODE(S)));
    break;

  case 2:      /* No timer removed in Reset */
    if (xShouldBeTraced(xtResetAction, (xPrsNode)0))
      xPrintString("*   No timer was removed\n");
    break;

  case 3:      /* Timer removed in Set */
    if (xShouldBeTraced(xtSetImplicitReset, (xPrsNode)0))
      PRINTF2("*   Timer of type %s was removed\n",
              xWriteEntity((xIdNode)XSIGNAL_IDNODE(S)));
    break;

  case 4:      /* Timer signal removed in Set */
    if (xShouldBeTraced(xtSetImplicitReset, (xPrsNode)0))
      PRINTF2("*   Timer signal of type %s was removed\n",
              xWriteEntity((xIdNode)XSIGNAL_IDNODE(S)));
    break;
  }
}


/*---+---------------------------------------------------------------
     xTraceNextstate
-------------------------------------------------------------------*/
void xTraceNextstate(
  xPrsNode  PrsP,
  int       InState)
{
  xStateIdNode StateId;

#ifdef XMONITOR
  if (xSysD.xStepToVisible && xShouldBeTraced(xtVisibleStep, (xPrsNode)0))
    xSysD.StopInMonitor = 1;
#endif
  if (xShouldBeTraced(xtNextstate, (xPrsNode)0)) {
#ifndef XNOUSEOFSERVICE
    if ( PrsP->ActiveSrv != (xSrvNode)0 ) {
      if ( PrsP->ActiveSrv->ActivePrd != (xPrdNode)0 )
        StateId = xGetState(PrsP, PrsP->ActiveSrv->ActivePrd,
          PrsP->ActiveSrv->ActivePrd->NameNode->StateList, InState);
      else
        StateId = xGetState(PrsP, (xPrdNode)0,
                     PrsP->ActiveSrv->NameNode->StateList, InState);
    } else {
#endif
     if ( PrsP->ActivePrd != (xPrdNode)0 )
       StateId = xGetState(PrsP, PrsP->ActivePrd,
          PrsP->ActivePrd->NameNode->StateList, InState);
     else
       StateId = xGetState(PrsP, (xPrdNode)0, PrsP->NameNode->StateList, InState);
#ifndef XNOUSEOFSERVICE
    }
#endif
    PRINTF2("*** NEXTSTATE  %s\n", xWriteEntity((xIdNode)StateId));
  }
}


/*---+---------------------------------------------------------------
     xTraceNextstateDiscard
-------------------------------------------------------------------*/
void xTraceNextstateDiscard(
  xPrsNode    PrsP,
  xSignalNode Signal)
{
  if (xShouldBeTraced(xtNextstateDiscard, PrsP))
     PRINTF2("*   Null transition : %s\n", 
             xWriteEntity((xIdNode)XSIGNAL_IDNODE(Signal)));
  if (! XIS_CONT_SIGNAL(Signal))
    if (XSIGNAL_IDNODE(Signal)->First != (xIdNode)0)
      if (xShouldBeTraced(xtNextstateDiscardPara, PrsP))
        xWriteSignalParameters(Signal, "*      ");
}


/*---+---------------------------------------------------------------
     xTraceTask
-------------------------------------------------------------------*/
void xTraceTask (char *In_Str)
{
  if (xShouldBeTraced(xtTask, (xPrsNode)0))
    PRINTF2("*   TASK  %s\n", In_Str);
}


/*---+---------------------------------------------------------------
     xTraceAlg
-------------------------------------------------------------------*/
void xTraceAlg (char *In_Str)
{
  if (xShouldBeTraced(xtTask, (xPrsNode)0))
    PRINTF2("*   %s\n", In_Str);
}


/*---+---------------------------------------------------------------
     xTraceAlgValue
-------------------------------------------------------------------*/
void xTraceAlgValue(
  char       *In_Str,
  void       *In_Addr,
  tSDLTypeInfo * SortNode)
{
  if (xShouldBeTraced(xtTask, (xPrsNode)0)) {
    PRINTF2("*   %s", In_Str);
    if (SortNode != 0 && xShouldBeTraced(xtTaskValue, (xPrsNode)0))
      xxWriteSort(In_Addr, SortNode);
    xPrintString("\n");
  }
}


/*---+---------------------------------------------------------------
     xTraceAssign
-------------------------------------------------------------------*/
void xTraceAssign(
  char       *In_Str,
  void       *In_Addr,
  tSDLTypeInfo *SortNode)
{
  if (xShouldBeTraced(xtTask, (xPrsNode)0)) {
    PRINTF2("*   ASSIGN  %s", In_Str);
    if (SortNode != 0 &&
        xShouldBeTraced(xtTaskValue, (xPrsNode)0)) {
      xxWriteSort(In_Addr, SortNode);
    }
    xPrintString("\n");
  }
}


/*---+---------------------------------------------------------------
     xTraceDecision
-------------------------------------------------------------------*/
void xTraceDecision(
  void        *In_Addr,
  tSDLTypeInfo *  SortNode)
{
  if (xShouldBeTraced(xtDecision, (xPrsNode)0)) {
    xPrintString("*   DECISION  Value:");
                 /* Prevent UI from trigger on ": " */
    xPrintString(" ");
    xxWriteSort(In_Addr, SortNode);
    xPrintString("\n");
  }
}


/*---+---------------------------------------------------------------
     xTraceStop
-------------------------------------------------------------------*/
void xTraceStop (xPrsNode  PrsP)
{
  int         NoOfSignals;
  xSignalNode Signal;
  xbool       StopDiscardTrace, StopDiscardParaTrace;
  xSignalNode Timer;
  xbool       StopTimerDiscardTrace, StopTimerDiscardParaTrace;

#ifdef XMONITOR
  if (xSysD.xStepToVisible && xShouldBeTraced(xtVisibleStep, PrsP))
    xSysD.StopInMonitor = 1;
#endif

  if (xShouldBeTraced(xtStop, PrsP)) {
#ifndef XNOUSEOFSERVICE
    if (PrsP->ActiveSrv != (xSrvNode)0) {
      xPrintString("*** Service STOP\n");
      if (PrsP->SrvList->NextSrv != (xSrvNode)0) return;
    }
#endif
    NoOfSignals = 0;
    XBEGIN_INPUTPORT_LOOP(PrsP, Signal)
      NoOfSignals++;
    XEND_INPUTPORT_LOOP
    if (NoOfSignals == 0)
      xPrintString("*** STOP   (no signals were discarded)\n");
    else if (NoOfSignals == 1)
      xPrintString("*** STOP   (1 signal was discarded)\n");
    else
      PRINTF2("*** STOP   (%d signals were discarded)\n", NoOfSignals);
  }
  StopDiscardTrace = xShouldBeTraced(xtStopDiscard, PrsP);
  StopDiscardParaTrace = xShouldBeTraced(xtStopDiscardPara, PrsP);
  if (StopDiscardTrace || StopDiscardParaTrace) {
    XBEGIN_INPUTPORT_LOOP(PrsP, Signal)
      if (StopDiscardTrace) {
        PRINTF2("*   Discarded: %s", 
                xWriteEntity((xIdNode)XSIGNAL_IDNODE(Signal)));
        PRINTF2(" from %s\n", xWri_SDL_PId(&XSIGNAL_SENDER(Signal)));
      }
      if (StopDiscardParaTrace)
        if (! XIS_CONT_SIGNAL(Signal))
          if (XSIGNAL_IDNODE(Signal)->First != (xIdNode)0)
            xWriteSignalParameters(Signal, "*      ");
    XEND_INPUTPORT_LOOP
  }
  StopTimerDiscardTrace = xShouldBeTraced(xtStopTimerDiscard, PrsP);
  StopTimerDiscardParaTrace = xShouldBeTraced(xtStopTimerDiscardPara, PrsP);
  if (StopTimerDiscardTrace || StopTimerDiscardParaTrace) {
    XBEGIN_TIMERQ_LOOP(Timer)
      if (XPID_TO_PRS(XTIMER_SENDER(Timer)) == PrsP) {
        if (StopTimerDiscardTrace)
          PRINTF2("*   Timer of type %s was removed\n",
                 xWriteEntity((xIdNode)XTIMER_IDNODE(Timer)));
        if (StopTimerDiscardParaTrace)
          if (XTIMER_IDNODE(Timer)->First != (xIdNode)0)
            xWriteSignalParameters(XTIMERSIGNAL(Timer), "*      ");
      }
    XEND_TIMERQ_LOOP
  }
}


/*---+---------------------------------------------------------------
     xTraceTransition
-------------------------------------------------------------------*/
void xTraceTransition (xPrsNode Process)
{
  xbool         First = (xbool)1;
  xSignalNode   Signal = XPRS_NEXT_REC_SIG(Process);

#ifdef XCOVERAGE
  xPrsIdNode    PrsId;
  xStateIdNode  StateId;
  int           InState;
  XSIGTYPE      SignalId;
  int           Pos;
  xPrdIdNode    PrdId;
#ifndef XNOUSEOFSERVICE
  xSrvIdNode    SrvId;
#endif

  InState = xFindState(Process);
  PrsId = Process->NameNode;
  if (InState == START_STATE) {
    if (Process->ActivePrd == (xPrdNode)0) {
#ifndef XNOUSEOFSERVICE
      if  (PrsId->Contents == (xIdNode *)0 ||
           PrsId->Contents[0] == (xIdNode)0 ||
           PrsId->Contents[0]->EC != xServiceEC ) {
#endif
        /* Start transition by process */
        if (PrsId->Super != (xPrsIdNode)0) {
          PrsId = PrsId->Super;
          while (PrsId->StateList[0] != xStartStateId)
            PrsId = PrsId->Super;
        }
        PrsId->NoOfStartTransitions++;
#ifndef XNOUSEOFSERVICE
      }
#endif
    }
#ifndef XNOUSEOFSERVICE
    if (Process->ActiveSrv != (xSrvNode)0 &&
        Process->ActiveSrv->ActivePrd == (xPrdNode)0) {
      /* Start transition by service */
      SrvId = Process->ActiveSrv->NameNode;
      if (SrvId->Super != (xSrvIdNode)0) {
        SrvId = SrvId->Super;
        while (SrvId->StateList[0] != xStartStateId)
          SrvId = SrvId->Super;
      }
      SrvId->NoOfStartTransitions++;
    }
#endif
  } else {
    SignalId = XSIGNAL_CODE(Signal);
#ifndef XNOUSEOFSERVICE
    if (Process->ActiveSrv != (xSrvNode)0) {
      if (Process->ActiveSrv->ActivePrd != (xPrdNode)0) {
        PrdId = Process->ActiveSrv->ActivePrd->NameNode;
        StateId = xGetState(Process, Process->ActiveSrv->ActivePrd,
          PrdId->StateList, InState);
        if (StateId != &xRPCWaitStateIdRec) {
          while (PrdId->Assoc_Function !=
                 Process->ActiveSrv->ActivePrd->RestartPRD) {
            PrdId = PrdId->Super;
            StateId = StateId->Super;
          }
          if (XSIGNAL_IDNODE(Signal) == xContSigId)
            StateId->CoverageArray[PrdId->SignalSetLength]++;
          else {
            Pos = 0;
            while ( ((PrdId->SignalSet)[Pos] != (XSIGTYPE)0)
                    && ((PrdId->SignalSet)[Pos] != SignalId) )
              Pos++;
            if (Pos < PrdId->SignalSetLength)
              StateId->CoverageArray[Pos]++;
          }
        }
      }
      else {
        SrvId = Process->ActiveSrv->NameNode;
        StateId = xGetState(Process, (xPrdNode)0, 
                            SrvId->StateList, InState);
        if (StateId != &xRPCWaitStateIdRec) {
          if (SrvId->Super != (xSrvIdNode)0) {
            SrvId = SrvId->Super;
            while (SrvId->PAD_Function != Process->ActiveSrv->RestartPAD) {
              SrvId = SrvId->Super;
              StateId = StateId->Super;
            }
          }
          if (XSIGNAL_IDNODE(Signal) == xContSigId)
            StateId->CoverageArray[PrsId->SignalSetLength]++;
          else {
            Pos = 0;
            while ( ((SrvId->SignalSet)[Pos] != (XSIGTYPE)0)
                    && ((SrvId->SignalSet)[Pos] != SignalId) )
              Pos++;
            if (Pos < SrvId->SignalSetLength)
              StateId->CoverageArray[Pos]++;
          }
        }
      }
    } else {
#endif
      if (Process->ActivePrd != (xPrdNode)0) {
        PrdId = Process->ActivePrd->NameNode;
        StateId = xGetState(Process, Process->ActivePrd,
          PrdId->StateList, InState);
        if (StateId != &xRPCWaitStateIdRec) {
          while (PrdId->Assoc_Function !=
                 Process->ActivePrd->RestartPRD) {
            PrdId = PrdId->Super;
            StateId = StateId->Super;
          }
          if (XSIGNAL_IDNODE(Signal) == xContSigId)
            StateId->CoverageArray[PrdId->SignalSetLength]++;
          else {
            Pos = 0;
            while ( ((PrdId->SignalSet)[Pos] != (XSIGTYPE)0)
                    && ((PrdId->SignalSet)[Pos] != SignalId) )
              Pos++;
            if (Pos < PrdId->SignalSetLength)
              StateId->CoverageArray[Pos]++;
          }
        }
      }
      else {
        StateId = xGetState(Process, (xPrdNode)0, 
                            PrsId->StateList, InState);
        if (StateId != &xRPCWaitStateIdRec) {
          if (PrsId->Super != (xPrsIdNode)0) {
            PrsId = PrsId->Super;
            while (PrsId->PAD_Function != Process->RestartPAD) {
              PrsId = PrsId->Super;
              StateId = StateId->Super;
            }
          }
          if (XSIGNAL_IDNODE(Signal) == xContSigId)
            StateId->CoverageArray[PrsId->SignalSetLength]++;
          else {
            Pos = 0;
            while ( ((PrsId->SignalSet)[Pos] != (XSIGTYPE)0)
                    && ((PrsId->SignalSet)[Pos] != SignalId) )
              Pos++;
            if (Pos < PrsId->SignalSetLength)
              StateId->CoverageArray[Pos]++;
          }
        }
      }
#ifndef XNOUSEOFSERVICE
    }
#endif
  }
#endif

  if (xShouldBeTraced(xtTransition, Process)) {
    xPrintString("\n*** TRANSITION START\n");
    xIdentifyTransition(Process, "*      ");
  }
  if (XSIGNAL_IDNODE(Signal)->EC == xStartUpSignalEC) {
    if (xShouldBeTraced(xtTransitionPara, Process)) {
      xWriteFPars(Process->NameNode, Signal, &First);
      if ( ! First)
        xPrintString("\n");
    }
  }
  else if (XSIGNAL_IDNODE(Signal) != xContSigId)
    if (XSIGNAL_IDNODE(Signal)->First != (xIdNode)0)
      if (xShouldBeTraced(xtTransitionPara, Process))
        xWriteSignalParameters(Signal, "*      ");
}


#ifndef XNOUSEOFSERVICE
/*---+---------------------------------------------------------------
     xTraceStartService
-------------------------------------------------------------------*/
void xTraceStartService (xSrvNode Srv)
{
  if (xShouldBeTraced(xtTransition, Srv->ContainerPrs)) {
    PRINTF2("*   Start service %s\n", Srv->NameNode->Name);
  }
}
#endif


/*---+---------------------------------------------------------------
     xWritePrdParameters
-------------------------------------------------------------------*/
static void xWritePrdParameters(
  xPrdIdNode xIdNodeProc,
  xPrdNode   PrdVarP,
  xbool     *IsFirst)
{
  xIdNode xIdNodeProcPar;

  if (xIdNodeProc->Super != (xPrdIdNode)0)
    xWritePrdParameters(xIdNodeProc->Super, PrdVarP, IsFirst);

  for (xIdNodeProcPar = xIdNodeProc->First;
       xIdNodeProcPar != (xIdNode)0;
       xIdNodeProcPar = xIdNodeProcPar->Suc) {
    if ( xIdNodeProcPar->EC == xFormalParEC &&
         ! XIS_RESULT_PARA((xVarIdNode)xIdNodeProcPar) ) {
      if (*IsFirst) {
        PRINTF("*      Parameter(s) :");
        /* Prevent UI from trigger on ": " */
        PRINTF(" ");
	*IsFirst = (xbool)0;
      } else {
	PRINTF(", ");
      }
      if ( XIS_ADDRESS((xVarIdNode)xIdNodeProcPar) ) {
        xxWriteSort(*(void **)((xptrint)PrdVarP +
			       ((xVarIdNode)xIdNodeProcPar)->Offset),
		    ((xVarIdNode)xIdNodeProcPar)->TypeNode);
      } else {
        xxWriteSort((void *)((xptrint)PrdVarP +
			     ((xVarIdNode)xIdNodeProcPar)->Offset),
		    ((xVarIdNode)xIdNodeProcPar)->TypeNode);
      }
    }
  }
}


/*---+---------------------------------------------------------------
     xWritePrdResult
-------------------------------------------------------------------*/
static void xWritePrdResult(
  xPrdIdNode xIdNodeProc,
  xPrdNode   PrdVarP)
{
  xIdNode xIdNodeProcPar;

  for (xIdNodeProcPar = xIdNodeProc->First;
       xIdNodeProcPar != (xIdNode)0;
       xIdNodeProcPar = xIdNodeProcPar->Suc) {
    if ( xIdNodeProcPar->EC == xFormalParEC &&
         XIS_RESULT_PARA((xVarIdNode)xIdNodeProcPar) ) {
      PRINTF(" :");
      PRINTF(" ");
      if (((xVarIdNode)xIdNodeProcPar)->Offset2 != 0) {
        /* This is the case : returns name owntype */
        xxWriteSort(*(void **)((xptrint)PrdVarP +
			       ((xVarIdNode)xIdNodeProcPar)->Offset2),
		    ((xVarIdNode)xIdNodeProcPar)->TypeNode);
      } else if (XIS_ADDRESS((xVarIdNode)xIdNodeProcPar)) {
        xxWriteSort(*(void **)((xptrint)PrdVarP +
			       ((xVarIdNode)xIdNodeProcPar)->Offset),
		    ((xVarIdNode)xIdNodeProcPar)->TypeNode);
      } else {
        xxWriteSort((void *)((xptrint)PrdVarP +
			     ((xVarIdNode)xIdNodeProcPar)->Offset),
		    ((xVarIdNode)xIdNodeProcPar)->TypeNode);
      }
      return;
    }
  }
}


/*---+---------------------------------------------------------------
     xTraceProcedureStart
-------------------------------------------------------------------*/
void xTraceProcedureStart (xPrdNode PrdVarP)
{
  xbool IsFirst = (xbool)1;

  if (xShouldBeTraced(xtProcedureStart, (xPrsNode)0)) {
    if (PrdVarP->NameNode->EC == xOperatorEC) {
       PRINTF2("*   OPERATOR START %s\n", 
               xWriteEntity((xIdNode)PrdVarP->NameNode));
    } else if (PrdVarP->NameNode->EC == xProcedureEC) {
       PRINTF2("*   PROCEDURE START %s\n", 
               xWriteEntity((xIdNode)PrdVarP->NameNode));
    }
  }
  if (xShouldBeTraced(xtProcedurePara, (xPrsNode)0)) {
    xWritePrdParameters(PrdVarP->NameNode, PrdVarP, &IsFirst);
    if (! IsFirst) xPrintString("\n");
  }
}


/*---+---------------------------------------------------------------
     xTraceNotImplCreate
-------------------------------------------------------------------*/
void xTraceNotImplCreate (char * S)
{
  if (xShouldBeTraced(xtCreate, (xPrsNode)0)) {
    PRINTF2("*   CREATE %s (UNIMPLEMENTED)\n", S);
  }
}


/*---+---------------------------------------------------------------
     xTraceNotImplProcedure
-------------------------------------------------------------------*/
void xTraceNotImplProcedure (char * S)
{
  if (xShouldBeTraced(xtProcedureStart, (xPrsNode)0)) {
    PRINTF2("*   PROCEDURE CALL %s (UNIMPLEMENTED)\n", S);
  }
}


/*---+---------------------------------------------------------------
     xTraceProcedureReturn
-------------------------------------------------------------------*/
void xTraceProcedureReturn (xPrdNode PrdVarP)
{
  if (xShouldBeTraced(xtProcedureReturn, (xPrsNode)0)) {
    if (PrdVarP->NameNode->EC == xOperatorEC) {
      PRINTF2("*   OPERATOR RETURN %s", 
              xWriteEntity((xIdNode)PrdVarP->NameNode));
    } else if (PrdVarP->NameNode->EC == xProcedureEC) {
      PRINTF2("*   PROCEDURE RETURN %s", 
              xWriteEntity((xIdNode)PrdVarP->NameNode));
    }
    if (xShouldBeTraced(xtProcedurePara, (xPrsNode)0)) {
      xWritePrdResult(PrdVarP->NameNode, PrdVarP);
    }
    xPrintString("\n");
  }
}


/*---+---------------------------------------------------------------
     xTraceExport
-------------------------------------------------------------------*/
void xTraceExport (char *In_Str)
{
  if (xShouldBeTraced(xtExport, (xPrsNode)0))
     PRINTF2("*   EXPORT : %s\n", In_Str);
}

#endif
/************************** END XTRACE *****************************/



/************************* XBREAKBEFORE ****************************/
#ifdef XBREAKBEFORE
/*---+---------------------------------------------------------------
     xSetupGRCov
-------------------------------------------------------------------*/
void xSetupGRCov(
  xPrsNode  P,
  int       SymbolNumber )
{
  xPrsIdNode PrsId;
#ifndef XNOUSEOFSERVICE
  xSrvIdNode SrvId;
#endif
  xPrdIdNode PrdId;
  xSymbolType SymbolType;

#ifdef XMONITOR
  xSysD.xCurrentSymbolNumber = SymbolNumber;
#endif
#ifndef XNOUSEOFSERVICE
  if (P->ActiveSrv != (xSrvNode)0) {
    if (P->ActiveSrv->ActivePrd == (xPrdNode)0) {
      SrvId = P->ActiveSrv->NameNode;
      while (SrvId->PAD_Function != P->ActiveSrv->RestartPAD)
        SrvId = SrvId->Super;
      xSysD.xCurrentSymbolRef = SrvId->GRrefFunc(SymbolNumber, &SymbolType);
#ifdef XCOVERAGE
      SrvId->CoverageArray[SymbolNumber]++;
#endif
    } else {  /* In procedure */
      PrdId = P->ActiveSrv->ActivePrd->NameNode;
      while (PrdId->Assoc_Function != P->ActiveSrv->ActivePrd->RestartPRD)
        PrdId = PrdId->Super;
      xSysD.xCurrentSymbolRef = PrdId->GRrefFunc(SymbolNumber, &SymbolType);
#ifdef XCOVERAGE
      PrdId->CoverageArray[SymbolNumber]++;
#endif
    }
    return;
  }
#endif
  if (P->ActivePrd == (xPrdNode)0) {
    PrsId = P->NameNode;
    while (PrsId->PAD_Function != P->RestartPAD)
      PrsId = PrsId->Super;
    xSysD.xCurrentSymbolRef = PrsId->GRrefFunc(SymbolNumber, &SymbolType);
#ifdef XCOVERAGE
    PrsId->CoverageArray[SymbolNumber]++;
#endif
  } else {  /* In procedure */
    PrdId = P->ActivePrd->NameNode;
    while (PrdId->Assoc_Function != P->ActivePrd->RestartPRD)
      PrdId = PrdId->Super;
    xSysD.xCurrentSymbolRef = PrdId->GRrefFunc(SymbolNumber, &SymbolType);
#ifdef XCOVERAGE
    PrdId->CoverageArray[SymbolNumber]++;
#endif
  }
}


#ifdef XPERFSIM
/* KEEP xSymbolTypeStr2 UPDATED WITH xSymbolType */
static char * xSymbolTypeStr2 [] = {
   "START", "INPUT", "PRIORITYINPUT", "CONTINUOUSSIGNAL",
   "TASK", "AssignmentStatement", "Assignment2Statement", "OUTPUT",
   "CREATE", "DECISION", "DecisionAny", "DecisionInformal",
   "TRANSITIONOPTION", "SET", "RESET", "EXPORT",
   "PROCEDURECALL", "ValueReturningProcedureCall", "RPC", "ValueReturningRPC",
   "IF", "LOOP", "LOOPTEST", "LOOPUPDATE", "BREAK", "CONTINUE",
   "NEXTSTATE", "JOIN", "STOP", "RETURN",
   "pCALL INPUT", "pCALL CALL", "pREPLY OUTPUT", "pCALL NEXTSTATE", 
   "pREPLY INPUT", "LABEL"
};
/* KEEP xSymbolTimes UPDATED WITH xSymbolType */
static int xSymbolTimes [] = {
   0, 0, 0,0,
   10, 10, 10, 10,
   20, 10, 10, 10,
   0, 10, 10, 10,
   10, 10, 10, 10,
   10, 10, 10, 10, 10, 10,
   0, 0, 10, 10,
   0, 10, 10, 0,
   0, 0
};

typedef struct xAtDelayStruct *xAtDelayNode;

typedef struct xAtDelayStruct {
   char        *GRReference;
   xIdNode      PrsIdNode;
   long int     SymbolNumber;
   int          Delay;
   xAtDelayNode Next;
} xAtDelayRec;

static xAtDelayNode xAtDelays = (xAtDelayNode)0;

static xbool xPerfSimOn = (xbool)0;

/*---+---------------------------------------------------------------
     xPerfSim
-------------------------------------------------------------------*/
static void xPerfSim(
  long int  SymbolNumber,
  xbool     BetweenSymbols )
{
  xPrsNode    P;
  xPrsIdNode  PrsId = (xPrsIdNode)0;
  xPrdIdNode  PrdId = (xPrdIdNode)0;
#ifndef XNOUSEOFSERVICE
  xSrvIdNode  SrvId = (xSrvIdNode)0;
#endif
  char       *SymbolRef;
  xSymbolType SymbolType;
  xAtDelayNode BP;

  if ( ! xPerfSimOn ) {
    return;
  }

  P = XREADYQ_FIRST;
#ifndef XNOUSEOFSERVICE
  if (P->ActiveSrv != (xSrvNode)0) {
    if (P->ActiveSrv->ActivePrd == (xPrdNode)0) {
      SrvId = P->ActiveSrv->NameNode;
      while (SrvId->PAD_Function != P->ActiveSrv->RestartPAD)
        SrvId = SrvId->Super;
      if (SymbolNumber == -1)
        SymbolNumber = P->ActiveSrv->RestartAddress;
      SymbolRef = SrvId->GRrefFunc(SymbolNumber, &SymbolType);
    } else {  /* In procedure */
      PrdId = P->ActiveSrv->ActivePrd->NameNode;
      while (PrdId->Assoc_Function != P->ActiveSrv->ActivePrd->RestartPRD)
        PrdId = PrdId->Super;
      if (SymbolNumber == -1)
        SymbolNumber = P->ActiveSrv->ActivePrd->RestartAddress;
      SymbolRef = PrdId->GRrefFunc(SymbolNumber, &SymbolType);
    }
  }
  else {
#endif
    if (P->ActivePrd == (xPrdNode)0) {
      PrsId = P->NameNode;
      while (PrsId->PAD_Function != P->RestartPAD)
        PrsId = PrsId->Super;
      if (SymbolNumber == -1)
        SymbolNumber = P->RestartAddress;
      SymbolRef = PrsId->GRrefFunc(SymbolNumber, &SymbolType);
    } else {  /* In procedure */
      PrdId = P->ActivePrd->NameNode;
      while (PrdId->Assoc_Function != P->ActivePrd->RestartPRD)
        PrdId = PrdId->Super;
      if (SymbolNumber == -1)
        SymbolNumber = P->ActivePrd->RestartAddress;
      SymbolRef = PrdId->GRrefFunc(SymbolNumber, &SymbolType);
    }
#ifndef XNOUSEOFSERVICE
  }
#endif
  if (SymbolType == xsNoSuchSymbolType) {
    /* This happens e.g. when starting the services in a process */
#ifdef DEBUG
    PRINTF("SymbolType == xsNoSuchSymbolType\n");
#endif
    return;
  }

  for (BP = xAtDelays;
       BP != (xAtDelayNode)0;
       BP = BP->Next) {
    if (BP->SymbolNumber == SymbolNumber) {
      if ((PrsId && BP->PrsIdNode == (xIdNode)PrsId) ||
#ifndef XNOUSEOFSERVICE
          (SrvId && BP->PrsIdNode == (xIdNode)SrvId) ||
#endif
          (PrdId && BP->PrsIdNode == (xIdNode)PrdId)) {
        if (xShouldBeTraced(xtTen, (xPrsNode)0)) {
#ifdef DEBUG
          PRINTF2("%s", BetweenSymbols ? "B-" : "");
#endif
          PRINTF3("Executing at %s. Adding %d\n",
                  BP->GRReference, BP->Delay);
        }
        xSysD.xSystemTime = xPlus_SDL_Duration(xSysD.xSystemTime,
                  SDL_Time_Lit((xint32)BP->Delay, (xint32)0));
      }
    }
  }

  if (xShouldBeTraced(xtTen, (xPrsNode)0)) {
#ifdef DEBUG
    PRINTF2("%s", BetweenSymbols ? "B-" : "");
#endif
    PRINTF3("Executing a %s symbol. Adding %d\n",
            xSymbolTypeStr2[SymbolType], xSymbolTimes[SymbolType]);
  }
  xSysD.xSystemTime = xPlus_SDL_Duration(xSysD.xSystemTime,
               SDL_Time_Lit((xint32)xSymbolTimes[SymbolType], (xint32)0));
}
#endif


/*---+---------------------------------------------------------------
     xBreakBefore
-------------------------------------------------------------------*/
xbool xBreakBefore(
          xPrsNode     P,
  xCTrace(char        *FileName)
  xCTrace(long int     LineNo)
          int          RestartAddress,
          xbool        BetweenSymbols )
{
#ifdef XMONITOR
  xbool Result;
#endif
#ifdef XGRTRACE
  int   IsGRTrace;
#endif

  xSysD.xPreviousSymbolRef = xSysD.xCurrentSymbolRef;
  xSetupGRCov(P, RestartAddress);

#ifdef XCTRACE
  xSysD.xCFileName = FileName;
  xSysD.xCLineNo = LineNo;
  xSysD.xBetweenTrans = (xbool)0;
#endif
#ifdef XMONITOR
#ifdef XPERFSIM
  xPerfSim(RestartAddress, BetweenSymbols);
#endif
  Result = xMonBreakAtSymbol(RestartAddress, BetweenSymbols);
#endif
#ifdef XGRTRACE
  IsGRTrace = xIsGRTraced((xPrsNode)0);
  if ( IsGRTrace == 2 )
    xGRTraceSymbol(xSysD.xCurrentSymbolRef);
#endif
#ifdef XMONITOR
  if ( Result ) {
#ifndef XNOUSEOFSERVICE
    if ( P->ActiveSrv != (xSrvNode)0 ) {
#if defined(XMONITOR) || defined(XTRACE)
      P->ActiveSrv->InTransition = (xbool)1;
#endif
      if ( P->ActiveSrv->ActivePrd != (xPrdNode)0 )
        P->ActiveSrv->ActivePrd->RestartAddress = RestartAddress;
      else
        P->ActiveSrv->RestartAddress = RestartAddress;
      return (xbool)1;
    }
#endif
#if defined(XMONITOR) || defined(XTRACE)
    P->InTransition = (xbool)1;
#endif
    if ( P->ActivePrd != (xPrdNode)0 )
      P->ActivePrd->RestartAddress = RestartAddress;
    else
      P->RestartAddress = RestartAddress;
    return (xbool)1;
  }
#endif
  return (xbool)0;
}


/*---+---------------------------------------------------------------
     xGRSetSymbol
-------------------------------------------------------------------*/
#ifdef THREADED_MSCTRACE
void xGRSetSymbol (xPrsNode yVarP, int SymbolNumber)
#else
void xGRSetSymbol (int SymbolNumber)
#endif /* THREADED_MSCTRACE */
{
  /* If SymbolNumber is >= 0 then input or continuous signal, else
     if SymbolNumber is -1 then nextstate or stop. */
#ifdef THREADED_MSCTRACE
  xSystemData xSysD;
  xSysD = *yVarP->SysD;
#endif /* THREADED_MSCTRACE */
  xSysD.xPreviousSymbolRef = xSysD.xCurrentSymbolRef;
  if (SymbolNumber < 0) {
    xSysD.xCurrentSymbolRef = " ";
#ifdef XCTRACE
    xSysD.xBetweenTrans = (xbool)1;
#endif
  } else {
    xSetupGRCov(XREADYQ_FIRST, SymbolNumber);
#ifdef XMSCE
    xMSCETransition(XREADYQ_FIRST);
#endif
  }
}


/*---+---------------------------------------------------------------
     xSetUpCurrentSymbolRef
-------------------------------------------------------------------*/
#ifdef THREADED_MSCTRACE
void xSetUpCurrentSymbolRef (xPrsNode PrsP )
#else
void xSetUpCurrentSymbolRef (void)
#endif /* THREADED_MSCTRACE */

    /* set up xSysD.xCurrentSymbolRef to next input to be executed */
{
  xPrsNode      P;
  xStateIdNode  StateId;
  int           InState;
  xPrsIdNode    PrsId = (xPrsIdNode)0;
  int           Pos = 0;
  int           RestartAddr;
  xbool         IsInProcess;
  xPrdIdNode    PrdId = (xPrdIdNode)0;
#ifndef XNOUSEOFSERVICE
  xSrvIdNode    SrvId = (xSrvIdNode)0;
#endif
  xSymbolType   SymbolType;

#ifdef THREADED_MSCTRACE
#undef XREADYQ_EMPTY
#undef XREADYQ_FIRST
#define XREADYQ_EMPTY  ((*(PrsP->SysD)).xReadyQueue->Suc == (*(PrsP->SysD)).xReadyQueue)
#define XREADYQ_FIRST (*(PrsP->SysD)).xReadyQueue->Suc
#endif /* THREADED_MSCTRACE */
  if (XREADYQ_EMPTY) {
    xSysD.xCurrentSymbolRef = " ";
  } else {
    P = XREADYQ_FIRST;
#ifndef XNOUSEOFSERVICE
    if (P->ActiveSrv != (xSrvNode)0) {
      IsInProcess = P->ActiveSrv->ActivePrd == (xPrdNode)0;
      if ( IsInProcess ) {
        SrvId = P->ActiveSrv->NameNode;
        InState = P->ActiveSrv->State;
        if (InState == START_STATE)
          StateId = xStartStateId;
        else
          StateId = P->ActiveSrv->NameNode->StateList[InState];
        RestartAddr = P->ActiveSrv->RestartAddress;
        if (SrvId->Super != (xSrvIdNode)0 && XPRS_STATEID(P->ActiveSrv) == START_STATE) {
          SrvId = SrvId->Super;
          while (SrvId->StateList[0] != xStartStateId)
            SrvId = SrvId->Super;
        }
        else if (SrvId->Super != (xSrvIdNode)0) {
          SrvId = SrvId->Super;
          while (SrvId->PAD_Function != P->ActiveSrv->RestartPAD) {
            SrvId = SrvId->Super;
            StateId = StateId->Super;
          }
        }
      } else {
        PrdId = P->ActiveSrv->ActivePrd->NameNode;
        InState = P->ActiveSrv->ActivePrd->State;
        if (InState == START_STATE)
          StateId = xStartStateId;
        else
          StateId =
              P->ActiveSrv->ActivePrd->NameNode->StateList[InState];
        RestartAddr = P->ActiveSrv->ActivePrd->RestartAddress;
        while (PrdId->Assoc_Function != P->ActiveSrv->ActivePrd->RestartPRD) {
          PrdId = PrdId->Super;
          StateId = StateId->Super;
        }
      }
    } else {
#endif
      IsInProcess = P->ActivePrd == (xPrdNode)0;
      if ( IsInProcess ) {
        PrsId = P->NameNode;
        InState = P->State;
        if (InState == START_STATE)
          StateId = xStartStateId;
        else
          StateId = P->NameNode->StateList[InState];
        RestartAddr = P->RestartAddress;
        if (PrsId->Super != (xPrsIdNode)0 && XPRS_STATEID(P) == START_STATE) {
#ifndef XNOUSEOFSERVICE
          if  (PrsId->Contents == (xIdNode *)0 ||
               PrsId->Contents[0] == (xIdNode)0 ||
               PrsId->Contents[0]->EC != xServiceEC ) {
#endif
            PrsId = PrsId->Super;
            while (PrsId->StateList[0] != xStartStateId)
              PrsId = PrsId->Super;
#ifndef XNOUSEOFSERVICE
          }
#endif
        }
        else if (PrsId->Super != (xPrsIdNode)0) {
          PrsId = PrsId->Super;
          while (PrsId->PAD_Function != P->RestartPAD) {
            PrsId = PrsId->Super;
            StateId = StateId->Super;
          }
        }
      } else {
        PrdId = P->ActivePrd->NameNode;
        InState = P->ActivePrd->State;
        if (InState == START_STATE)
          StateId = xStartStateId;
        else
          StateId =
              P->ActivePrd->NameNode->StateList[InState];
        RestartAddr = P->ActivePrd->RestartAddress;
        while (PrdId->Assoc_Function != P->ActivePrd->RestartPRD) {
          PrdId = PrdId->Super;
          StateId = StateId->Super;
        }
      }
#ifndef XNOUSEOFSERVICE
    }
#endif
    if (RestartAddr != 0) {
      if ( IsInProcess ) {
#ifndef XNOUSEOFSERVICE
        if (P->ActiveSrv != (xSrvNode)0)
          xSysD.xCurrentSymbolRef = (SrvId->GRrefFunc)(RestartAddr, &SymbolType);
        else
#endif
          xSysD.xCurrentSymbolRef = (PrsId->GRrefFunc)(RestartAddr, &SymbolType);
      } else {
        xSysD.xCurrentSymbolRef = (PrdId->GRrefFunc)(RestartAddr, &SymbolType);
      }
    } else if (InState == START_STATE) {
      if ( IsInProcess ) {
#ifndef XNOUSEOFSERVICE
        if (P->ActiveSrv != (xSrvNode)0)
          xSysD.xCurrentSymbolRef = (SrvId->GRrefFunc)(0, &SymbolType);
        else
#endif
          xSysD.xCurrentSymbolRef = (PrsId->GRrefFunc)(0, &SymbolType);
      } else {
        xSysD.xCurrentSymbolRef = (PrdId->GRrefFunc)(0, &SymbolType);
      }
    } else if (P->Signal->NameNode != xContSigId) {
      if ( IsInProcess ) {
#ifndef XNOUSEOFSERVICE
        if (P->ActiveSrv != (xSrvNode)0)
          while ( ((SrvId->SignalSet)[Pos] != (XSIGTYPE)0) &&
                  ((SrvId->SignalSet)[Pos] != P->Signal->NameNode) )
            Pos++;
        else
#endif
          while ( ((PrsId->SignalSet)[Pos] != (XSIGTYPE)0) &&
                  ((PrsId->SignalSet)[Pos] != P->Signal->NameNode) )
            Pos++;
      } else {
        while ( ((PrdId->SignalSet)[Pos] != (XSIGTYPE)0) &&
                ((PrdId->SignalSet)[Pos] != P->Signal->NameNode) )
          Pos++;
      }
      if ( (StateId->InputRef)[Pos] != 0 ) {
        if ( IsInProcess ) {
#ifndef XNOUSEOFSERVICE
          if (P->ActiveSrv != (xSrvNode)0)
            xSysD.xCurrentSymbolRef =
              (SrvId->GRrefFunc)((StateId->InputRef)[Pos], &SymbolType);
          else
#endif
            xSysD.xCurrentSymbolRef =
              (PrsId->GRrefFunc)((StateId->InputRef)[Pos], &SymbolType);
        } else {
          xSysD.xCurrentSymbolRef =
            (PrdId->GRrefFunc)((StateId->InputRef)[Pos], &SymbolType);
        }
      } else {
        xSysD.xCurrentSymbolRef = " ";
      }
    } else {
      xSysD.xCurrentSymbolRef = " ";
    }
  }
}

#endif
/*********************** END XBREAKBEFORE **************************/





/*************************** XMONITOR ******************************/
#if defined (THREADED_MSCTRACE) || defined (XMONITOR)
#ifdef TAUVER
char xKernelVersion[] = "SDL Simulator library, version " TAUVER;
#else
# ifdef DEBUG
char xKernelVersion[] = "SDL Simulator library, version 4.4.0 " __DATE__;
# else
char xKernelVersion[] = "SDL Simulator library, version 4.4.0";
# endif
#endif


#ifndef XNOSELECT
/*---+---------------------------------------------------------------
     xCheckForInput
-------------------------------------------------------------------*/
static xbool xCheckForInput (void)
{
  int NextChar;

#ifdef XSIMULATORUI
  if (xSysD.SESIMUICOMFlag) /* Command received */
    return (xbool)1;
  if (xSysD.xNoticeBoard.SimulatorUIStarted != 0)
    return (xbool)0;
#endif
  if (xCheckForKeyboardInput(0)) {              /* Do not wait */
    if ((NextChar = fgetc(stdin)) == '\n')
      return (xbool)1;
    ungetc(NextChar, stdin);
  }
  return (xbool)0;
}
#endif
        /* XNOSELECT */


/*---+---------------------------------------------------------------
     xCloseAllMonitorFiles
-------------------------------------------------------------------*/
void xCloseAllMonitorFiles (void)
{
  xSignalLogNode SignalLog;

  for (SignalLog = xSysD.SignalLogList;
       SignalLog != (xSignalLogNode)0;
       SignalLog = SignalLog->Next)
    if (fclose(SignalLog->File) != 0)
       xPrintString("Error closing SignalLog file\n");
  if (xSysD.InteractionLog.Active)
    if (fclose(xSysD.InteractionLog.File) != 0)
       xPrintString("Error closing Interaction Logfile\n");
  if (xSysD.CommandLog.Active)
    if (fclose(xSysD.CommandLog.File) != 0)
       xPrintString("Error closing Command Logfile\n");
#ifdef XMSCE
  xMSCEClose();
#endif
}


/*---+---------------------------------------------------------------
     AddCommand
-------------------------------------------------------------------*/
static void AddCommand( char * Str, int Number )
{
  xMonitorCommandIdNode CommandIdNode;
  xIdNode               TempId;

  CommandIdNode =
           (xMonitorCommandIdNode)xAlloc((xptrint)sizeof(xMonitorCommandIdRec));
  CommandIdNode->Parent = xSysD.xCommandTable;
  CommandIdNode->First = (xIdNode)0;
  CommandIdNode->Suc = (xIdNode)0;
  CommandIdNode->Name = (xNameType)xAlloc((xptrint)(strlen(Str) + (xptrint)1));
  (void)strcpy(CommandIdNode->Name, Str);
  CommandIdNode->EC = xMonitorCommandEC;
  CommandIdNode->CommandNo = Number;

  TempId = xSysD.xCommandTable->First;
  if (TempId == (xIdNode)0)
    xSysD.xCommandTable->First = (xIdNode)CommandIdNode;
  else {
    while (TempId->Suc != (xIdNode)0)
      TempId = TempId->Suc;
    TempId->Suc = (xIdNode)CommandIdNode;
  }
}


/*---+---------------------------------------------------------------
     xInitMonitorCommands
-------------------------------------------------------------------*/
static void xInitMonitorCommands (void)
{
  static struct xIdStruct ComIdNode =
       {xMonitorCommandEC, (xIdNode)0, (xIdNode)0, (xIdNode)0, "CommandTable"};

  xSysD.xCommandTable = &ComIdNode;
#ifdef XDEBUGPM
  AddCommand("status-PostMaster", -1);
#endif

  /* GENERAL COMMANDS */
  AddCommand("Help", 1);
  AddCommand("News", 62);
  AddCommand("Exit", 53);
  AddCommand("Quit", 3);
  AddCommand("Show-Versions", 65);
  AddCommand("Include-File", 79);
  AddCommand("@", 76);                           /* '@' DoCheckForInput */
#ifdef XCOVERAGE
  AddCommand("Print-Coverage-Table", 46);
  AddCommand("Clear-Coverage-Table", 5);
#ifdef XCONNECTPM
  if (xSysD.xNoticeBoard.PMConnected)
    AddCommand("Show-Coverage-Viewer", 6);
#endif
#endif

  /* TRACE COMMANDS */
  AddCommand("Set-Trace", 4);
  AddCommand("Reset-Trace", 8);
  AddCommand("List-Trace-Values", 54);
#ifdef XGRTRACE
  if (xSysD.xNoticeBoard.PMConnected) {
    AddCommand("Set-GR-Trace", 58);
    AddCommand("Reset-GR-Trace", 61);
    AddCommand("List-GR-Trace-Values", 63);
  }
#endif
  AddCommand("Show-Next-Symbol", 78);
  AddCommand("Show-Previous-Symbol", 80);
#ifdef XCTRACE
  AddCommand("Show-C-Line-Number", 81);
#endif
#ifdef XCONNECTPM
  AddCommand("GR-Conversion", 110);
#endif

  /* MESSAGE SEQUENCE CHART COMMANDS */
#ifdef XMSCE
  AddCommand("Set-MSC-Trace", 89);
  AddCommand("Reset-MSC-Trace", 90);
  AddCommand("List-MSC-Trace-Values", 91);
#ifdef XCONNECTPM
  if (xSysD.xNoticeBoard.PMConnected)
    AddCommand("Start-Interactive-MSC-Log", 85);
#endif
  AddCommand("Start-Batch-MSC-Log", 86);
  AddCommand("Stop-MSC-Log", 88);
  AddCommand("List-MSC-Log", 87);
  AddCommand("Define-MSC-Trace-Channels", 99);
#endif

  /* EXECUTE COMMANDS */
  AddCommand("Go", 20);
  AddCommand("Go-Forever", 77);
  AddCommand("Proceed-Until", 22);
  AddCommand("Proceed-To-Timer", 23);
  AddCommand("Next-Transition", 21);
  AddCommand("Next-Visible-Transition", 24);
  AddCommand("Next-Symbol", 47);
  AddCommand("Next-Statement", 48);
  AddCommand("Step-Symbol", 64);
  AddCommand("Step-Statement", 49);
  AddCommand("Finish", 50);
  AddCommand("Rearrange-Ready-Queue", 56);

  /* VIEW COMMANDS */
  AddCommand("Now", 2);
  AddCommand("Scope", 59);
  AddCommand("Set-Scope", 60);
  AddCommand("Stack", 37);
  AddCommand("Up", 51);
  AddCommand("Down", 52);
  AddCommand("List-Ready-Queue", 12);
  AddCommand("List-Timer", 15);
  AddCommand("List-Process", 13);
  AddCommand("List-Input-Port", 14);
  AddCommand("Examine-PId", 16);
  AddCommand("Examine-Variable", 19);
  AddCommand("Display-Array-With-Index", 113);
  AddCommand("Examine-Signal-Instance", 17);
  AddCommand("Examine-Timer-Instance", 18);
  AddCommand("Print-Paths", 9);
  AddCommand("SymbolTable", 10);
  AddCommand("ASN1-Value-Notation", 92);
  AddCommand("SDL-Value-Notation", 93);
  AddCommand("REF-Address-Notation", 94);
  AddCommand("REF-Value-Notation", 95);
  AddCommand("REF-Deref-Value-Notation", 109);
  AddCommand("Define-Integer-Output-Mode", 107);

  /* BREAKPOINT COMMANDS */
  AddCommand("Breakpoint-Transition", 34);
  AddCommand("Breakpoint-Output", 36);
  AddCommand("Breakpoint-Variable", 32);
  AddCommand("Breakpoint-At", 33);
  AddCommand("Remove-Breakpoint", 35);
  AddCommand("Remove-All-Breakpoints", 135);
  AddCommand("List-Breakpoints", 38);
  AddCommand("Save-Breakpoints", 138);
  AddCommand("Show-Breakpoint", 31);
  AddCommand("Remove-At", 30);

  /* ENVIRONMENT COMMANDS */
  AddCommand("Output-To", 26);
  AddCommand("Output-Via", 27);
  AddCommand("Output-None", 57);
  AddCommand("Output-From-Env", 108);
#ifdef XPMCOMM
  if (xSysD.xNoticeBoard.PMConnected) {
    AddCommand("Start-SDL-Env", 69);
    AddCommand("Stop-SDL-Env", 70);
    AddCommand("Call-SDL-Env", 71);
    AddCommand("Start-SDT-Env", 69);
    AddCommand("Stop-SDT-Env", 70);
    AddCommand("Call-SDT-Env", 71);
  }
#endif
#ifdef XITEXCOMM
  if (xSysD.xNoticeBoard.PMConnected) {
    AddCommand("Start-ITEX-Com", 82);
    AddCommand("ITEX-Channel", 111);
  }
#endif
#ifdef XSDLENVUI
  if (xSysD.xNoticeBoard.PMConnected)
    AddCommand("Start-UI", 75);
#endif
#ifdef XENV
  AddCommand("Start-Env", 72);
  AddCommand("Stop-Env", 73);
  AddCommand("Call-Env", 74);
#endif

  /* LOG COMMANDS */
  AddCommand("Signal-Log", 66);
  AddCommand("Close-Signal-Log", 67);
  AddCommand("List-Signal-Log", 68);
  AddCommand("Log-On", 28);
  AddCommand("Log-Off", 29);
  AddCommand("Command-Log-On", 83);
  AddCommand("Command-Log-Off", 84);

  /* CHANGE SYSTEM COMMANDS */
  AddCommand("Output-Internal", 25);
  AddCommand("Nextstate", 40);
  AddCommand("Create", 39);
  AddCommand("Stop", 41);
  AddCommand("Set-Timer", 43);
  AddCommand("Reset-Timer", 44);
  AddCommand("Assign-Value", 42);
  AddCommand("Remove-Signal-Instance", 45);
  AddCommand("Rearrange-Input-Port", 55);

#ifdef XCONNECTPM
  if (xSysD.xNoticeBoard.PMConnected)
    AddCommand("Start-SimUI", 7);
#endif

  AddCommand("Define-Continue-Mode", 11);

#ifdef XCONNECTPM
  if (xSysD.xNoticeBoard.PMConnected) {
    AddCommand("Connect-To-Editor", 96);
    AddCommand("Disconnect-Editor", 97);
  }
#endif
  AddCommand( "Cd", 98);
#ifdef XPERFSIM
  AddCommand( "List-Delay", 101);
  AddCommand( "Define-Delay", 102);
  AddCommand( "Save-Delay", 103);
  AddCommand( "Define-At-Delay", 104);
  AddCommand( "Remove-Delay", 105);
  AddCommand( "Performance-Simulation", 106);
#endif
#ifdef FORK_PROCESS
#ifndef _Windows
  AddCommand( "Fork-Process", 112);
#endif
#endif
  AddCommand("Save-State", 114);
  AddCommand("Restore-State", 115);
  AddCommand("xSet", 116);
}


/*---+---------------------------------------------------------------
     xInitMonitorSystem
-------------------------------------------------------------------*/
void xInitMonitorSystem (void)
{
#if defined(XCLOCK)
  xSysD.xTimeInMonitor = SDL_Duration_Lit( (xint32)0, (xint32)0 );
#endif
#ifdef XENV
  xSysD.xInEnvOn = (xbool)0;
#endif
  xSysD.Interrupted = 0;
  xSysD.xProceedUntil = 0;
  xSysD.xGoForever = 0;

  xSysD.StopInMonitor = 1;
  xSysD.StoppedInMonitor = 0;
  xSysD.StepSymbol = 0;
  xSysD.StepStatement = 0;
  xSysD.NextSymbol = 0;
  xSysD.NextStatement = 0;
  xSysD.Finish = 0;
  xSysD.NextLevel = 0;
  xSysD.xStepToVisible = 0;
  xSysD.WelcomeMessagePrinted = 0;
/* Init some variables declared in Kernel */
  xSysD.xMonitorCreate = (xbool)0;
  xSysD.xMonitorOutput = (xbool)0;
  xSysD.xDynamicError = (xbool)0;
  xSysD.xSavingState = (xbool)0;
  xSysD.xRestoringState = (xbool)0;

  xSysD.AtBreakpoints = (xAtBreakpointNode)0;
  xSysD.VariableBreakpoints = (xVariableBreakpointNode)0;
  xSysD.TransitionBreakpoints = (xBreakpointNode)0;
  xSysD.OutputBreakpoints = (xBreakpointOutputNode)0;
  xSysD.SignalLogList = (xSignalLogNode)0;
  xSysD.xNextMonTimeVar = xMaxTime;

#ifdef TARGETSIM
#ifdef XCONNECTPM
  if (xSysD.xNoticeBoard.TargetParam == 3 ||
      xSysD.xNoticeBoard.TargetParam == 2) {
#ifndef XNOSELECT
    if (xSysD.xNoticeBoard.TargetParam == 3)
      xSysD.xDoCheckForInput = (xbool)0;
#endif
    xSysD.StopInMonitor = 0;
    xSysD.xCommandTable = (xIdNode)0;
    return;
  }
#endif
#endif
      /* TARGETSIM */

  xInitMonitorCommands();
}

/*---+---------------------------------------------------------------
     xCheckTrace
-------------------------------------------------------------------*/
static xbool xCheckTrace (xIdNode FromNode)
{
  xIdNode  R;
  xPrsNode PrsNode;

  if (FromNode == xSymbolTableRoot) {
#ifdef XTRACE
    if (xSysD.Trace_Default > 0)
      return (xbool)0;
#endif
#ifdef XGRTRACE
    if (xSysD.GRTrace > 0)
      return (xbool)0;
#endif
  }

  for (R = FromNode->First; R != (xIdNode)0; R = R->Suc) {
    if (R->EC == xSystemEC) {
#ifdef XTRACE
      if (((xSystemIdNode)R)->Trace_Default > 0)
        return (xbool)0;
#endif
#ifdef XGRTRACE
      if (((xSystemIdNode)R)->GRTrace > 0)
        return (xbool)0;
#endif
    }
    else if (R->EC == xBlockEC) {
#ifdef XTRACE
      if (((xBlockIdNode)R)->Trace_Default > 0)
        return (xbool)0;
#endif
#ifdef XGRTRACE
      if (((xBlockIdNode)R)->GRTrace > 0)
        return (xbool)0;
#endif
    }
    else if (R->EC == xProcessEC) {
#ifdef XTRACE
      if (((xPrsIdNode)R)->Trace_Default > 0)
        return (xbool)0;
#endif
#ifdef XGRTRACE
      if (((xPrsIdNode)R)->GRTrace > 0)
        return (xbool)0;
#endif
      for (PrsNode = *((xPrsIdNode)R)->ActivePrsList;
           PrsNode != (xPrsNode)0;
           PrsNode = PrsNode->NextPrs) {
#ifdef XTRACE
        if (PrsNode->Trace_Default > 0)
          return (xbool)0;
#endif
#ifdef XGRTRACE
        if (PrsNode->GRTrace > 0)
          return (xbool)0;
#endif
      }
    }
  }
  for (R = FromNode->First; R != (xIdNode)0; R = R->Suc) {
    if ( ! xCheckTrace(R) )
      return (xbool)0;
  }
  return (xbool)1;
}


#ifdef XTRACE
/*---+---------------------------------------------------------------
     WriteTraces
-------------------------------------------------------------------*/

#define MaxTraceLevel 6

static char *TraceHelp[] = {
  /* 0 */   " = No trace",
  /* 1 */   " = Signals to and from environment",
  /* 2 */   " = Transition start and timer outputs",
  /* 3 */   " = Important SDL actions",
  /* 4 */   " = All SDL actions",
  /* 5 */   " = All SDL actions + Result",
  /* 6 */   " = All SDL actions + Result + Parameters"
};

static void WriteTraces (xIdNode  FromNode)
{
  xIdNode  R;
  xPrsNode PrsNode;
  int      Trace;

  if (FromNode == xSymbolTableRoot) {
    Trace = xSysD.Trace_Default;
    PRINTF3("Default     : %d%s\n", Trace,
                Trace > MaxTraceLevel ? "" : TraceHelp[Trace]);
  }

  for (R = FromNode->First; R != (xIdNode)0; R = R->Suc) {
    if (R->EC == xSystemEC) {
      Trace = ((xSystemIdNode)R)->Trace_Default;
      if (Trace >= 0) {
        PRINTF4("System  %s  : %d%s\n", xWriteEntity(R), Trace,
                Trace > MaxTraceLevel ? "" : TraceHelp[Trace]);
      }
    }
    else if (R->EC == xBlockEC) {
      Trace = ((xBlockIdNode)R)->Trace_Default;
      if (Trace >= 0) {
        PRINTF4("Block   %s  : %d%s\n", xWriteEntity(R), Trace,
                Trace > MaxTraceLevel ? "" :  TraceHelp[Trace]);
      }
    }
    else if (R->EC == xProcessEC) {
      Trace = ((xPrsIdNode)R)->Trace_Default;
      if (Trace >= 0) {
        PRINTF4("Process %s  : %d%s\n", xWriteEntity(R), Trace,
                Trace > MaxTraceLevel ? "" : TraceHelp[Trace]);
      }
      for (PrsNode = *((xPrsIdNode)R)->ActivePrsList;
           PrsNode != (xPrsNode)0;
           PrsNode = PrsNode->NextPrs) {
        Trace = PrsNode->Trace_Default;
        if (Trace >= 0) {
          PRINTF4("PId     %s  : %d%s\n", xWri_SDL_PId(&(PrsNode->Self)), Trace,
                Trace > MaxTraceLevel ? "" : TraceHelp[Trace]);
        }
      }
    }
  }
  for ( R=FromNode->First; R!=(xIdNode)0; R=R->Suc )
    WriteTraces(R);
}
#endif
       /* XTRACE */


#ifdef XGRTRACE
/*---+---------------------------------------------------------------
     WriteGRTraces
-------------------------------------------------------------------*/

#define MaxGRTraceLevel 2

static char *GRTraceHelp[] = {
  /* 0 */   " = GR trace off",
  /* 1 */   " = Show next symbol when entering monitor",
  /* 2 */   " = Show all symbols"
};

static void WriteGRTraces (xIdNode  FromNode)
{
  xIdNode  R;
  xPrsNode PrsNode;
  int      Trace;

  if (FromNode == xSymbolTableRoot) {
    Trace = xSysD.GRTrace;
    PRINTF3("Default    %d%s\n", Trace,
            Trace > MaxGRTraceLevel ? "" : GRTraceHelp[Trace]);
  }

  for (R = FromNode->First; R != (xIdNode)0; R = R->Suc) {
    if (R->EC == xSystemEC) {
      Trace = ((xSystemIdNode)R)->GRTrace;
      if (Trace >= 0) {
        PRINTF4("System  %s %d%s\n", xWriteEntity(R), Trace,
                Trace > MaxGRTraceLevel ? "" : GRTraceHelp[Trace]);
      }
    }
    else if (R->EC == xBlockEC) {
      Trace = ((xBlockIdNode)R)->GRTrace;
      if (Trace >= 0) {
        PRINTF4("Block   %s %d%s\n", xWriteEntity(R), Trace,
                Trace > MaxGRTraceLevel ? "" : GRTraceHelp[Trace]);
      }
    }
    else if (R->EC == xProcessEC) {
      Trace = ((xPrsIdNode)R)->GRTrace;
      if (Trace >= 0) {
        PRINTF4("Process %s %d%s\n", xWriteEntity(R), Trace,
                Trace > MaxGRTraceLevel ? "" : GRTraceHelp[Trace]);
      }
      for (PrsNode = *((xPrsIdNode)R)->ActivePrsList;
           PrsNode != (xPrsNode)0;
           PrsNode = PrsNode->NextPrs) {
        Trace = PrsNode->GRTrace;
        if (Trace >= 0) {
          PRINTF4("PId     %s %d%s\n", xWri_SDL_PId(&(PrsNode->Self)), Trace,
                  Trace > MaxGRTraceLevel ? "" : GRTraceHelp[Trace]);
        }
      }
    }
  }
  for ( R=FromNode->First; R!=(xIdNode)0; R=R->Suc )
    WriteGRTraces(R);
}
#endif
       /* XGRTRACE */


#ifdef XMSCE

/*---+---------------------------------------------------------------
     WriteMSCETraces
-------------------------------------------------------------------*/
#define MaxMSCETraceLevel 3

static char *MSCETraceHelp[] = {
  /* 0 */   " = No MSC trace",
  /* 1 */   " = Conditional MSC trace",
  /* 2 */   " = Unconditional MSC trace",
  /* 3 */   " = Block trace",
};

static void WriteMSCETraces (xIdNode FromNode)
{
  xIdNode  R;
  xPrsNode PrsNode;
  int      Trace;

  if (FromNode == xSymbolTableRoot) {
    Trace = xSysD.MSCETrace;
    PRINTF3("Default        %d%s\n", Trace,
            Trace > MaxMSCETraceLevel ? "" : MSCETraceHelp[Trace]);
  }

  for (R = FromNode->First; R != (xIdNode)0; R = R->Suc) {
    if (R->EC == xSystemEC) {
      Trace = ((xSystemIdNode)R)->MSCETrace;
      if (Trace >= 0) {
        PRINTF4("System  %-10s %d%s\n", xWriteEntity(R), Trace,
                Trace > MaxMSCETraceLevel ? "" : MSCETraceHelp[Trace]);
      }
    }
    else if (R->EC == xBlockEC) {
      Trace = ((xBlockIdNode)R)->MSCETrace;
      if (Trace >= 0) {
        PRINTF4("Block   %-10s %d%s\n", xWriteEntity(R), Trace,
                Trace > MaxMSCETraceLevel ? "" : MSCETraceHelp[Trace]);
      }
    }
    else if (R->EC == xProcessEC) {
      Trace = ((xPrsIdNode)R)->MSCETrace;
      if (Trace >= 0) {
        PRINTF4("Process %-10s %d%s\n", xWriteEntity(R), Trace,
                Trace > MaxMSCETraceLevel ? "" : MSCETraceHelp[Trace]);
      }
      for (PrsNode = *((xPrsIdNode)R)->ActivePrsList;
           PrsNode != (xPrsNode)0;
           PrsNode = PrsNode->NextPrs) {
        Trace = PrsNode->MSCETrace;
        if (Trace >= 0) {
          PRINTF4("PId     %-10s %d%s\n", xWri_SDL_PId(&(PrsNode->Self)), Trace,
                  Trace > MaxMSCETraceLevel ? "" : MSCETraceHelp[Trace]);
        }
      }
    }
  }
  for ( R=FromNode->First; R!=(xIdNode)0; R=R->Suc )
    WriteMSCETraces(R);
}
#endif
       /* XMSCE */


/*---+---------------------------------------------------------------
     xVerify
-------------------------------------------------------------------*/
xbool xVerify (char * Prompt)
{
  char    strVar[256];

  (void)xPromptQuestionMark(Prompt,
    "Yes if first nonblank character is 'y' or 'Y', otherwise No : ", strVar);
  if (strVar[0]== 'y' || strVar[0] == 'Y')
    return (xbool)1;
  return (xbool)0;
}


/*---+---------------------------------------------------------------
     xChoose2
-------------------------------------------------------------------*/
/* Prompts the user to choose between Alt1 and Alt2.
Returns 1 or 2 depending on the user choice.
No default value accepted.
If failure: returns 0
*/
static int xChoose2(
  char * Prompt,
  char * Alt1,
  char * Alt2)
{
  xxToken Token;
  char    strVar[256];

 restart:
  Token = xScanToken(strVar);
  if (Token == xxEoln) {
    xPrintString(Prompt);
  } else if (Token == xxQuestionMark) {
    xSkipLine();
    PRINTF2( "%s ", Alt1 );
    PRINTF2( "%s ", Alt2 );
    xPrintString(": ");
  } else if (Token==xxMinus) {
    return 0;
  } else if (strVar[0] != '\0') {
    if (xfEqualIdString(strVar, Alt1)) {
      return 1;
    } else if (xfEqualIdString(strVar, Alt2)) {
      return 2;
    } else {
      return 0;
    }
  } else {
    return 0;
  }

  while (1) {
    Token = xScanToken(strVar);
    if (Token == xxEoln) {
      PRINTF2( "%s ", Alt1 );
      PRINTF2( "%s ", Alt2 );
      xPrintString(": ");
    } else if (Token == xxQuestionMark) {
      xSkipLine();
      PRINTF2( "%s ", Alt1 );
      PRINTF2( "%s ", Alt2 );
      xPrintString(": ");
    } else if (Token==xxMinus) {
      goto restart;
    } else if (strVar[0] != '\0') {
      if (xfEqualIdString(strVar, Alt1)) {
	return 1;
      } else if (xfEqualIdString(strVar, Alt2)) {
	return 2;
      } else {
	return 0;
      }
    } else {
      return 0;
    }
  }
}

/*---+---------------------------------------------------------------
     xChooseAlternative
-------------------------------------------------------------------*/
/* Prompts the user to choose between the alternatives in the NL
 * 'alternatives'. 'xChooseAlternative' returns a number >= 0 if the user
 * chooses the corresponding alternative. Otherwise it returns -1 for '-' or
 * -2 for invalid input or -3 if canceled with '[' (Cancel button in ValUI).
*/
static int  xChooseAlternative(
  char * Prompt,
  char ** alternatives)
{
  int     i;
  xxToken Token;
  char    strVar[256];

  Token = xScanToken(strVar);
  if (Token == xxEoln) {
    PRINTF(Prompt);
  } else if (Token == xxQuestionMark) {
    xSkipLine();
    for (i = 0; alternatives[i]; i++) {
      PRINTF2( "%s ", alternatives[i] );
    }
    PRINTF(": ");
  } else if (Token==xxMinus) {
    return -1;
  } else if (Token==xxLBracket) {
    return -3;
  } else if (strVar[0] != '\0') {
    for (i = 0; alternatives[i]; i++) {
      if (xfEqualIdString(strVar, alternatives[i])) {
        return i;
      }
    }
    return -2;
  } else {
    return -2;
  }

  for (;;) {
    Token = xScanToken(strVar);
    if (Token == xxEoln) {
      for (i = 0; alternatives[i]; i++) {
        PRINTF2( "%s ", alternatives[i] );
      }
      PRINTF(": ");
    } else if (Token == xxQuestionMark) {
      xSkipLine();
      for (i = 0; alternatives[i]; i++) {
        PRINTF2( "%s ", alternatives[i] );
      }
      PRINTF(": ");
    } else if (Token==xxMinus) {
      return -1;
    } else if (Token==xxLBracket) {
      return -3;
    } else if (strVar[0] != '\0') {
      for (i = 0; alternatives[i]; i++) {
        if (xfEqualIdString(strVar, alternatives[i])) {
          return i;
        }
      }
      return -2;
    } else {
      return -2;
    }
  }
}

/*---+---------------------------------------------------------------
     xWriteProcessHeading
-------------------------------------------------------------------*/
static void xWriteProcessHeading (void)
{
  xWriteBuf_Fmt("%-*s %-*s%-9sSignal instance\n",
    xfShortIdentifierLength+7,
    "PId",
    xfShortIdentifierLength+1,
    "State",
    "Signals");
}


/*---+---------------------------------------------------------------
     SignalsInPort
-------------------------------------------------------------------*/
static int SignalsInPort (xPrsNode PrsNode)
{
  int         count;
  xSignalNode Signal;

  count = 0;
  XBEGIN_INPUTPORT_LOOP(PrsNode, Signal)
    if (! XIS_STARTUP_SIGNAL(Signal))
      count++;
  XEND_INPUTPORT_LOOP
  return count;
}


/*---+---------------------------------------------------------------
     WriteProcessInfo
-------------------------------------------------------------------*/
static void WriteProcessInfo(
  xPrsNode PrsNode,
  char * Str)
{
  int         count;
  char        strVar[256];
  static WriteBuf *Buf = 0;

  count = SignalsInPort(PrsNode);
#ifndef XNOUSEOFSERVICE
  if (PrsNode->ActiveSrv == (xSrvNode)0) {
#endif
    strcpy(strVar,
         xGetState(PrsNode, (xPrdNode)0, PrsNode->NameNode->StateList,
                   XPRS_STATEID(PrsNode))->Name);
    if (PrsNode->InTransition || PrsNode->ActivePrd != (xPrdNode)0)
      strcat(strVar, "*");
#ifndef XNOUSEOFSERVICE
  } else {
    strcpy(strVar, "-");
  }
#endif
  xWriteBuf_Fmt("%-*s %-*s%-9d%s",
    xfShortIdentifierLength+7,
    xWri_SDL_PId_No_Qua(&(PrsNode->Self)),
    xfShortIdentifierLength+1,
    strVar,
    count,
    XPRS_NEXT_REC_SIG(PrsNode) != 0 ?
      XSIGNAL_IDNODE(XPRS_NEXT_REC_SIG(PrsNode))->Name : "-");
  if (XPRS_NEXT_REC_SIG(PrsNode) != 0)
    if (XSIGNAL_IDNODE(XPRS_NEXT_REC_SIG(PrsNode)) == xContSigId)
      PRINTF2(" Prio %d", XCONT_SIG_PRIO(XPRS_NEXT_REC_SIG(PrsNode)));
  xPrintString("\n");

  if (xNeedsQualifier((xIdNode)PrsNode->NameNode)) {
    PRINTF2("%s   ", Str);
    if (!Buf)
      Buf = WriteBuf_New(60);
    else
      WriteBuf_Clear(Buf);
    xGetQualifier(Buf, (xIdNode)PrsNode->NameNode, PrsNode->BlockInstNumber);
    xPrintString(WriteBuf_Data(Buf));
    xPrintString("\n");
  }

#ifndef XNOUSEOFSERVICE
  if (PrsNode->ActiveSrv != (xSrvNode)0) {
    strcpy(strVar,
         xGetState(PrsNode, (xPrdNode)0, PrsNode->ActiveSrv->NameNode->StateList,
                   XPRS_STATEID(PrsNode->ActiveSrv))->Name);
    if (PrsNode->ActiveSrv->InTransition ||
        PrsNode->ActiveSrv->ActivePrd != (xPrdNode)0)
      strcat(strVar, "*");
    xWriteBuf_Fmt("%s   %-*s %s\n", Str,
      xfShortIdentifierLength+4,
      xWriteEntity((xIdNode)PrsNode->ActiveSrv->NameNode),
      strVar);

    if (PrsNode->ActiveSrv->ActivePrd != (xPrdNode)0) {
      xWriteBuf_Fmt("%s     %-*s %s%c\n", Str,
        xfShortIdentifierLength+4,
        xPrdInstance(PrsNode->ActiveSrv->ActivePrd),
        xGetState(PrsNode, PrsNode->ActiveSrv->ActivePrd,
          PrsNode->ActiveSrv->ActivePrd->NameNode->StateList,
          PrsNode->ActiveSrv->ActivePrd->State
        )->Name,
        PrsNode->ActiveSrv->InTransition ? '*' : ' ');
    }
  } else {
#endif
    if (PrsNode->ActivePrd != (xPrdNode)0) {
      xWriteBuf_Fmt("%s   %-*s %s%c\n", Str,
        xfShortIdentifierLength+4,
        xPrdInstance(PrsNode->ActivePrd),
        xGetState(PrsNode, PrsNode->ActivePrd,
          PrsNode->ActivePrd->NameNode->StateList,
          PrsNode->ActivePrd->State
        )->Name,
        PrsNode->InTransition ? '*' : ' ');
    }
#ifndef XNOUSEOFSERVICE
  }
#endif
}


/*---+---------------------------------------------------------------
     xListAllPId
-------------------------------------------------------------------*/
static void xListAllPId (xIdNode FromNode)
{
  xIdNode  IdNode;
  xPrsNode PrsNode;

  for ( IdNode  = FromNode->First;
        IdNode != (xIdNode)0;
        IdNode  = IdNode->Suc ){
    if (IdNode->EC == xProcessEC) {
      for (PrsNode = *((xPrsIdNode)IdNode)->ActivePrsList;
           PrsNode != (xPrsNode)0;
           PrsNode = PrsNode->NextPrs) {
        WriteProcessInfo(PrsNode, "");
      }
    }
  }
  for ( IdNode  = FromNode->First;
        IdNode != (xIdNode)0;
        IdNode  = IdNode->Suc ){
    xListAllPId(IdNode);
  }
}

/*---+---------------------------------------------------------------
     xGetCommand
-------------------------------------------------------------------*/
static xMonitorCommandIdNode xGetCommand(
  char      *NameP,
  xxToken    Token,
  xIdNode    FromNode)
{
  xfCodeType Code;
  long       ECSet;
  xIdNode    xIdNodeVar;

  if (Token != xxId && Token != xxAt)
    return (xMonitorCommandIdNode)0;
  ECSet = 1L << ((long)xMonitorCommandEC);
  xfDecodeId(NameP, FromNode, ECSet, &xIdNodeVar, &Code, (xIdNode)0);
  if (Code == xfOk)
    return (xMonitorCommandIdNode)xIdNodeVar;
  else if (Code == xfAmbiguous) {
    xPrintString("Command was ambiguous, it might be an abbreviation of :\n");
    for (xIdNodeVar = FromNode->First;
         xIdNodeVar != (xIdNode)0;
         xIdNodeVar = xIdNodeVar->Suc) {
      if (xIdNodeVar->EC == xMonitorCommandEC)
        if (xfEqualIdString(NameP, xIdNodeVar->Name) == 1)
          PRINTF2("%s ", xIdNodeVar->Name);
    }
    xPrintString("\n");
  }
  else if (Code == xfNotFound) {
    PRINTF2("Command was not found: %s\n", NameP);
  }
  return (xMonitorCommandIdNode)0;
}


/*---+---------------------------------------------------------------
     xInitScope
-------------------------------------------------------------------*/
static void xInitScope (void)
{
#ifndef XNOUSEOFSERVICE
  xSysD.xSrvScope = (xSrvNode)0;
#endif
  if ( ! XTIMERQ_EMPTY &&
       xLE_SDL_Time(XFIRST_TIMER_TIME, xSysD.NowInMonitor) ) {
    xSysD.xPrsScope = XPID_TO_PRS(XTIMER_RECEIVER(XTIMERQ_FIRST));
    xSysD.xPrdScope = xSysD.xPrsScope->ActivePrd;
  } else if (! XREADYQ_EMPTY) {
    xSysD.xPrsScope = XREADYQ_FIRST;
#ifndef XNOUSEOFSERVICE
    if (xSysD.xPrsScope->ActiveSrv != (xSrvNode)0) {
      xSysD.xSrvScope = xSysD.xPrsScope->ActiveSrv;
      xSysD.xPrdScope = xSysD.xPrsScope->ActiveSrv->ActivePrd;
    } else
#endif
      xSysD.xPrdScope = xSysD.xPrsScope->ActivePrd;
  } else if ( ! XTIMERQ_EMPTY ) {
    xSysD.xPrsScope = XPID_TO_PRS(XTIMER_RECEIVER(XTIMERQ_FIRST));
    xSysD.xPrdScope = xSysD.xPrsScope->ActivePrd;
  } else {
    xSysD.xPrsScope = (xPrsNode)0;
    xSysD.xPrdScope = (xPrdNode)0;
  }
}


/*---+---------------------------------------------------------------
     xPrintScope
-------------------------------------------------------------------*/
void xPrintScope (xbool PrintScope)
{
#ifdef XGRTRACE
  int         GRTraceLevel;
  xSymbolType SymbolType;
  xPrsIdNode  PrsId;
  xPrdIdNode  PrdId;
#ifndef XNOUSEOFSERVICE
  xSrvIdNode SrvId;
#endif
#endif

  if (xSysD.xPrsScope == (xPrsNode)0) {
    if (PrintScope)
       xPrintString("No scope is set\n");
  } else {
    if (PrintScope) {
      PRINTF2("Process scope : %s\n", 
              xWri_SDL_PId(&(xSysD.xPrsScope->Self)));
#ifndef XNOUSEOFSERVICE
      if (xSysD.xSrvScope != (xSrvNode)0) {
        PRINTF2("Service scope : %s\n", xSysD.xSrvScope->NameNode->Name);
      }
#endif
      if (xSysD.xPrdScope != (xPrdNode)0) {
        PRINTF2("Procedure scope : %s\n", xPrdInstance(xSysD.xPrdScope));
      }
    }
#ifdef XGRTRACE
    GRTraceLevel = xIsGRTraced(xSysD.xPrsScope);
    if (GRTraceLevel >= 1) {
      if ( !PrintScope && !XTIMERQ_EMPTY &&
           ( XREADYQ_EMPTY ||
             xLE_SDL_Time(XFIRST_TIMER_TIME, xSysD.NowInMonitor)
           )
         ) {
          /* Next event is timer output, only if monitor just restarted */
        xGRTraceSymbol(XTIMER_IDNODE(XTIMERQ_FIRST)->RefToDefinition);
#ifndef XNOUSEOFSERVICE
      } else if (xSysD.xSrvScope != (xSrvNode)0) {
        if (xSysD.xPrdScope != (xPrdNode)0) {
          if (xSysD.xPrdScope != xSysD.xSrvScope->ActivePrd) {
              /* In PrdScope which is not active (at call) */
            PrdId = xSysD.xPrdScope->NameNode;
            while (PrdId->Assoc_Function != xSysD.xPrdScope->RestartPRD)
              PrdId = PrdId->Super;
            xGRTraceSymbol(PrdId->GRrefFunc
                (xSysD.xPrdScope->CallAddress, &SymbolType));
          }
          else if (xSysD.xSrvScope->InTransition ||
                   xSysD.xPrsScope->Signal != 0) {
              /* In PrdScope which is active, InTransition */
            PrdId = xSysD.xPrdScope->NameNode;
            while (PrdId->Assoc_Function != xSysD.xPrdScope->RestartPRD)
              PrdId = PrdId->Super;
            xGRTraceSymbol(PrdId->GRrefFunc
                (xSysD.xPrdScope->RestartAddress, &SymbolType));
          }
          else
              /* In PrdScope which is active, In state */
            xGRTraceSymbol(
              xGetState(xSysD.xPrsScope, xSysD.xSrvScope->ActivePrd, 
                        xSysD.xSrvScope->ActivePrd->NameNode->StateList, 
                        xSysD.xSrvScope->ActivePrd->State)
              ->RefToDefinition);
        } else {
          if (xSysD.xSrvScope->ActivePrd != (xPrdNode)0) {
              /* In service which is not active (at call) */
            SrvId = xSysD.xSrvScope->NameNode;
            while (SrvId->PAD_Function != xSysD.xSrvScope->RestartPAD)
              SrvId = SrvId->Super;
            xGRTraceSymbol(SrvId->GRrefFunc
                (xSysD.xSrvScope->CallAddress, &SymbolType));
          }
          else if (xSysD.xSrvScope->InTransition ||
                   xSysD.xPrsScope->Signal != 0) {
              /* In service which is active, InTransition */
            SrvId = xSysD.xSrvScope->NameNode;
            while (SrvId->PAD_Function != xSysD.xSrvScope->RestartPAD)
              SrvId = SrvId->Super;
            xGRTraceSymbol(SrvId->GRrefFunc
                (xSysD.xSrvScope->RestartAddress, &SymbolType));
          }
          else
              /* In service which is active, in state */
            xGRTraceSymbol(
              xGetState(xSysD.xPrsScope, (xPrdNode)0, 
                        xSysD.xSrvScope->NameNode->StateList, 
                        xSysD.xSrvScope->State)
              ->RefToDefinition);
        }
#endif
      } else {
        if (xSysD.xPrdScope != (xPrdNode)0) {
          if (xSysD.xPrdScope != xSysD.xPrsScope->ActivePrd) {
              /* In PrdScope which is not active (at call) */
            PrdId = xSysD.xPrdScope->NameNode;
            while (PrdId->Assoc_Function != xSysD.xPrdScope->RestartPRD)
              PrdId = PrdId->Super;
            xGRTraceSymbol(PrdId->GRrefFunc
                (xSysD.xPrdScope->CallAddress, &SymbolType));
          }
          else if (xSysD.xPrsScope->InTransition ||
                   xSysD.xPrsScope->Signal != 0) {
              /* In PrdScope which is active, InTransition */
            PrdId = xSysD.xPrdScope->NameNode;
            while (PrdId->Assoc_Function != xSysD.xPrdScope->RestartPRD)
              PrdId = PrdId->Super;
            xGRTraceSymbol(PrdId->GRrefFunc
                (xSysD.xPrdScope->RestartAddress, &SymbolType));
          }
          else
              /* In PrdScope which is active, In state */
            xGRTraceSymbol(
              xGetState(xSysD.xPrsScope, xSysD.xPrsScope->ActivePrd, 
                        xSysD.xPrsScope->ActivePrd->NameNode->StateList, 
                        xSysD.xPrsScope->ActivePrd->State)
              ->RefToDefinition);
        } else {
          if (xSysD.xPrsScope->ActivePrd != (xPrdNode)0) {
              /* In process which is not active (at call) */
            PrsId = xSysD.xPrsScope->NameNode;
            while (PrsId->PAD_Function != xSysD.xPrsScope->RestartPAD)
              PrsId = PrsId->Super;
            xGRTraceSymbol(PrsId->GRrefFunc
                (xSysD.xPrsScope->CallAddress, &SymbolType));
          }
#ifndef XNOUSEOFSERVICE
          else if (xSysD.xPrsScope->ActiveSrv != (xSrvNode)0)
              /* In process which contains services */
            xGRTraceSymbol(xSysD.xPrsScope->NameNode->RefToDefinition);
#endif
          else if (xSysD.xPrsScope->InTransition ||
                   xSysD.xPrsScope->Signal != 0) {
              /* In process which is active, InTransition */
            PrsId = xSysD.xPrsScope->NameNode;
            while (PrsId->PAD_Function != xSysD.xPrsScope->RestartPAD)
              PrsId = PrsId->Super;
            xGRTraceSymbol(PrsId->GRrefFunc
                (xSysD.xPrsScope->RestartAddress, &SymbolType));
          }
          else
              /* In process which is active, in state */
            xGRTraceSymbol(
              xGetState(xSysD.xPrsScope, (xPrdNode)0, 
                        xSysD.xPrsScope->NameNode->StateList, 
                        xSysD.xPrsScope->State)
              ->RefToDefinition);
        }
      }
    }
#endif
  }
}


/*---+---------------------------------------------------------------
     xChangeScope
-------------------------------------------------------------------*/
static void xChangeScope (xPrsNode PrsNode)
{
  if (XREADYQ_FIRST == PrsNode) {
    if ( xSysD.xPrsScope == (xPrsNode)0 ||
         ( ! XTIMERQ_EMPTY &&
           xGT_SDL_Time(XFIRST_TIMER_TIME, xSysD.NowInMonitor) &&
           xSysD.xPrsScope == XPID_TO_PRS(XTIMER_RECEIVER(XTIMERQ_FIRST)) &&
           xSysD.xPrsScope->ActivePrd == xSysD.xPrdScope
         )
       ) {
      xSysD.xPrsScope = PrsNode;
#ifndef XNOUSEOFSERVICE
      if (xSysD.xPrsScope->ActiveSrv != (xSrvNode)0) {
        xSysD.xSrvScope = xSysD.xPrsScope->ActiveSrv;
        xSysD.xPrdScope = xSysD.xPrsScope->ActiveSrv->ActivePrd;
      } else
#endif
        xSysD.xPrdScope = xSysD.xPrsScope->ActivePrd;
      xPrintScope((xbool)1);
    }
  }
}


/*---+---------------------------------------------------------------
     xReadSignal
-------------------------------------------------------------------*/
static void xReadSignal(
  XSIGTYPE    * IdNode,
  xSignalNode * Signal,
  xIdNode       LimId)
{
  xbool EmptyInput;

  *IdNode = (xSignalIdNode)xGetIdNodeInECSet("Signal name : ", xSignalOrTimer,
    xSymbolTableRoot, &EmptyInput, (xbool)0, LimId);
  if (*IdNode == (XSIGTYPE)0) return;
  if ( (*IdNode)->EC == xRemotePrdEC)
    *IdNode = (xSignalIdNode)(*IdNode)->Suc;  /* Go to pCALL signal */
  if (xReadSignalParameters(*IdNode, Signal, SDL_NULL)) return;
  XRELEASE_SIGNAL(*Signal);
  *IdNode = (XSIGTYPE)0;
}


/*---+---------------------------------------------------------------
     xReadNumberOfSteps
-------------------------------------------------------------------*/
static int xReadNumberOfSteps (void)
{
  xxToken Token;
  char    strVar[256];
  int     intVar;

  Token = xScanToken(strVar);
  if (Token == xxSemicolon) {
    xUngetToken(Token, strVar);
    return 1;
  }
  if (Token == xxId) {
    if ( sscanf(strVar, "%d", &intVar) ) {
      return intVar;
    }
  }
  return 1;
}


/*---+---------------------------------------------------------------
     xGetBreakpointCommand
-------------------------------------------------------------------*/
static xbool xGetBreakpointCommand (char ** Command)
{
  xxToken Token;
  char    strVar[256];

  Token = xPromptQuestionMark("Breakpoint command : ", (char *)0, strVar);
  if (Token == xxLBracket) {
    *Command = (char *)0;
    return (xbool)0;
  }
  if (Token != xxEoln && Token != xxMinus) {
    xUngetToken(Token, strVar);
    *Command = (char *)xAlloc((xptrint)(strlen(xInputPos) + 1));
    strcpy(*Command, xInputPos);
    if ((*Command)[strlen(*Command) - 1] == '\n')
      (*Command)[strlen(*Command) - 1] = '\0';
    xSkipLine();
  } else {
    *Command = (char *)0;
  }
  return (xbool)1;
}


/*---+---------------------------------------------------------------
     xRemoveBreakpointVariable
-------------------------------------------------------------------*/
static void xRemoveBreakpointVariable (xVariableBreakpointNode OldBP)
{
  xVariableBreakpointNode BP;

  if (OldBP == xSysD.VariableBreakpoints)
    xSysD.VariableBreakpoints = OldBP->Next;
  else {
    for ( BP = xSysD.VariableBreakpoints;
          BP->Next != (xVariableBreakpointNode)0;
          BP = BP->Next )
      if (BP->Next == OldBP)
        break;
    BP->Next = OldBP->Next;
  }
  if (OldBP->Command != (char *)0)
    xFree((void **)&OldBP->Command);
  WriteBuf_Del(&OldBP->CurrentValue);
  xFree((void **)&OldBP);
}


/*---+---------------------------------------------------------------
     xInsertBreakpointVariable
-------------------------------------------------------------------*/
static xbool xInsertBreakpointVariable (xVariableBreakpointNode NewBP)
{
  xVariableBreakpointNode BP;

  if ( ! xGetBreakpointCommand(&NewBP->Command) ) {
    return (xbool)0;
  }
  if (xSysD.VariableBreakpoints == (xVariableBreakpointNode)0) {
    xSysD.VariableBreakpoints = NewBP;
  }
  else {
    for ( BP = xSysD.VariableBreakpoints;
          BP->Next != (xVariableBreakpointNode)0;
          BP = BP->Next )
      ;
    BP->Next = NewBP;
  }
  return (xbool)1;
}


/*---+---------------------------------------------------------------
     SetBreakpointVariable
-------------------------------------------------------------------*/
static void SetBreakpointVariable (char * strVar)
{
  xVarIdNode              xIdNodeVariable;
  xPrdNode                LoopPrdNode;
  xbool                   xEmptyInput;
  xVariableBreakpointNode NewBP;
  xptrint                 VarPointer;
  xxToken                 Token;
  xPrsNode                tmpPrs;
  xPrsIdNode              ProcessId;

  Token = xScanToken(strVar);
  if (Token == xxLPar) {
    tmpPrs = xReadProcess("Process : ", &ProcessId, (xIdNode)0);
    if (tmpPrs != (xPrsNode)0) {
      XSYSD xPrsScope = tmpPrs;
      XSYSD xPrdScope = (xPrdNode)0;
#ifndef XNOUSEOFSERVICE
      XSYSD xSrvScope = (xSrvNode)0;
#endif
    } else {
      return;
    }
    Token = xScanToken(strVar);
    if (Token != xxRPar) xUngetToken(Token, strVar);
  } else {
    xUngetToken(Token, strVar);
  }

  if (xSysD.xPrsScope == (xPrsNode)0) {
    xPrintScope((xbool)1);
    return;
  }

  Token = xReadVariable("Variable name : ", strVar, &xEmptyInput, (xbool)0);
  if (Token != xxId) {
    xPrintString("No variable name found\n");
    return;
  }
  if ( ! xVariableInProcess(strVar, &xIdNodeVariable, &VarPointer) )
    return;
  NewBP = (xVariableBreakpointNode)xAlloc((xptrint)sizeof(*NewBP));
  NewBP->Next = (xVariableBreakpointNode)0;
  NewBP->Process = xSysD.xPrsScope;
  NewBP->Procedure = xSysD.xPrdScope;
#ifndef XNOUSEOFSERVICE
  NewBP->Service = xSysD.xSrvScope;
#endif
  if (xSysD.xPrdScope != (xPrdNode)0) {
    NewBP->PrdId = xSysD.xPrdScope->NameNode;
    NewBP->PrdInstance = 1;
    for (LoopPrdNode = xSysD.xPrdScope->DynamicFather;
         LoopPrdNode != (xPrdNode)0;
         LoopPrdNode = LoopPrdNode->DynamicFather)
      if (LoopPrdNode->NameNode == xSysD.xPrdScope->NameNode)
        NewBP->PrdInstance++;
  }
  else {
    NewBP->PrdId = (xPrdIdNode)0;
    NewBP->PrdInstance = 0;
  }
  NewBP->PId = NewBP->Process->Self;
  NewBP->VarId = xIdNodeVariable;
  NewBP->CurrentValue = WriteBuf_New(12);
  xGenericWriteSort(NewBP->CurrentValue, (void *)VarPointer,
		    xIdNodeVariable->TypeNode);
  WriteBuf_Terminate(NewBP->CurrentValue);
  if ( ! xInsertBreakpointVariable(NewBP) ) {
    WriteBuf_Del(&NewBP->CurrentValue);
    xFree((void **)&NewBP);
    return;
  }
  xPrintString("New breakpoint on variable ");
  if (xSysD.xPrdScope != (xPrdNode)0)
    xPrintPrdVariable(xIdNodeVariable, xSysD.xPrdScope);
#ifndef XNOUSEOFSERVICE
  else if (xSysD.xSrvScope != (xSrvNode)0)
    xPrintPrsVariable(xIdNodeVariable, (xptrint)xSysD.xSrvScope);
#endif
  else
    xPrintPrsVariable(xIdNodeVariable, (xptrint)xSysD.xPrsScope);
}


/*---+---------------------------------------------------------------
     xSetBreakpointVariable
-------------------------------------------------------------------*/
static void xSetBreakpointVariable (char * strVar)
{
  xPrsNode      oldPrsScope;
  xPrdNode      oldPrdScope;
#ifndef XNOUSEOFSERVICE
  xSrvNode      oldSrvScope;
#endif

  oldPrsScope = XSYSD xPrsScope;
  oldPrdScope = XSYSD xPrdScope;
#ifndef XNOUSEOFSERVICE
  oldSrvScope = XSYSD xSrvScope;
#endif

  SetBreakpointVariable(strVar);

  XSYSD xPrsScope = oldPrsScope;
  XSYSD xPrdScope = oldPrdScope;
#ifndef XNOUSEOFSERVICE
  XSYSD xSrvScope = oldSrvScope;
#endif
}


/*---+---------------------------------------------------------------
     xDeadBreakpointVariable
-------------------------------------------------------------------*/
static xbool xDeadBreakpointVariable (xVariableBreakpointNode BP)
{
  xPrdNode  PrdNode;
#ifndef XNOUSEOFSERVICE
  xSrvNode  SrvNode;
#endif

#ifndef XPRSOPT
  if ( ! xEq_SDL_PId(XPID_TO_PRS(BP->PId)->Self, BP->PId)) {
                                           /* Process instance dead? */
#else
#ifdef XNRINST
  if ( XPID_INSTNR(BP->PId) == 0 ) {
                                           /* Process instance dead? */
#else
  if ( BP->PId.LocalPId->InAvailList ) {
                                           /* Process instance dead? */
#endif
#endif
    PRINTF3("\nBreakpoint variable %s %s no longer exists\n",
            xWri_SDL_PId(&BP->PId), BP->VarId->Name);
    return (xbool)1;
  }

  if (BP->Procedure != (xPrdNode)0) {
    for (PrdNode = BP->Process->ActivePrd;
         PrdNode != (xPrdNode)0;
         PrdNode = PrdNode->DynamicFather) {
      if (PrdNode == BP->Procedure)
        break;
    }
    if (PrdNode == (xPrdNode)0) {
      PRINTF2("\nBreakpoint variable %s", xWri_SDL_PId(&BP->PId));
      PRINTF4(" %s in procedure %s:%d no longer exists\n", BP->VarId->Name,
           BP->PrdId->Name, BP->PrdInstance);
      return (xbool)1;
    }
  }
#ifndef XNOUSEOFSERVICE
  if (BP->Service != (xSrvNode)0) {
    for (SrvNode = BP->Service->ContainerPrs->SrvList;
         SrvNode != (xSrvNode)0;
         SrvNode = SrvNode->NextSrv)
      if (SrvNode == BP->Service)
        break;
    if (SrvNode == (xSrvNode)0) {
      PRINTF2("\nBreakpoint variable %s", xWri_SDL_PId(&BP->PId));
      PRINTF3(" %s in service %s no longer exists\n", BP->VarId->Name,
           BP->Service->NameNode->Name);
      return (xbool)1;
    }
  }
#endif

  return (xbool)0;
}


/*---+---------------------------------------------------------------
     xCheckOneBreakpointVariable
-------------------------------------------------------------------*/
static xbool xCheckOneBreakpointVariable (xVariableBreakpointNode BP)
{
  WriteBuf *NowVal;

  NowVal = WriteBuf_New(12);
  if (BP->Procedure != (xPrdNode)0)
    xGenericWriteSort(NowVal,
	  BP->VarId->EC == xFormalParEC && XIS_ADDRESS(BP->VarId)
          ?
          *(void **)((xptrint)BP->Procedure + BP->VarId->Offset)
          :
          (void *)((xptrint)BP->Procedure + BP->VarId->Offset)
          ,
          BP->VarId->TypeNode);
#ifndef XNOUSEOFSERVICE
  else if (BP->Service != (xSrvNode)0)
    xGenericWriteSort(NowVal,
          (void *)((xptrint)BP->Service + BP->VarId->Offset),
          BP->VarId->TypeNode);
#endif
  else
    xGenericWriteSort(NowVal,
          (void *)((xptrint)BP->Process + BP->VarId->Offset),
          BP->VarId->TypeNode);
  WriteBuf_Terminate(NowVal);
  if (strcmp(WriteBuf_Data(BP->CurrentValue), WriteBuf_Data(NowVal))) {
    xPrintString("\nBreakpoint matched by variable change.\nOld value = ");
    xPrintString(WriteBuf_Data(BP->CurrentValue));
    xPrintString("\nNew value ");
    WriteBuf_Clear(BP->CurrentValue);
    (void)WriteBuf_Add_WriteBuf(BP->CurrentValue, NowVal);
    WriteBuf_Terminate(BP->CurrentValue);
    WriteBuf_Del(&NowVal);
    if (BP->Procedure != (xPrdNode)0)
      xPrintPrdVariable(BP->VarId, BP->Procedure);
#ifndef XNOUSEOFSERVICE
    else if (BP->Service != (xSrvNode)0)
      xPrintPrsVariable(BP->VarId, (xptrint)BP->Service);
#endif
    else
      xPrintPrsVariable(BP->VarId, (xptrint)BP->Process);
    return (xbool)1;
  }
  return (xbool)0;
}


/*---+---------------------------------------------------------------
     xCheckBreakpointVariable
-------------------------------------------------------------------*/
static xbool xCheckBreakpointVariable (void)
{
  xVariableBreakpointNode BP, BPNext;
  xbool                   DoBreak;

  if (xSysD.VariableBreakpoints == (xVariableBreakpointNode)0)
    return (xbool)0;
  DoBreak = (xbool)0;
  BP = xSysD.VariableBreakpoints;
  while (BP != (xVariableBreakpointNode)0) {
    BPNext = BP->Next;
    if (xDeadBreakpointVariable(BP)) {
      xPrintString("Breakpoint removed\n");
      if (BP->Command != (char *)0) {
        PRINTF2("Breakpoint command: \"%s\"\n", BP->Command);
        sprintf(xSysD.xInputLine, "%s\n", BP->Command);
        xInputPos = xSysD.xInputLine;
      }
      xRemoveBreakpointVariable(BP);
      DoBreak = (xbool)1;
    }
    else if (xCheckOneBreakpointVariable(BP)) {
      if (BP->Command != (char *)0) {
        sprintf(xSysD.xInputLine, "%s\n", BP->Command);
        xInputPos = xSysD.xInputLine;
      }
      DoBreak = (xbool)1;
    }
    BP = BPNext;
  }
  return DoBreak;
}


/*---+---------------------------------------------------------------
     xListOneBreakpointVariable
-------------------------------------------------------------------*/
static void xListOneBreakpointVariable(
  xVariableBreakpointNode BP,
  int                    *count)
{
  PRINTF2("\n%d\n", ++*count);
  PRINTF2("Variable       : %s\n", BP->VarId->Name);
  if (BP->Procedure != (xPrdNode)0) {
    PRINTF3("Procedure      : %s:%d\n", xWriteEntity((xIdNode)BP->PrdId), 
            BP->PrdInstance);
  }
  PRINTF2("PId            : %s\n", xWri_SDL_PId(&BP->PId));
  PRINTF2("Current value  : %s\n", WriteBuf_Data(BP->CurrentValue));
  if (BP->Command != (char *)0) {
    PRINTF2("Command        : %s\n", BP->Command);
  }
}


/*---+---------------------------------------------------------------
     xSaveOneBreakpointVariable
-------------------------------------------------------------------*/
static void xSaveOneBreakpointVariable(
  FILE                   *fileVar,
  xVariableBreakpointNode BP)
{
  fprintf(fileVar, "Breakpoint-Variable %s %s\n", BP->VarId->Name,
          BP->Command ? BP->Command : "-");
}


/*---+---------------------------------------------------------------
     xUnparseSDTRef
-------------------------------------------------------------------*/
static xbool xUnparseSDTRef(
  char      * strVar,
  char      * FileName,
  long int  * GRSymbolNumber,
  int       * GRLineNumber)
{
  int  No, FNo;
  char tmpStr[256];

  *GRSymbolNumber = 0;
  *GRLineNumber = 0;
  FileName[0] = '\0';

  if (strVar == (char *)0 || strVar[0] == '\0') return (xbool)0;

  /* Only a PR line number */
  No = 0;
  if (strVar[No] >= '0' && strVar[No] <= '9') {
    while (strVar[No] >= '0' && strVar[No] <= '9')
      *GRSymbolNumber = *GRSymbolNumber*10 + (int)(strVar[No++]) - '0';
    if (strVar[No] != '-' && strVar[No] != '\0') {
      PRINTF2("Illegal SDT reference: %s\n", strVar);
      PRINTF2("Illegal character '%c' in symbol number\n", strVar[No]);
      return (xbool)0;
    }
    return (xbool)1;
  }

  /* Handle #SDTREF( */
  if (strlen(strVar) < (unsigned)8 || 
      ( (strVar[0] != '#') ||
        (strVar[1] != 'S' && strVar[1] != 's') ||
        (strVar[2] != 'D' && strVar[2] != 'd') ||
        (strVar[3] != 'T' && strVar[3] != 't') ||
        (strVar[4] != 'R' && strVar[4] != 'r') ||
        (strVar[5] != 'E' && strVar[5] != 'e') ||
        (strVar[6] != 'F' && strVar[6] != 'f') ||
        (strVar[7] != '(')
      )
     ) {
    PRINTF2("Illegal SDT reference: %s\n", strVar);
    xPrintString("SDT reference should start with #SDTREF(\n");
    return (xbool)0;
  }
  No = 8;

  /* Handle first parameter, i.e. SDL or TEXT */
  FNo = 0;
  while (strVar[No] != ',' && strVar[No] != ')' && strVar[No] != '(' &&
         strVar[No] != '\0')
    tmpStr[FNo++] = strVar[No++];
  tmpStr[FNo] = '\0';
  if ( (FNo == 3) &&
       (tmpStr[0] == 'S' || tmpStr[0] == 's') &&
       (tmpStr[1] == 'D' || tmpStr[1] == 'd') &&
       (tmpStr[2] == 'L' || tmpStr[2] == 'l')
     ) {
    /* GR reference */
    if (strVar[No] == ',') No++;

    /* Handle file name */
    FNo = 0;
    while (strVar[No] != ',' && strVar[No] != ')' && strVar[No] != '(' &&
           strVar[No] != '\0')
      FileName[FNo++] = strVar[No++];
    FileName[FNo] = '\0';
    if (strVar[No] == ')' || strVar[No] == '\0') {
      PRINTF2("Illegal SDT reference: %s\n", strVar);
      xPrintString("Ending ) or end of string found before symbol number was found\n");
      return (xbool)0;
    }

    /* Handle page name */
    if (strVar[No] == '(') {
      while (strVar[No] != ')' && strVar[No] != '\0')
        No++;
      if (strVar[No] == '\0') {
        PRINTF2("Illegal SDT reference: %s\n", strVar);
        xPrintString("End of string found before symbol number was found\n");
        return (xbool)0;
      }
      No++;
    }
    if (strVar[No] == ',') No++;

    /* Handle object id */
    if (strVar[No] == ',' || strVar[No] == ')' || strVar[No] == '(') {
      PRINTF2("Illegal SDT reference: %s\n", strVar);
      xPrintString("Symbol number not found\n");
      return (xbool)0;
    }
    while (strVar[No] >= '0' && strVar[No] <= '9')
      *GRSymbolNumber = *GRSymbolNumber*10 + (int)(strVar[No++]) - '0';
    if (strVar[No] != ',' && strVar[No] != ')' && strVar[No] != '(' &&
        strVar[No] != '\0') {
      PRINTF2("Illegal SDT reference: %s\n", strVar);
      PRINTF2("Illegal character '%c' in symbol number\n", strVar[No]);
      return (xbool)0;
    } else if (strVar[No] == '\0') {
      PRINTF2("Illegal SDT reference: %s\n", strVar);
      xPrintString("End of string found before symbol number was complete\n");
      return (xbool)0;
    }

    /* Handle koordinates */
    if (strVar[No] == '(') {
      while (strVar[No] != ')' && strVar[No] != '\0')
        No++;
      if (strVar[No] == '\0') {
        PRINTF2("Illegal SDT reference: %s\n", strVar);
        xPrintString("End of string found before line number was found\n");
        return (xbool)0;
      }
      No++;
    }
    if (strVar[No] == ',') No++;

    /* Handle line number */
    while (strVar[No] >= '0' && strVar[No] <= '9')
      *GRLineNumber = *GRLineNumber*10 + (int)(strVar[No++]) - '0';
    if (strVar[No] != ',' && strVar[No] != ')' && strVar[No] != '(' &&
        strVar[No] != '\0') {
      PRINTF2("Illegal SDT reference: %s\n", strVar);
      PRINTF2("Illegal character '%c' in line number\n", strVar[No]);
      return (xbool)0;
    } else if (strVar[No] == '\0') {
      PRINTF2("Illegal SDT reference: %s\n", strVar);
      xPrintString("End of string found before line number was complete\n");
      return (xbool)0;
    }

  } else if ( (FNo == 4) &&
       (tmpStr[0] == 'T' || tmpStr[0] == 't') &&
       (tmpStr[1] == 'E' || tmpStr[1] == 'e') &&
       (tmpStr[2] == 'X' || tmpStr[2] == 'x') &&
       (tmpStr[3] == 'T' || tmpStr[3] == 't')
     ) {
    /* PR reference */
    if (strVar[No] == ',') No++;

    /* Handle file name */
    FNo = 0;
    while (strVar[No] != ',' && strVar[No] != ')' && strVar[No] != '(' &&
           strVar[No] != '\0')
      FileName[FNo++] = strVar[No++];
    FileName[FNo] = '\0';
    if (strVar[No] == ')' || strVar[No] == '\0') {
      PRINTF2("Illegal SDT reference: %s\n", strVar);
      xPrintString("Ending ) or end of string found before line number was found\n");
      return (xbool)0;
    }
    if (strVar[No] == ',') No++;

    /* Handle line number */
    if (strVar[No] == ',' || strVar[No] == ')' || strVar[No] == '(') {
      PRINTF2("Illegal SDT reference: %s\n", strVar);
      xPrintString("Line number not found\n");
      return (xbool)0;
    }
    while (strVar[No] >= '0' && strVar[No] <= '9')
      *GRSymbolNumber = *GRSymbolNumber*10 + (int)(strVar[No++]) - '0';
    if (strVar[No] != ',' && strVar[No] != ')' && strVar[No] != '(' &&
        strVar[No] != '\0') {
      PRINTF2("Illegal SDT reference: %s\n", strVar);
      PRINTF2("Illegal character '%c' in line number\n", strVar[No]);
      return (xbool)0;
    } else if (strVar[No] == '\0') {
      PRINTF2("Illegal SDT reference: %s\n", strVar);
      xPrintString("End of string found before line number was complete\n");
      return (xbool)0;
    }

  } else if ( (FNo == 2) &&
       (tmpStr[0] == 'U' || tmpStr[0] == 'u') &&
       (tmpStr[1] == '2')
     ) {
    /* U2 reference */
    if (strVar[No] == ',') No++;

    /* Handle file name + unique id */
    FNo = 0;
    while (strVar[No] != '|' && strVar[No] != ')' && strVar[No] != '\0')
      FileName[FNo++] = strVar[No++];
    if (strVar[No] == '|')
      FileName[FNo++] = '"';
    FileName[FNo++] = ')';
    FileName[FNo] = '\0';
    if (strVar[No++] == '|') {
      if (strVar[No++] == 'p' || strVar[No++] == 'P') {
        if (strVar[No++] == 'o' || strVar[No++] == 'O') {
          if (strVar[No++] == 's' || strVar[No++] == 'S') {
            if (strVar[No++] == '(') {
              /* Handle line number */
              while (strVar[No] >= '0' && strVar[No] <= '9')
                *GRLineNumber = *GRLineNumber*10 + (int)(strVar[No++]) - '0';
            }
          }
        }
      }
    }

  } else {
      PRINTF2("Illegal SDT reference: %s\n", strVar);
      PRINTF2("Reference type: %s  not recognized\n", tmpStr);
      return (xbool)0;
  }

  return (xbool)1;
}


/*---+---------------------------------------------------------------
     xFindSDTRef
-------------------------------------------------------------------*/
static xbool xFindSDTRef (
  xIdNode   Node,
  char     *FileName,
  long int  GRSymbolNumber,
  int       GRLineNumber,
  xIdNode  *PrsIdNode, 
  long int *SymbolNumber)
{
  xIdNode     Temp;
  long int    I;
  xSymbolType S;
  long int    FNumber;
  int         FLine;
  char        FName[256];
  char       *GRref;
  xbool       found;

  if ( Node->EC == xProcessTypeEC ||
       ( Node->EC == xProcessEC && ((xPrsIdNode)Node)->Super == (xPrsIdNode)0) ) {
    found = (xbool)0;
    for (I=0; I<=((xPrsIdNode)Node)->MaxSymbolNumber; I++) {
      GRref = ((xPrsIdNode)Node)->GRrefFunc(I, &S);
      if ( xUnparseSDTRef(GRref, FName, &FNumber, &FLine) ) {
        if ( FNumber == GRSymbolNumber &&
             ( GRLineNumber == 0 || GRLineNumber == FLine ) &&
             ( FileName[0] == '\0' || strcmp(FileName, FName) == 0 ) ) {
          if (found) {
            PRINTF2(
              "\nNOTE! Found another symbol (%s) matching the SDT reference\n",
              xSymbolTypeStr[S]);
          }
          else {
            *PrsIdNode = Node;
            *SymbolNumber = I;
            found = (xbool)1;
          }
        }
      }
    }
    if (found)
      return (xbool)1;
#ifndef XNOUSEOFSERVICE
  } else if ( Node->EC == xServiceTypeEC ||
            ( Node->EC == xServiceEC && ((xSrvIdNode)Node)->Super == (xSrvIdNode)0) ) {
    found = (xbool)0;
    for (I=0; I<=((xSrvIdNode)Node)->MaxSymbolNumber; I++) {
      GRref = ((xSrvIdNode)Node)->GRrefFunc(I, &S);
      if ( xUnparseSDTRef(GRref, FName, &FNumber, &FLine) ) {
        if ( FNumber == GRSymbolNumber &&
             ( GRLineNumber == 0 || GRLineNumber == FLine ) &&
             ( FileName[0] == '\0' || strcmp(FileName, FName) == 0 ) ) {
          if (found) {
            PRINTF2(
              "\nNOTE! Found another symbol (%s) matching the SDT reference\n",
              xSymbolTypeStr[S]);
          }
          else {
            *PrsIdNode = Node;
            *SymbolNumber = I;
            found = (xbool)1;
          }
        }
      }
    }
    if (found)
      return (xbool)1;
#endif
  } else if (Node->EC == xProcedureEC) {
    found = (xbool)0;
    for (I=0; I<=((xPrdIdNode)Node)->MaxSymbolNumber; I++) {
      GRref = ((xPrdIdNode)Node)->GRrefFunc(I, &S);
      if ( xUnparseSDTRef(GRref, FName, &FNumber, &FLine) ) {
        if ( FNumber == GRSymbolNumber &&
             ( GRLineNumber == 0 || GRLineNumber == FLine ) &&
             ( FileName[0] == '\0' || strcmp(FileName, FName) == 0 ) ) {
          if (found) {
            PRINTF2(
              "\nNOTE! Found another symbol (%s) matching the SDT reference\n",
              xSymbolTypeStr[S]);
          }
          else {
            *PrsIdNode = Node;
            *SymbolNumber = I;
            found = (xbool)1;
          }
        }
      }
    }
    if (found)
      return (xbool)1;
  }
  for (Temp = Node->First; Temp != (xIdNode)0; Temp = Temp->Suc)
    if ( xFindSDTRef(Temp, FileName, GRSymbolNumber, GRLineNumber,
                     PrsIdNode, SymbolNumber) )
      return (xbool)1;
  return (xbool)0;
}


/*---+---------------------------------------------------------------
     xGetSDTRef
-------------------------------------------------------------------*/
static xbool xGetSDTRef(
  char     *strVar,
  xIdNode  *PrsIdNode,
  long int *SymbolNumber)
{
  xxToken   Token;
  int       No, Parentheses;
  xbool     EndFound;
  long int  GRSymbolNumber;
  int       GRLineNumber;
  char      FileName[256];
  char     *grFileName;
#ifdef XCONNECTPM
  char      buffer2[2 * 256];
#endif

  Token = xPromptQuestionMark("SDT reference : ", "SDT reference : ", strVar);
  if (Token == xxLBracket)
    return (xbool)0;

  xUngetToken(Token, strVar);
  No = 0;
  Parentheses = 0;
  EndFound = (xbool)0;
  while (*xInputPos != '\n' && *xInputPos != '\0' && !EndFound) {
    strVar[No++] = *xInputPos;
    if (*xInputPos == '(') Parentheses++;
    if (*xInputPos == ')') {
      Parentheses--;
      if (Parentheses == 0) EndFound = (xbool)1;
    }
    xInputPos++;
  }
  if (Parentheses) {
    xPrintString("Mismatch of parentheses in SDT reference\n");
    return (xbool)0;
  }

  if (strVar[No-1] == '-') {
    xInputPos--;
    No--;
  }
  while (strVar[No-1] == ' ' || strVar[No-1] == '\t') No--;
  strVar[No] = '\0';
  if (! xUnparseSDTRef(strVar, FileName, &GRSymbolNumber, &GRLineNumber) )
    return (xbool)0;

#ifdef XCONNECTPM
  grFileName = xGRConversion((xbool)1, FileName, buffer2);
#else
  grFileName = FileName;
#endif
  if (! xFindSDTRef(xSymbolTableRoot, grFileName, GRSymbolNumber, GRLineNumber,
                    PrsIdNode, SymbolNumber) ) {
    if (GRLineNumber > 0) {
      if (xFindSDTRef(xSymbolTableRoot, grFileName, GRSymbolNumber, 0,
                      PrsIdNode, SymbolNumber)) {
        PRINTF("\nNo symbol with given SDT reference was found (line mismatch),\n"
               "a symbol was found when linenumber was removed.\n");
        return (xbool)1;
      }
    }
    xPrintString("No symbol with given SDT reference was found\n");
#ifdef DEBUG
    PRINTF2("%s\n", strVar);
#endif
    return (xbool)0;
  }

  return (xbool)1;
}


/*---+---------------------------------------------------------------
     xSetBreakpointAt
-------------------------------------------------------------------*/
static void xSetBreakpointAt (char * strVar)
{
  xIdNode     PrsIdNode;
  long int    SymbolNumber;
  xAtBreakpointNode BP;
  xAtBreakpointNode NewBP;
  xSymbolType S;

  if ( ! xGetSDTRef(strVar, &PrsIdNode, &SymbolNumber) )
    return;

  if (PrsIdNode->EC == xProcedureEC)
    (void)((xPrdIdNode)PrsIdNode)->GRrefFunc(SymbolNumber, &S);
#ifndef XNOUSEOFSERVICE
  else if (PrsIdNode->EC == xServiceEC || PrsIdNode->EC == xServiceTypeEC)
    (void)((xSrvIdNode)PrsIdNode)->GRrefFunc(SymbolNumber, &S);
#endif
  else
    (void)((xPrsIdNode)PrsIdNode)->GRrefFunc(SymbolNumber, &S);
  if (S == xsLabel) {
    PRINTF2("Cannot set breakpoint on a %s\n", xSymbolTypeStr[S]);
    return;
  }

  NewBP = (xAtBreakpointNode)xAlloc((xptrint)sizeof(*NewBP));
  NewBP->Next = (xAtBreakpointNode)0;
  NewBP->GRReference = (char *)xAlloc((xptrint)(strlen(strVar) + 1));
  strcpy(NewBP->GRReference, strVar);
  NewBP->PrsIdNode = PrsIdNode;
  NewBP->SymbolNumber = SymbolNumber;
  if ( ! xGetBreakpointCommand(&NewBP->Command) ) {
    xFree((void **)&NewBP->GRReference);
    xFree((void **)&NewBP);
    return;
  }
  if (xSysD.AtBreakpoints == (xAtBreakpointNode)0) {
    xSysD.AtBreakpoints = NewBP;
  }
  else {
    for ( BP = xSysD.AtBreakpoints;
          BP->Next != (xAtBreakpointNode)0;
          BP = BP->Next )
      ;
    BP->Next = NewBP;
  }
  PRINTF2("\nNew breakpoint at : %s\n", strVar);
  PRINTF4("Object            : %s %s\nSymbol type       : %s\n",
     xEntityString[NewBP->PrsIdNode->EC],
     xWriteEntity(NewBP->PrsIdNode),
     xSymbolTypeStr[S]);
#ifdef XCONNECTPM
  xUpdateBreakpoints((xbool)1);
#endif
}


/*---+---------------------------------------------------------------
     xRemoveBreakpointAt
-------------------------------------------------------------------*/
static void xRemoveBreakpointAt(char * strVar)
{
  int               No;
  xIdNode           PrsIdNode;
  long int          SymbolNumber;
  xAtBreakpointNode BP;
  xAtBreakpointNode BPNext;
  xAtBreakpointNode BPLoop;

  if (xSysD.AtBreakpoints == (xAtBreakpointNode)0) {
    xPrintString("No graphical breakpoint defined\n");
    return;
  }

  if ( ! xGetSDTRef(strVar, &PrsIdNode, &SymbolNumber) )
    return;

  No = 0;
  BP = xSysD.AtBreakpoints;
  while (BP) {
    BPNext = BP->Next;
    if (BP->PrsIdNode == PrsIdNode && BP->SymbolNumber == SymbolNumber) {
      if (BP == xSysD.AtBreakpoints)
        xSysD.AtBreakpoints = BPNext;
      else {
        for (BPLoop = xSysD.AtBreakpoints;
             BPLoop->Next;
             BPLoop = BPLoop->Next) {
          if (BPLoop->Next == BP)
            break;
        }
        BPLoop->Next = BP->Next;
      }
      if (BP->Command)
        xFree((void **)&BP->Command);
      xFree((void **)&BP->GRReference);
      xFree((void **)&BP);
      No++;
    }
    BP = BPNext;
  }
  if (No == 1) {
    PRINTF2("\n%d breakpoint removed\n", No);
  }
  else {
    PRINTF2("\n%d breakpoints removed\n", No);
  }
#ifdef XCONNECTPM
  if (No > 0)
    xUpdateBreakpoints((xbool)1);
#endif
}


/*---+---------------------------------------------------------------
     xCheckOneBreakpointAt
-------------------------------------------------------------------*/
static xbool xCheckOneBreakpointAt(
  xPrsNode           Process,
  long int           SymbolNumber,
  xAtBreakpointNode  BP)
{
  xPrsIdNode    PrsId;
  xPrdIdNode    PrdId;
  xPrdNode      Prd;
#ifndef XNOUSEOFSERVICE
  xSrvIdNode    SrvId;
#endif

  if (BP->SymbolNumber != SymbolNumber)
    return (xbool)0;

#ifndef XNOUSEOFSERVICE
  if (Process->ActiveSrv == (xSrvNode)0) {
#endif
    Prd = Process->ActivePrd;
    while (Prd != (xPrdNode)0 && Prd->NameNode->EC == xCompoundStmtEC)
      Prd = Prd->DynamicFather;

    if (Prd == (xPrdNode)0) {
      PrsId = Process->NameNode;
      while (PrsId->PAD_Function != Process->RestartPAD)
        PrsId = PrsId->Super;
      if (BP->PrsIdNode == (xIdNode)PrsId)
        return (xbool)1;
    }
    else {
      PrdId = Prd->NameNode;
      while (PrdId->Assoc_Function != Prd->RestartPRD)
        PrdId = PrdId->Super;
      if (BP->PrsIdNode == (xIdNode)PrdId)
        return (xbool)1;
    }
#ifndef XNOUSEOFSERVICE
  } else {
    Prd = Process->ActiveSrv->ActivePrd;
    while (Prd != (xPrdNode)0 && Prd->NameNode->EC == xCompoundStmtEC)
      Prd = Prd->DynamicFather;

    if (Prd == (xPrdNode)0) {
      SrvId = Process->ActiveSrv->NameNode;
      while (SrvId->PAD_Function != Process->ActiveSrv->RestartPAD)
        SrvId = SrvId->Super;
      if (BP->PrsIdNode == (xIdNode)SrvId)
        return (xbool)1;
    }
    else {
      PrdId = Prd->NameNode;
      while (PrdId->Assoc_Function != Prd->RestartPRD)
        PrdId = PrdId->Super;
      if (BP->PrsIdNode == (xIdNode)PrdId)
        return (xbool)1;
    }
  }
#endif
  return (xbool)0;
}


/*---+---------------------------------------------------------------
     xCheckBreakpointAt
-------------------------------------------------------------------*/
static xbool xCheckBreakpointAt(
  xPrsNode Process,
  long int SymbolNumber)
{
  xAtBreakpointNode BP;

  if (xSysD.AtBreakpoints == (xAtBreakpointNode)0)
    return (xbool)0;
  for (BP = xSysD.AtBreakpoints;
       BP != (xAtBreakpointNode)0;
       BP = BP->Next)
    if (xCheckOneBreakpointAt(Process, SymbolNumber, BP)) {
      PRINTF2("\nBreakpoint matched at %s\n", BP->GRReference);
      if (BP->Command != (char *)0) {
        sprintf(xSysD.xInputLine, "%s\n", BP->Command);
        xInputPos = xSysD.xInputLine;
      }
      return (xbool)1;
    }
  return (xbool)0;
}


/*---+---------------------------------------------------------------
     xListOneBreakpointAt
-------------------------------------------------------------------*/
static void xListOneBreakpointAt(
  xAtBreakpointNode BP,
  int              *count)
{
  xSymbolType       S;

  PRINTF2("\n%d\n", ++*count);
  PRINTF2("SDT reference   : %s\n", BP->GRReference);
  if (BP->PrsIdNode->EC == xProcedureEC)
    (void)((xPrdIdNode)BP->PrsIdNode)->GRrefFunc(BP->SymbolNumber, &S);
#ifndef XNOUSEOFSERVICE
  else if (BP->PrsIdNode->EC == xServiceEC ||
           BP->PrsIdNode->EC == xServiceTypeEC)
    (void)((xSrvIdNode)BP->PrsIdNode)->GRrefFunc(BP->SymbolNumber, &S);
#endif
  else
    (void)((xPrsIdNode)BP->PrsIdNode)->GRrefFunc(BP->SymbolNumber, &S);
  PRINTF4("Object          : %s %s\nSymbol type     : %s\n",
     xEntityString[BP->PrsIdNode->EC],
     xWriteEntity(BP->PrsIdNode),
     xSymbolTypeStr[S]);
  if (BP->Command != (char *)0) {
    PRINTF2("Command         : %s\n", BP->Command);
  }
}


/*---+---------------------------------------------------------------
     xShowBreakpointAt
-------------------------------------------------------------------*/
static void xShowBreakpointAt (void)
{
  xAtBreakpointNode BPA;
  int               count;
  int               intVar;

  if (xSysD.AtBreakpoints == (xAtBreakpointNode)0) {
    xPrintString("No graphical breakpoint defined\n");
    return;
  }
  count = 0;
  for ( BPA = xSysD.AtBreakpoints;
        BPA != (xAtBreakpointNode)0;
        BPA = BPA->Next )
    count++;
  if ( ! xReadEntryNumber("Breakpoint entry : ", &intVar, count))
    return;
  count = 0;
  for ( BPA = xSysD.AtBreakpoints;
        BPA != (xAtBreakpointNode)0;
        BPA = BPA->Next )
    if (++count == intVar)
      break;
  count--;
  xListOneBreakpointAt(BPA, &count);
#ifdef XGRTRACE
  xGRTraceSymbol(BPA->GRReference);
#endif
}


/*---+---------------------------------------------------------------
     xSaveOneBreakpointAt
-------------------------------------------------------------------*/
static void xSaveOneBreakpointAt(
  FILE             *fileVar,
  xAtBreakpointNode BP)
{
  fprintf(fileVar, "Breakpoint-At %s %s\n", BP->GRReference,
          BP->Command ? BP->Command : "-");
}


/*---+---------------------------------------------------------------
     xSetBreakpoint
-------------------------------------------------------------------*/
static void xSetBreakpoint (void)
{
  xBreakpointNode BPT;
  xBreakpointNode NewBPT;
  xBreakpointRec  BPTTemp;
  xbool           xEmptyInput;
  xIdNode         xIdNodeProcess;

  BPTTemp.Next = (xBreakpointNode)0;

  /* Process name */
  BPTTemp.ProcId = (xPrsIdNode)xGetIdNodeInECSet("Process name : ",
      1L<<((long)xProcessEC), xSymbolTableRoot,
      &xEmptyInput, (xbool)1, (xIdNode)0);
  if (! xEmptyInput && BPTTemp.ProcId == (xPrsIdNode)0) return;
  if (BPTTemp.ProcId == (xPrsIdNode)0)
    xIdNodeProcess = xSymbolTableRoot;
  else
    xIdNodeProcess = (xIdNode)BPTTemp.ProcId;

  /* Instance number */
  if ( ! xReadInstanceNumber("Instance number : ", &BPTTemp.InstNr,
                             &xEmptyInput))
    return;
  if (xEmptyInput) BPTTemp.InstNr = 0;

#ifndef XNOUSEOFSERVICE
  /* Serice name */
  BPTTemp.SrvId = (xSrvIdNode)xGetIdNodeInECSet("Service name : ",
      1L<<((long)xServiceEC), xIdNodeProcess, &xEmptyInput, (xbool)1, (xIdNode)0);
  if (! xEmptyInput && BPTTemp.SrvId == (xSrvIdNode)0)
    return;
  if (BPTTemp.SrvId != (xSrvIdNode)0)
    xIdNodeProcess = (xIdNode)BPTTemp.SrvId;
#endif

  /* State name */
  BPTTemp.StateId = (xStateIdNode)xGetIdNodeInECSet("State name : ",
      1L<<((long)xStateEC), xIdNodeProcess, &xEmptyInput, (xbool)1, (xIdNode)0);
  if (! xEmptyInput && BPTTemp.StateId == (xStateIdNode)0)
    return;

  /* Input name */
  BPTTemp.SignalId = (xSignalIdNode)xGetIdNodeInECSet("Input name : ",
      xSignalOrTimer, xSymbolTableRoot, &xEmptyInput, (xbool)1, (xIdNode)0);
  if (! xEmptyInput && BPTTemp.SignalId == (xSignalIdNode)0)
    return;

  /* Sender process name */
  BPTTemp.SenderId = (xPrsIdNode)xGetIdNodeInECSet("Sender process name : ",
      1L<<((long)xProcessEC), xSymbolTableRoot,
      &xEmptyInput, (xbool)1, (xIdNode)0);
  if (! xEmptyInput && BPTTemp.SenderId == (xPrsIdNode)0) return;

  /* Sender process instance number */
  if ( ! xReadInstanceNumber("Sender instance number : ",
                             &BPTTemp.SenderInstNr, &xEmptyInput))
    return;
  if (xEmptyInput) BPTTemp.SenderInstNr = 0;

  /* Counter */
  if ( ! xReadInstanceNumber("Stop at N:th time : ",
            &BPTTemp.SetToCounter, &xEmptyInput))
    return;
  if (xEmptyInput) BPTTemp.SetToCounter = 0;

  /* Breakpoint commands */
  BPTTemp.Counter = BPTTemp.SetToCounter;
  if ( ! xGetBreakpointCommand(&BPTTemp.Command) )
    return;
  NewBPT = (xBreakpointNode)xAlloc((xptrint)sizeof(*NewBPT));
  *NewBPT = BPTTemp;
  if (xSysD.TransitionBreakpoints == (xBreakpointNode)0) {
    xSysD.TransitionBreakpoints = NewBPT;
  }
  else {
    for ( BPT = xSysD.TransitionBreakpoints;
          BPT->Next != (xBreakpointNode)0;
          BPT = BPT->Next )
      ;
    BPT->Next = NewBPT;
  }
  xPrintString("New breakpoint defined\n");
}


/*---+---------------------------------------------------------------
     xCheckOneBreakpoint
-------------------------------------------------------------------*/
static xbool xCheckOneBreakpoint(
  xPrsNode        Process,
  SDL_PId         Sender,
  xBreakpointNode BPT)
{
  xStateIdNode StateId;

  if (BPT->ProcId != (xPrsIdNode)0 && Process->NameNode != BPT->ProcId)
    return (xbool)0;
  if (BPT->InstNr != 0 && XPRS_INSTNR(Process) != BPT->InstNr)
    return (xbool)0;
#ifndef XNOUSEOFSERVICE
  if (BPT->SrvId != (xSrvIdNode)0 &&
      ( Process->ActiveSrv == (xSrvNode)0 ||
        Process->ActiveSrv->NameNode != BPT->SrvId )
     )
    return (xbool)0;
#endif

#ifndef XNOUSEOFSERVICE
  if (Process->ActiveSrv == (xSrvNode)0) {
#endif
    if (Process->ActivePrd != (xPrdNode)0)
      StateId = xGetState(Process, Process->ActivePrd,
            Process->ActivePrd->NameNode->StateList, Process->ActivePrd->State);
    else
      StateId = xGetState(Process, (xPrdNode)0,
            Process->NameNode->StateList, Process->State);
#ifndef XNOUSEOFSERVICE
  } else {
    if (Process->ActiveSrv->ActivePrd != (xPrdNode)0)
      StateId = xGetState(Process, Process->ActiveSrv->ActivePrd,
            Process->ActiveSrv->ActivePrd->NameNode->StateList,
            Process->ActiveSrv->ActivePrd->State);
    else
      StateId = xGetState(Process, (xPrdNode)0,
            Process->ActiveSrv->NameNode->StateList, Process->ActiveSrv->State);
  }
#endif

  if ( BPT->StateId != (xStateIdNode)0 && StateId != BPT->StateId)
    return (xbool)0;
  if (BPT->SignalId != (xSignalIdNode)0 &&
      XSIGNAL_IDNODE(XPRS_NEXT_REC_SIG(Process)) != BPT->SignalId)
    return (xbool)0;
  if (! xEq_SDL_PId_NULL(Sender)) {
    if (BPT->SenderId != (xPrsIdNode)0 &&
        XPID_TO_PRS(Sender)->NameNode != BPT->SenderId)
      return (xbool)0;
    if (BPT->SenderInstNr != 0 && XPID_INSTNR(Sender) != BPT->SenderInstNr)
      return (xbool)0;
  }
  BPT->Counter--;
  if (BPT->Counter > 0)
    return (xbool)0;
  BPT->Counter = BPT->SetToCounter;
  return (xbool)1;
}


/*---+---------------------------------------------------------------
     xCheckBreakpoint
-------------------------------------------------------------------*/
static xbool xCheckBreakpoint (xPrsNode Process)
{
  xBreakpointNode BPT;
  SDL_PId         Sender;

  if (xSysD.TransitionBreakpoints == (xBreakpointNode)0)
    return (xbool)0;
  Sender = XSIGNAL_SENDER(XPRS_NEXT_REC_SIG(Process));
  if ( ! xEq_SDL_PId_NULL(Sender) )
    if (! XIS_PID_IN_SYSTEM(Sender) )
      Sender = xEnv;
  for (BPT = xSysD.TransitionBreakpoints;
       BPT != (xBreakpointNode)0;
       BPT = BPT->Next)
    if (xCheckOneBreakpoint(Process, Sender, BPT)) {
      xPrintString("\nBreakpoint matched by transition\n");
      if (BPT->Command != (char *)0) {
        sprintf(xSysD.xInputLine, "%s\n", BPT->Command);
        xInputPos = xSysD.xInputLine;
      }
      return (xbool)1;
    }
  return (xbool)0;
}


/*---+---------------------------------------------------------------
     xListOneBreakpoint
-------------------------------------------------------------------*/
static void xListOneBreakpoint(
  xBreakpointNode BPT,
  int            *count)
{
  PRINTF2("\n%d\n", ++*count);
  if (BPT->ProcId == (xPrsIdNode)0)
    xPrintString("Process name    : any\n");
  else
    PRINTF2("Process name    : %s\n", xWriteEntity((xIdNode)BPT->ProcId));
  if (BPT->InstNr == 0)
    xPrintString("Instance        : any\n");
  else
    PRINTF2("Instance        : %d\n", BPT->InstNr);
#ifndef XNOUSEOFSERVICE
  if (BPT->SrvId == (xSrvIdNode)0)
    xPrintString("Service name    : any\n");
  else
    PRINTF2("Service name    : %s\n", xWriteEntity((xIdNode)BPT->SrvId));
#endif
  if (BPT->StateId == (xStateIdNode)0)
    xPrintString("State           : any\n");
  else
    PRINTF2("State           : %s\n", xWriteEntity((xIdNode)BPT->StateId));
  if (BPT->SignalId == (xSignalIdNode)0)
    xPrintString("Input           : any\n");
  else
    PRINTF2("Input           : %s\n", xWriteEntity((xIdNode)BPT->SignalId));
  if (BPT->SenderId == (xPrsIdNode)0)
    xPrintString("Sender name     : any\n");
  else
    PRINTF2("Sender name     : %s\n", xWriteEntity((xIdNode)BPT->SenderId));
  if (BPT->SenderInstNr == 0)
    xPrintString("Sender instance : any\n");
  else
    PRINTF2("Sender instance : %d\n", BPT->SenderInstNr);
  if (BPT->SetToCounter > 1) {
    PRINTF2("Stop after      : %d", BPT->SetToCounter);
    PRINTF2(" (remains %d)\n", BPT->Counter);
  }
  else
    xPrintString("Stop each time\n");
  if (BPT->Command != (char *)0)
    PRINTF2("Command         : %s\n", BPT->Command);
}


/*---+---------------------------------------------------------------
     xSaveOneBreakpoint
-------------------------------------------------------------------*/
static void xSaveOneBreakpoint(
  FILE           *fileVar,
  xBreakpointNode BPT)
{
  fprintf(fileVar, "Breakpoint-Transition %s",
          BPT->ProcId ? xWriteEntity((xIdNode)BPT->ProcId) : "-");
  if (BPT->InstNr == 0)
    fprintf(fileVar, " -");
  else
    fprintf(fileVar, " %d", BPT->InstNr);
#ifndef XNOUSEOFSERVICE
  fprintf(fileVar, " %s", BPT->SrvId ? xWriteEntity((xIdNode)BPT->SrvId) : "-");
#endif
  fprintf(fileVar, " %s",
          BPT->StateId ? xWriteEntity((xIdNode)BPT->StateId) : "-");
  fprintf(fileVar, " %s",
          BPT->SignalId ? xWriteEntity((xIdNode)BPT->SignalId) : "-");
  fprintf(fileVar, " %s",
          BPT->SenderId ? xWriteEntity((xIdNode)BPT->SenderId) : "-");
  if (BPT->SenderInstNr == 0)
    fprintf(fileVar, " -");
  else
    fprintf(fileVar, " %d", BPT->SenderInstNr);
  if (BPT->SetToCounter == 0)
    fprintf(fileVar, " -");
  else
    fprintf(fileVar, " %d", BPT->SetToCounter);
  fprintf(fileVar, " %s\n", BPT->Command ? BPT->Command : "-");
}


/*---+---------------------------------------------------------------
     xSetBreakpointOutput
-------------------------------------------------------------------*/
static void xSetBreakpointOutput (void)
{
  xBreakpointOutputNode BPO;
  xBreakpointOutputNode NewBPO;
  xBreakpointOutputRec  BPOTemp;
  xbool                 xEmptyInput;

  BPOTemp.Next = (xBreakpointOutputNode)0;

  /* Signal name */
  BPOTemp.SignalId = (xSignalIdNode)xGetIdNodeInECSet("Signal name  : ",
      xSignalOrTimer, xSymbolTableRoot, &xEmptyInput, (xbool)1, (xIdNode)0);
  if (! xEmptyInput && BPOTemp.SignalId == (xSignalIdNode)0)
    return;

  /* Receiver process name */
  BPOTemp.ReceiverId = (xPrsIdNode)xGetIdNodeInECSet(
      "Receiver process name : ", 1L<<((long)xProcessEC), 
      xSymbolTableRoot, &xEmptyInput, (xbool)1, (xIdNode)0);
  if (! xEmptyInput && BPOTemp.ReceiverId == (xPrsIdNode)0)  return;

  /* Receiver instance number */
  if ( ! xReadInstanceNumber("Receiver instance number : ",
                          &BPOTemp.ReceiverInstNr, &xEmptyInput))
    return;
  if (xEmptyInput) BPOTemp.ReceiverInstNr = 0;

  /* Sender process name */
  BPOTemp.SenderId = (xPrsIdNode)xGetIdNodeInECSet(
      "Sender process name : ", 1L<<((long)xProcessEC), 
      xSymbolTableRoot, &xEmptyInput, (xbool)1, (xIdNode)0);
  if (! xEmptyInput && BPOTemp.SenderId == (xPrsIdNode)0) return;

  /* Sender instance number */
  if ( ! xReadInstanceNumber("Sender instance number : ",
                          &BPOTemp.SenderInstNr, &xEmptyInput))
    return;
  if (xEmptyInput) BPOTemp.SenderInstNr = 0;

  /* Counter */
  if ( ! xReadInstanceNumber("Stop at N:th time : ",
            &BPOTemp.SetToCounter, &xEmptyInput))
    return;
  if (xEmptyInput) BPOTemp.SetToCounter = 0;
  BPOTemp.Counter = BPOTemp.SetToCounter;

  /* Breakpoint commands */
  if ( ! xGetBreakpointCommand(&BPOTemp.Command) )
    return;

  NewBPO = (xBreakpointOutputNode)xAlloc((xptrint)sizeof(*NewBPO));
  *NewBPO = BPOTemp;
  if (xSysD.OutputBreakpoints == (xBreakpointOutputNode)0) {
    xSysD.OutputBreakpoints = NewBPO;
  }
  else {
    for ( BPO = xSysD.OutputBreakpoints;
          BPO->Next != (xBreakpointOutputNode)0;
          BPO = BPO->Next )
      ;
    BPO->Next = NewBPO;
  }
  xPrintString("New breakpoint defined\n");
}


/*---+---------------------------------------------------------------
     xCheckOneBreakpointOutput
-------------------------------------------------------------------*/
static xbool xCheckOneBreakpointOutput(
  SDL_PId               Receiver,
  SDL_PId               Sender,
  xSignalNode           Signal,
  xBreakpointOutputNode BPO)
{
  if (BPO->SignalId != (xSignalIdNode)0 &&
      XSIGNAL_IDNODE(Signal) != BPO->SignalId)
    return (xbool)0;
  if (BPO->ReceiverId != (xPrsIdNode)0 &&
      XPID_TO_PRS(Receiver)->NameNode != BPO->ReceiverId)
    return (xbool)0;
  if (BPO->ReceiverInstNr != 0 &&
      XPID_INSTNR(Receiver) != BPO->ReceiverInstNr)
    return (xbool)0;
  if (! xEq_SDL_PId_NULL(XSIGNAL_SENDER(Signal))) {
    if (BPO->SenderId != (xPrsIdNode)0 &&
        XPID_TO_PRS(Sender)->NameNode != BPO->SenderId)
      return (xbool)0;
    if (BPO->SenderInstNr != 0 && XPID_INSTNR(Sender) != BPO->SenderInstNr)
      return (xbool)0;
  }
  BPO->Counter--;
  if (BPO->Counter > 0)
    return (xbool)0;
  BPO->Counter = BPO->SetToCounter;
  return (xbool)1;
}


/*---+---------------------------------------------------------------
     xCheckBreakpointOutput
-------------------------------------------------------------------*/
xbool xCheckBreakpointOutput (xSignalNode Signal)
{
  xBreakpointOutputNode BPO;
  SDL_PId               Receiver;
  SDL_PId               Sender;

  if (xSysD.OutputBreakpoints == (xBreakpointOutputNode)0)
    return (xbool)0;
  Receiver = XSIGNAL_RECEIVER(Signal);
  if (! XIS_PID_IN_SYSTEM(Receiver) )
    Receiver = xEnv;
  Sender = XSIGNAL_SENDER(Signal);
  if ( ! xEq_SDL_PId_NULL(Sender) )
    if (! XIS_PID_IN_SYSTEM(Sender) )
      Sender = xEnv;
  for (BPO = xSysD.OutputBreakpoints;
       BPO != (xBreakpointOutputNode)0;
       BPO = BPO->Next)
    if (xCheckOneBreakpointOutput(Receiver, Sender, Signal, BPO)) {
      PRINTF2("\nBreakpoint matched by output of %s\n",
              xWriteEntity((xIdNode)XSIGNAL_IDNODE(Signal)));
      if (BPO->Command != (char *)0) {
        sprintf(xSysD.xInputLine, "%s\n", BPO->Command);
        xInputPos = xSysD.xInputLine;
      }
      return (xbool)1;
    }
  return (xbool)0;
}


/*---+---------------------------------------------------------------
     xListOneBreakpointOutput
-------------------------------------------------------------------*/
static void xListOneBreakpointOutput(
  xBreakpointOutputNode BPO,
  int                  *count)
{
  PRINTF2("\n%d\n", ++*count);
  if (BPO->SignalId == (xSignalIdNode)0)
    xPrintString("Signal name       : any\n");
  else
    PRINTF2("Signal name       : %s\n", 
            xWriteEntity((xIdNode)BPO->SignalId));
  if (BPO->ReceiverId == (xPrsIdNode)0)
    xPrintString("Receiver name     : any\n");
  else
    PRINTF2("Receiver name     : %s\n", 
            xWriteEntity((xIdNode)BPO->ReceiverId));
  if (BPO->ReceiverInstNr == 0)
    xPrintString("Receiver instance : any\n");
  else
    PRINTF2("Receiver instance : %d\n", BPO->ReceiverInstNr);
  if (BPO->SenderId == (xPrsIdNode)0)
    xPrintString("Sender name       : any\n");
  else
    PRINTF2("Sender name       : %s\n", 
            xWriteEntity((xIdNode)BPO->SenderId));
  if (BPO->SenderInstNr == 0)
    xPrintString("Sender instance   : any\n");
  else
    PRINTF2("Sender instance   : %d\n", BPO->SenderInstNr);
  if (BPO->SetToCounter > 1) {
    PRINTF2("Stop after        : %d", BPO->SetToCounter);
    PRINTF2(" (remains %d)\n", BPO->Counter);
  }
  else
    xPrintString("Stop each time\n");
  if (BPO->Command != (char *)0)
    PRINTF2("Command           : %s\n", BPO->Command);
}


/*---+---------------------------------------------------------------
     xSaveOneBreakpointOutput
-------------------------------------------------------------------*/
static void xSaveOneBreakpointOutput(
  FILE                 *fileVar,
  xBreakpointOutputNode BPO)
{
  fprintf(fileVar, "Breakpoint-Output %s",
          BPO->SignalId ? xWriteEntity((xIdNode)BPO->SignalId) : "-");
  fprintf(fileVar, " %s",
          BPO->ReceiverId ? xWriteEntity((xIdNode)BPO->ReceiverId) : "-");
  if (BPO->ReceiverInstNr == 0)
    fprintf(fileVar, " -");
  else
    fprintf(fileVar, " %d", BPO->ReceiverInstNr);
  fprintf(fileVar, " %s",
          BPO->SenderId ? xWriteEntity((xIdNode)BPO->SenderId) : "-");
  if (BPO->SenderInstNr == 0)
    fprintf(fileVar, " -");
  else
    fprintf(fileVar, " %d", BPO->SenderInstNr);
  if (BPO->SetToCounter == 0)
    fprintf(fileVar, " -");
  else
    fprintf(fileVar, " %d", BPO->SetToCounter);
  fprintf(fileVar, " %s\n", BPO->Command ? BPO->Command : "-");
}


/*---+---------------------------------------------------------------
     xRemoveBreakpoint
-------------------------------------------------------------------*/
static void xRemoveBreakpoint (void)
{
  xVariableBreakpointNode BPV, BPVtmp;
  xAtBreakpointNode       BPA, BPAtmp;
  xBreakpointNode         BPT, BPTtmp;
  xBreakpointOutputNode   BPO, BPOtmp;
  int                     intVar;
  int                     count;
  int                     VariableBreaks, AtBreaks, TransitionBreaks;

  if (xSysD.TransitionBreakpoints == (xBreakpointNode)0 &&
      xSysD.VariableBreakpoints == (xVariableBreakpointNode)0 &&
      xSysD.AtBreakpoints == (xAtBreakpointNode)0 &&
      xSysD.OutputBreakpoints == (xBreakpointOutputNode)0) {
    xPrintString("No breakpoint defined\n");
    return;
  }
  count = 0;
  for ( BPA = xSysD.AtBreakpoints;
        BPA != (xAtBreakpointNode)0;
        BPA = BPA->Next )
    count++;
  AtBreaks = count;
  for ( BPV = xSysD.VariableBreakpoints;
        BPV != (xVariableBreakpointNode)0;
        BPV = BPV->Next )
    count++;
  VariableBreaks = count;
  for ( BPT = xSysD.TransitionBreakpoints;
        BPT != (xBreakpointNode)0;
        BPT = BPT->Next )
    count++;
  TransitionBreaks = count;
  for ( BPO = xSysD.OutputBreakpoints;
        BPO != (xBreakpointOutputNode)0;
        BPO = BPO->Next )
    count++;
  if ( ! xReadEntryNumber("Breakpoint entry : ", &intVar, count))
    return;
  if (intVar <= AtBreaks) {
    if (intVar == 1) {
      BPAtmp = xSysD.AtBreakpoints;
      xSysD.AtBreakpoints = xSysD.AtBreakpoints->Next;
    }
    else {
      count = 0;
      for ( BPA = xSysD.AtBreakpoints;
            BPA != (xAtBreakpointNode)0;
            BPA = BPA->Next )
        if (++count == intVar - 1)
          break;
      BPAtmp = BPA->Next;
      BPA->Next = BPA->Next->Next;
    }
    if (BPAtmp->Command != (char *)0)
      xFree((void **)&BPAtmp->Command);
    xFree((void **)&BPAtmp->GRReference);
    xFree((void **)&BPAtmp);
#ifdef XCONNECTPM
    xUpdateBreakpoints((xbool)1);
#endif
  }
  else if (intVar <= VariableBreaks) {
    intVar = intVar - AtBreaks;
    if (intVar == 1) {
      BPVtmp = xSysD.VariableBreakpoints;
      xSysD.VariableBreakpoints = xSysD.VariableBreakpoints->Next;
    }
    else {
      count = 0;
      for ( BPV = xSysD.VariableBreakpoints;
            BPV != (xVariableBreakpointNode)0;
            BPV = BPV->Next )
        if (++count == intVar - 1)
          break;
      BPVtmp = BPV->Next;
      BPV->Next = BPV->Next->Next;
    }
    if (BPVtmp->Command != (char *)0)
      xFree((void **)&BPVtmp->Command);
    WriteBuf_Del(&BPVtmp->CurrentValue);
    xFree((void **)&BPVtmp);
  }
  else if (intVar <= TransitionBreaks) {
    intVar = intVar - VariableBreaks;
    if (intVar == 1) {
      BPTtmp = xSysD.TransitionBreakpoints;
      xSysD.TransitionBreakpoints = xSysD.TransitionBreakpoints->Next;
    }
    else {
      count = 0;
      for ( BPT = xSysD.TransitionBreakpoints;
            BPT != (xBreakpointNode)0;
            BPT = BPT->Next )
        if (++count == intVar - 1)
          if (BPT->Next != (xBreakpointNode)0)
            break;
      BPTtmp = BPT->Next;
      BPT->Next = BPT->Next->Next;
    }
    if (BPTtmp->Command != (char *)0)
      xFree((void **)&BPTtmp->Command);
    xFree((void **)&BPTtmp);
  }
  else {
    intVar = intVar - TransitionBreaks;
    if (intVar == 1) {
      BPOtmp = xSysD.OutputBreakpoints;
      xSysD.OutputBreakpoints = xSysD.OutputBreakpoints->Next;
    }
    else {
      count = 0;
      for ( BPO = xSysD.OutputBreakpoints;
            BPO != (xBreakpointOutputNode)0;
            BPO = BPO->Next )
        if (++count == intVar - 1)
          if (BPO->Next != (xBreakpointOutputNode)0)
            break;
      BPOtmp = BPO->Next;
      BPO->Next = BPO->Next->Next;
    }
    if (BPOtmp->Command != (char *)0)
      xFree((void **)&BPOtmp->Command);
    xFree((void **)&BPOtmp);
  }
  xPrintString("Breakpoint was removed\n");
}


/*---+---------------------------------------------------------------
     xRemoveAllBreakpoints
-------------------------------------------------------------------*/
static void xRemoveAllBreakpoints (void)
{
  xVariableBreakpointNode BPV;
  xAtBreakpointNode       BPA;
  xBreakpointNode         BPT;
  xBreakpointOutputNode   BPO;
  xbool                   grBp;

  if (xSysD.TransitionBreakpoints == (xBreakpointNode)0 &&
      xSysD.VariableBreakpoints == (xVariableBreakpointNode)0 &&
      xSysD.AtBreakpoints == (xAtBreakpointNode)0 &&
      xSysD.OutputBreakpoints == (xBreakpointOutputNode)0) {
    xPrintString("No breakpoints defined\n");
    return;
  }

  if (xSysD.AtBreakpoints)
    grBp = (xbool)1;
  else
    grBp = (xbool)0;
  BPA = xSysD.AtBreakpoints;
  while (BPA) {
    xSysD.AtBreakpoints = BPA->Next;
    if (BPA->Command != (char *)0)
      xFree((void **)&BPA->Command);
    xFree((void **)&BPA->GRReference);
    xFree((void **)&BPA);
    BPA = xSysD.AtBreakpoints;
  }
#ifdef XCONNECTPM
  if (grBp)
    xUpdateBreakpoints((xbool)1);
#endif
  BPV = xSysD.VariableBreakpoints;
  while (BPV) {
    xSysD.VariableBreakpoints = BPV->Next;
    if (BPV->Command != (char *)0)
      xFree((void **)&BPV->Command);
    WriteBuf_Del(&BPV->CurrentValue);
    xFree((void **)&BPV);
    BPV = xSysD.VariableBreakpoints;
  }
  BPT = xSysD.TransitionBreakpoints;
  while (BPT) {
    xSysD.TransitionBreakpoints = BPT->Next;
    if (BPT->Command != (char *)0)
      xFree((void **)&BPT->Command);
    xFree((void **)&BPT);
    BPT = xSysD.TransitionBreakpoints;
  }
  BPO = xSysD.OutputBreakpoints;
  while (BPO) {
    xSysD.OutputBreakpoints = BPO->Next;
    if (BPO->Command != (char *)0)
      xFree((void **)&BPO->Command);
    xFree((void **)&BPO);
    BPO = xSysD.OutputBreakpoints;
  }
  xPrintString("All breakpoints removed\n");
}


/*---+---------------------------------------------------------------
     xListBreakpoints
-------------------------------------------------------------------*/
static void xListBreakpoints (void)
{
  xVariableBreakpointNode BPV;
  xAtBreakpointNode       BPA;
  xBreakpointNode         BPT;
  xBreakpointOutputNode   BPO;
  int                     count;

  if (xSysD.TransitionBreakpoints == (xBreakpointNode)0 &&
      xSysD.VariableBreakpoints == (xVariableBreakpointNode)0 &&
      xSysD.AtBreakpoints == (xAtBreakpointNode)0 &&
      xSysD.OutputBreakpoints == (xBreakpointOutputNode)0) {
    xPrintString("No breakpoints defined\n");
    return;
  }

  count = 0;
  for ( BPA = xSysD.AtBreakpoints;
        BPA != (xAtBreakpointNode)0;
        BPA = BPA->Next )
    xListOneBreakpointAt(BPA, &count);
  for ( BPV = xSysD.VariableBreakpoints;
        BPV != (xVariableBreakpointNode)0;
        BPV = BPV->Next )
    xListOneBreakpointVariable(BPV, &count);
  for ( BPT = xSysD.TransitionBreakpoints;
        BPT != (xBreakpointNode)0;
        BPT = BPT->Next )
    xListOneBreakpoint(BPT, &count);
  for ( BPO = xSysD.OutputBreakpoints;
        BPO != (xBreakpointOutputNode)0;
        BPO = BPO->Next )
    xListOneBreakpointOutput(BPO, &count);
}

/*---+---------------------------------------------------------------
     xSaveBreakpoints
-------------------------------------------------------------------*/
static void xSaveBreakpoints (char * strVar)
{
  xVariableBreakpointNode BPV;
  xAtBreakpointNode       BPA;
  xBreakpointNode         BPT;
  xBreakpointOutputNode   BPO;
  FILE                  * TempFile;

  if (xSysD.TransitionBreakpoints == (xBreakpointNode)0 &&
      xSysD.VariableBreakpoints == (xVariableBreakpointNode)0 &&
      xSysD.AtBreakpoints == (xAtBreakpointNode)0 &&
      xSysD.OutputBreakpoints == (xBreakpointOutputNode)0) {
    xPrintString("No breakpoints defined\n");
    return;
  }

  if (! xGetAndOpenFile(&TempFile, (xbool)0, strVar, "com") )
    return;

  for ( BPA = xSysD.AtBreakpoints;
        BPA != (xAtBreakpointNode)0;
        BPA = BPA->Next )
    xSaveOneBreakpointAt(TempFile, BPA);
  for ( BPV = xSysD.VariableBreakpoints;
        BPV != (xVariableBreakpointNode)0;
        BPV = BPV->Next )
    xSaveOneBreakpointVariable(TempFile, BPV);
  for ( BPT = xSysD.TransitionBreakpoints;
        BPT != (xBreakpointNode)0;
        BPT = BPT->Next )
    xSaveOneBreakpoint(TempFile, BPT);
  for ( BPO = xSysD.OutputBreakpoints;
        BPO != (xBreakpointOutputNode)0;
        BPO = BPO->Next )
    xSaveOneBreakpointOutput(TempFile, BPO);
  if (TempFile != stdout)
    if (fclose(TempFile) != 0)
      xPrintString("Error saving breakpoints\n");
  PRINTF2("Breakpoints saved on file %s\n", strVar);
}


/*---+---------------------------------------------------------------
     xStackCom
-------------------------------------------------------------------*/
static void xStackCom (void)
{
  xPrsNode      PrsNode;
  xPrdNode      PrdNode;
#ifndef XNOUSEOFSERVICE
  xSrvNode      SrvNode;
#endif

  if (xSysD.xPrsScope == (xPrsNode)0) {
    xPrintScope((xbool)1);
    return;
  }
  PrsNode = xSysD.xPrsScope;
#ifndef XNOUSEOFSERVICE
  if (PrsNode->ActiveSrv != (xSrvNode)0) {
    if (xSysD.xSrvScope != (xSrvNode)0)
      SrvNode = xSysD.xSrvScope;
    else
      SrvNode = PrsNode->ActiveSrv;
    for (PrdNode = SrvNode->ActivePrd;
         PrdNode != (xPrdNode)0;
         PrdNode = PrdNode->DynamicFather) {
      xWriteBuf_Fmt("Procedure %-*s in state %s%c\n",
              xfShortIdentifierLength+7,
              xPrdInstance(PrdNode),
              xGetState(PrsNode, PrdNode, PrdNode->NameNode->StateList,
                        PrdNode->State)->Name,
              (PrdNode == PrsNode->ActiveSrv->ActivePrd &&
               ! PrsNode->ActiveSrv->InTransition) ? ' ' : '*');
    }
    xWriteBuf_Fmt("Service   %-*s in state %s%c\n",
            xfShortIdentifierLength+7,
            SrvNode->NameNode->Name,
            xGetState(PrsNode, (xPrdNode)0, SrvNode->NameNode->StateList,
                      SrvNode->State)->Name,
            SrvNode->InTransition ? '*' : ' ');
    xWriteBuf_Fmt("PId       %-*s\n",
            xfShortIdentifierLength+7,
            xWri_SDL_PId(&(PrsNode->Self)));
    return;
  }
#endif
  for (PrdNode = PrsNode->ActivePrd;
       PrdNode != (xPrdNode)0;
       PrdNode = PrdNode->DynamicFather) {
    xWriteBuf_Fmt("Procedure %-*s in state %s%c\n",
            xfShortIdentifierLength+7,
            xPrdInstance(PrdNode),
            xGetState(PrsNode, PrdNode, PrdNode->NameNode->StateList,
                      PrdNode->State)->Name,
            (PrdNode == PrsNode->ActivePrd &&
             ! PrsNode->InTransition) ? ' ' : '*');
  }
  xWriteBuf_Fmt("PId       %-*s in state %s%c\n",
          xfShortIdentifierLength+7,
          xWri_SDL_PId(&(PrsNode->Self)),
          xGetState(PrsNode, (xPrdNode)0, PrsNode->NameNode->StateList,
                    XPRS_STATEID(PrsNode))->Name,
          (PrsNode->InTransition || PrsNode->ActivePrd != (xPrdNode)0)
          ? '*' : ' ');
}


/*---+---------------------------------------------------------------
     xSetScope
-------------------------------------------------------------------*/
static void xSetScope (void)
{
  xPrsNode      tmpPrs;
  xPrsIdNode    ProcessId;
#ifndef XNOUSEOFSERVICE
  xSrvIdNode    ServiceId;
  xbool         xEmptyInput;
#endif

  tmpPrs = xReadProcess("Process : ", &ProcessId, (xIdNode)0);
  if (tmpPrs != (xPrsNode)0) {
#ifndef XNOUSEOFSERVICE
    if (tmpPrs->ActiveSrv != (xSrvNode)0) {
      xSysD.xSrvScope = xReadService("Service : ", &ServiceId,
                                     tmpPrs, &xEmptyInput);
      if (ServiceId != (xSrvIdNode)0 && xSysD.xSrvScope == (xSrvNode)0) {
        xPrintString("Service is stopped\n");
        xPrintScope((xbool)1);
        return; 
      }
      if (xSysD.xSrvScope != (xSrvNode)0)
        xSysD.xPrdScope = xSysD.xSrvScope->ActivePrd;
      else
        xSysD.xPrdScope = (xPrdNode)0;
    } else {
#endif
      xSysD.xPrdScope = tmpPrs->ActivePrd;
#ifndef XNOUSEOFSERVICE
      xSysD.xSrvScope = NULL;
    }
#endif
    xSysD.xPrsScope = tmpPrs;
  }
  xPrintScope((xbool)1);
}


/*---+---------------------------------------------------------------
     xUpCom
-------------------------------------------------------------------*/
static void xUpCom (void)
{
  if (xSysD.xPrsScope != (xPrsNode)0) {
#ifndef XNOUSEOFSERVICE
    if (xSysD.xSrvScope != (xSrvNode)0) {
      if (xSysD.xPrdScope == (xPrdNode)0) {
        xSysD.xSrvScope = (xSrvNode)0;     /* Up from service to process */
        xPrintScope((xbool)1);
        return;
      }
    }
#endif
    if (xSysD.xPrdScope == (xPrdNode)0) {
      xPrintString("At top of stack\n");
      return;
    }
    xSysD.xPrdScope = xSysD.xPrdScope->DynamicFather;
    xPrintScope((xbool)1);
    return;
  }
  xPrintScope((xbool)1);
}


/*---+---------------------------------------------------------------
     xDownCom
-------------------------------------------------------------------*/
static void xDownCom (void)
{
  xPrdNode      PrdNode;
#ifndef XNOUSEOFSERVICE
  xbool         xEmptyInput;
  xSrvIdNode    ServiceId;
#endif

  if (xSysD.xPrsScope != (xPrsNode)0) {
#ifndef XNOUSEOFSERVICE
    if (xSysD.xPrsScope->ActiveSrv != (xSrvNode)0 &&
        xSysD.xSrvScope == (xSrvNode)0) {
      /* down to service */
      xSysD.xSrvScope = xReadService("Service : ", &ServiceId,
                                     xSysD.xPrsScope, &xEmptyInput);
      if (xEmptyInput)
        xSysD.xSrvScope = xSysD.xPrsScope->ActiveSrv;
      else if (ServiceId != (xSrvIdNode)0 && xSysD.xSrvScope == (xSrvNode)0)
        xPrintString("Service is stopped\n");
      xPrintScope((xbool)1);
      return;
    }
    if (xSysD.xPrsScope->ActiveSrv != (xSrvNode)0 &&
        xSysD.xSrvScope != (xSrvNode)0) {
      if (xSysD.xPrdScope == xSysD.xSrvScope->ActivePrd) {
        xPrintString("At bottom of stack\n");
        return;
      }
      PrdNode = xSysD.xSrvScope->ActivePrd;
      while (PrdNode->DynamicFather != xSysD.xPrdScope)
        PrdNode = PrdNode->DynamicFather;
      xSysD.xPrdScope = PrdNode;
      xPrintScope((xbool)1);
      return;
    }
#endif
    if (xSysD.xPrdScope == xSysD.xPrsScope->ActivePrd) {
      xPrintString("At bottom of stack\n");
      return;
    }
    PrdNode = xSysD.xPrsScope->ActivePrd;
    while (PrdNode->DynamicFather != xSysD.xPrdScope)
      PrdNode = PrdNode->DynamicFather;
    xSysD.xPrdScope = PrdNode;
    xPrintScope((xbool)1);
    return;
  }
  xPrintScope((xbool)1);
}


/*---+---------------------------------------------------------------
     xWriteSignalParameters2
-------------------------------------------------------------------*/
static void xWriteSignalParameters2(
  xSignalNode Signal,
  char * Str)
{
  xIdNode xIdNodeSigPar;
  xbool   First = (xbool)1;

  if (XSIGNAL_IDNODE(Signal)->First == (xIdNode)0)
    return;

  PRINTF(" (");
  for (xIdNodeSigPar = XSIGNAL_IDNODE(Signal)->First;
       xIdNodeSigPar != (xIdNode)0;
       xIdNodeSigPar = xIdNodeSigPar->Suc) {
    if (First)
      First = (xbool)0;
    else
      PRINTF(", ");
    xxWriteSort(
      (void *)((xptrint)XSIGNAL_DATA(Signal)+((xVarIdNode)xIdNodeSigPar)->Offset),
      ((xVarIdNode)xIdNodeSigPar)->TypeNode);
  }
  PRINTF(")");
}


/*---+---------------------------------------------------------------
     xWriteFPars2
-------------------------------------------------------------------*/
static void xWriteFPars2(
  xPrsIdNode   Prs,
  xSignalNode  Signal,
  xbool       *First,
  char        *Str)
{
  xIdNode  IdNode;

  /* Treat first FPar:s in inherited process types. */
  if (Prs->Super != (xPrsIdNode)0)
    xWriteFPars2(Prs->Super, Signal, First, Str);

  /* Loop for formal parameters in this type (or ProcessEC) */
  for (IdNode = Prs->First; IdNode != (xIdNode)0; IdNode = IdNode->Suc ) {
    if (IdNode->EC == xFormalParEC) {
      if (*First) {
        PRINTF2("%s", Str);
        *First = (xbool)0;
      }
      else
        PRINTF(", ");
      xxWriteSort((void *)((xptrint)(XSIGNAL_DATA(Signal)) +
			  ((xVarIdNode)IdNode)->Offset2),
		 ((xVarIdNode)IdNode)->TypeNode);
    }
  }
}


/*---+---------------------------------------------------------------
     xGetRootSort
-------------------------------------------------------------------*/
/* Returns the root sort (wrt syntypes and inheritance) of the
   sort definition given by "sort".
*/

tSDLTypeInfo *xGetRootSort(tSDLTypeInfo *sort)
{
  tSDLTypeInfo *rootSort = sort;

  while  (rootSort->TypeClass == type_SDL_Syntype ||
          rootSort->TypeClass == type_SDL_Inherits)
    rootSort = ((tSDLGenInfo *)rootSort)->CompOrFatherSort;
  return rootSort;
}


/*---+---------------------------------------------------------------
     IsOwnInOutPar
-------------------------------------------------------------------*/
static xbool IsOwnInOutPar(xVarIdNode parId)
{
  if (XIS_INOUT_PARA(parId) &&
      xGetRootSort(parId->TypeNode)->TypeClass == type_SDL_Own) {
    return (xbool)1;
  }

  return (xbool)0;
}


/*---+---------------------------------------------------------------
     xRefAddress
-------------------------------------------------------------------*/
xbool xRefAddress(WriteBuf *buf, void *ptr, xIdNode FromNode)
{
  xIdNode       IdNode;
  xPrsNode      PrsNode;
  xPrdNode      PrdNode;
#ifndef XNOUSEOFSERVICE
  xSrvNode      SrvNode;
#endif
  xptrint  OldArea, TempOldStart, TempOldEnd;

  for ( IdNode  = FromNode->First;
        IdNode != (xIdNode)0;
        IdNode  = IdNode->Suc ) {
    if (IdNode->EC == xProcessEC) {
      for (PrsNode = *((xPrsIdNode)IdNode)->ActivePrsList;
           PrsNode != (xPrsNode)0;
           PrsNode = PrsNode->NextPrs) {
        OldArea = (xptrint)ptr;

        /* Check process data area */
        TempOldStart = (xptrint)PrsNode;
        TempOldEnd = TempOldStart + PrsNode->NameNode->VarSize;
        if ((TempOldStart <= OldArea) && (TempOldEnd > OldArea)) {
          /* Process data area is referenced */
          xAddBuf_Fmt(buf, "Ref Process %s %x",
                  xWri_SDL_PId(&(PrsNode->Self)), OldArea - TempOldStart);
          return (xbool)1;
        }
        if (PrsNode->pREPLY_Signal) {
          TempOldStart = (xptrint)(PrsNode->pREPLY_Signal);
          TempOldEnd = TempOldStart + PrsNode->pREPLY_Signal->NameNode->VarSize;
          if ((TempOldStart <= OldArea) && (TempOldEnd > OldArea)) {
            /* Process RPC reply signal data area is referenced */
            xAddBuf_Fmt(buf, "Ref Signal %s %x",
                    PrsNode->pREPLY_Signal->NameNode->Name,
                    OldArea - TempOldStart);
            return (xbool)1;
          }
        }

        if (PrsNode->ActivePrd) {
          /* Check procedures data area */
          for (PrdNode = PrsNode->ActivePrd;
               PrdNode;
               PrdNode = PrdNode->DynamicFather) {
            TempOldStart = (xptrint)PrdNode;
            TempOldEnd = TempOldStart + PrdNode->NameNode->VarSize;
            if (TempOldStart <= OldArea && TempOldEnd > OldArea) {
              /* Procedure data area is referenced */
              xAddBuf_Fmt(buf, "Ref Procedure %s %x",
                      xPrdInstance(PrdNode), OldArea - TempOldStart);
              return (xbool)1;
            }
            if (PrdNode->pREPLY_Signal) { /* Check pointer into RPC reply signal */
              TempOldStart = (xptrint)(PrdNode->pREPLY_Signal);
              TempOldEnd = TempOldStart +
                PrdNode->pREPLY_Signal->NameNode->VarSize;
              if (TempOldStart <= OldArea && TempOldEnd > OldArea) {
                /* PrdNode->pREPLY_Signals data area is referenced */
                xAddBuf_Fmt(buf, "Ref ProcedureSignal %s %s %x",
                        xPrdInstance(PrdNode),
                        PrdNode->pREPLY_Signal->NameNode->Name,
                        OldArea - TempOldStart);
                return (xbool)1;
              }
            }
          }
        }

#ifndef XNOUSEOFSERVICE
        if (PrsNode->SrvList) {
          /* Check services data area */
          for (SrvNode = PrsNode->SrvList;
               SrvNode;
               SrvNode = SrvNode->NextSrv) {
            TempOldStart = (xptrint)SrvNode;
            TempOldEnd = TempOldStart + SrvNode->NameNode->VarSize;
            if (TempOldStart <= OldArea && TempOldEnd > OldArea) {
              /* Service data area is referenced */
              xAddBuf_Fmt(buf, "Ref Service %x",
                      OldArea - TempOldStart);
              return (xbool)1;
            }
            if (SrvNode->pREPLY_Signal) {
              TempOldStart = (xptrint)(PrsNode->pREPLY_Signal);
              TempOldEnd = TempOldStart + PrsNode->pREPLY_Signal->NameNode->VarSize;
              if (TempOldStart <= OldArea && TempOldEnd > OldArea) {
                /* Service RPC reply signal data area is referenced */
                xAddBuf_Fmt(buf, "Ref ServiceSignal %s %x",
                        SrvNode->pREPLY_Signal->NameNode->Name,
                        OldArea - TempOldStart);
                return (xbool)1;
              }
            }

            if (SrvNode->ActivePrd) {
              /* Check procedures in service data area */
              for (PrdNode = SrvNode->ActivePrd;
                   PrdNode;
                   PrdNode = PrdNode->DynamicFather) {
                TempOldStart = (xptrint)PrdNode;
                TempOldEnd = TempOldStart + PrdNode->NameNode->VarSize;
                if (TempOldStart <= OldArea && TempOldEnd > OldArea) {
                  /* Procedure data area is referenced */
                  xAddBuf_Fmt(buf, "Ref Procedure %s %x",
                              xPrdInstance(PrdNode), OldArea - TempOldStart);
                  return (xbool)1;
                }
                if (PrdNode->pREPLY_Signal) { /* Check pointer into RPC reply signal */
                  TempOldStart = (xptrint)(PrdNode->pREPLY_Signal);
                  TempOldEnd = TempOldStart +
                    PrdNode->pREPLY_Signal->NameNode->VarSize;
                  if (TempOldStart <= OldArea && TempOldEnd > OldArea) {
                    /* PrdNode->pREPLY_Signals data area is referenced */
                    xAddBuf_Fmt(buf, "Ref ProcedureSignal %s %s %x",
                                xPrdInstance(PrdNode),
                                PrdNode->pREPLY_Signal->NameNode->Name,
                                OldArea - TempOldStart);
                    return (xbool)1;
                  }
                }
              }
            }
          }
        }
#endif
      }
    }
  }
  for ( IdNode  = FromNode->First;
        IdNode != (xIdNode)0;
        IdNode  = IdNode->Suc ){
    if (xRefAddress(buf, ptr, IdNode))
      return (xbool)1;
  }

  /* Not found */
  return (xbool)0;
}

xPrdNode xReadPrdInstance(char * strVar);
/*---+---------------------------------------------------------------
     xGetRefAddress
-------------------------------------------------------------------*/
void *xGetRefAddress(char * strVar)
{
  xbool         xEmptyInput;
  xptrint       AreaAddress;
  xxToken       Token;
  xPrsIdNode    ProcessId;
  xPrsNode      PrsNode;
  xPrdNode      PrdNode;
  xptrint       Offset;
  XSIGTYPE      SignalId;

  Token = xPromptQuestionMark("Entity : ", "Entity : ", strVar);
  if (Token == xxProcess) {
    PrsNode = xReadProcess(" (PId) : ", &ProcessId, (xIdNode)0);
    if ( ! PrsNode ) {
      return NULL;
    }
    AreaAddress = (xptrint)PrsNode;
  }
  else if (Token == xxProcedure) {
    PrdNode = xReadPrdInstance(strVar);
    if ( ! PrdNode ) {
      return NULL;
    }
    AreaAddress = (xptrint)PrdNode;
  }
#ifndef XNOUSEOFSERVICE
  else if (Token == xxService) {
    AreaAddress = (xptrint)xSysD.xSrvScope;
  }
#endif
  else if (Token == xxId && ! strcmp(strVar, "Signal") ) {
    if ( ! xSysD.xPrsScope || ! xSysD.xPrsScope->pREPLY_Signal ) {
      return NULL;
    }

    SignalId = (xSignalIdNode)xGetIdNodeInECSet("Signal name : ",
         1L<<((long)xRPCSignalEC), xSymbolTableRoot,
         &xEmptyInput, (xbool)0, (xIdNode)0);
    if (SignalId == (xSignalIdNode)0)
      return NULL;

    if (xSysD.xPrsScope->pREPLY_Signal->NameNode != SignalId) {
      PRINTF2("Wrong signal %s\n", SignalId->Name);
      return NULL;
    }

    AreaAddress = (xptrint)(xSysD.xPrsScope->pREPLY_Signal);
  }
#ifndef XNOUSEOFSERVICE
  else if (Token == xxId && ! strcmp(strVar, "ServiceSignal") ) {
    if ( ! xSysD.xSrvScope || ! xSysD.xSrvScope->pREPLY_Signal ) {
      return NULL;
    }

    SignalId = (xSignalIdNode)xGetIdNodeInECSet("Signal name : ",
         1L<<((long)xRPCSignalEC), xSymbolTableRoot,
         &xEmptyInput, (xbool)0, (xIdNode)0);
    if (SignalId == (xSignalIdNode)0)
      return NULL;

    if (xSysD.xSrvScope->pREPLY_Signal->NameNode != SignalId) {
      PRINTF2("Wrong signal %s\n", SignalId->Name);
      return NULL;
    }

    AreaAddress = (xptrint)(xSysD.xSrvScope->pREPLY_Signal);
  }
#endif
  else if (Token == xxId && ! strcmp(strVar, "ProcedureSignal") ) {
    PrdNode = xReadPrdInstance(strVar);
    if ( ! PrdNode || ! PrdNode->pREPLY_Signal ) {
      return NULL;
    }

    SignalId = (xSignalIdNode)xGetIdNodeInECSet("Signal name : ",
         1L<<((long)xRPCSignalEC), xSymbolTableRoot,
         &xEmptyInput, (xbool)0, (xIdNode)0);
    if (SignalId == (xSignalIdNode)0)
      return NULL;

    if (PrdNode->pREPLY_Signal->NameNode != SignalId) {
      PRINTF2("Wrong signal %s\n", SignalId->Name);
      return NULL;
    }

    AreaAddress = (xptrint)(PrdNode->pREPLY_Signal);
  }
  else {
    return NULL;
  }

  Token = xPromptQuestionMark("Offset : ", "Offset : ", strVar);
  if (Token != xxId || ! sscanf(strVar, "%x", &Offset) ) {
    return NULL;
  }

  return (void *)(AreaAddress + Offset);
}

/*---+---------------------------------------------------------------
     xPrintPrsVariable2
-------------------------------------------------------------------*/
void xPrintPrsVariable2(
  xVarIdNode IdNode,
  xptrint    PrsNode)
{
  PRINTF2("Assign-Value %s ", IdNode->Name);
  xxWriteSort((void *) (PrsNode + IdNode->Offset), IdNode->TypeNode);
  PRINTF("\n");
  if (IdNode->EC == xVariableEC && IdNode->Offset2 != (xptrint)0) {
    PRINTF2("xSet ExportedValue %s ", IdNode->Name);
    xxWriteSort((void *) (PrsNode + IdNode->Offset2), IdNode->TypeNode);    
    PRINTF("\n");
  }
}


/*---+---------------------------------------------------------------
     xPrintAllPrsVariables2
-------------------------------------------------------------------*/
void xPrintAllPrsVariables2(
  xIdNode    IdNode,
  xptrint    PrsNode)
{
  xVarIdNode  VarId;
  xPrsIdNode  ProcessId;
#ifndef XNOUSEOFSERVICE
  xSrvIdNode  ServiceId;
#endif
  int         count = 0;

  if (IdNode->EC == xProcessEC) {
    for ( ProcessId = (xPrsIdNode)IdNode;
          ProcessId != (xPrsIdNode)0;
          ProcessId = ProcessId->Super) {
      for ( VarId = (xVarIdNode)ProcessId->First;
            VarId != (xVarIdNode)0;
            VarId = (xVarIdNode)VarId->Suc ) {
        if (VarId->EC == xSyntVariableEC) {
          count++;
          PRINTF2("xSet SyntVariable %d ", count);
          xxWriteSort((void *) (PrsNode + VarId->Offset), VarId->TypeNode);
          PRINTF("\n");
        }
        else if (VarId->EC == xVariableEC || VarId->EC == xFormalParEC) {
          xPrintPrsVariable2(VarId, PrsNode);
        }
      }
    }
#ifndef XNOUSEOFSERVICE
  } else {
    for ( ServiceId = (xSrvIdNode)IdNode;
          ServiceId != (xSrvIdNode)0;
          ServiceId = ServiceId->Super) {
      for ( VarId = (xVarIdNode)ServiceId->First;
            VarId != (xVarIdNode)0;
            VarId = (xVarIdNode)VarId->Suc ) {
        if (VarId->EC == xSyntVariableEC) {
          count++;
          PRINTF2("xSet SyntVariable %d ", count);
          xxWriteSort((void *) (PrsNode + VarId->Offset), VarId->TypeNode);
          PRINTF("\n");
        }
        else if (VarId->EC == xVariableEC || VarId->EC == xFormalParEC) {
          xPrintPrsVariable2(VarId, PrsNode);
        }
      }
    }
#endif
  }
}


/*---+---------------------------------------------------------------
     xPrintPrdVariable2
-------------------------------------------------------------------*/
static void xPrintPrdVariable2(
  xVarIdNode IdNode,
  xPrdNode   PrdNode,
#ifndef XNOUSEOFSERVICE
  xSrvNode   SrvNode,
#endif
  xPrsNode   PrsNode)
{
  xptrint  OldArea, TempOldStart, TempOldEnd;
  xPrdNode TempOld;
  xbool    Found = (xbool)0;

  if (IdNode->EC == xFormalParEC && 
      (XIS_ADDRESS(IdNode) || IsOwnInOutPar(IdNode))) {
    /* Find IN/OUT parameter */
    /* Locate referenced data area */
    if (IsOwnInOutPar(IdNode)) {
      /* If an In/Out parameter is of type Own two variables are
         allocated in the procedure - one for the value and one
         with the address of to the actual parameter (_Var) */
      OldArea = *(xptrint *)((xptrint)PrdNode + IdNode->Offset +
                             IdNode->TypeNode->SortSize);
    }
    else {
      OldArea = *(xptrint *)((xptrint)PrdNode + IdNode->Offset);
    }
    /* Loop over dynamic fathers */
    TempOld = PrdNode->DynamicFather;
    while (TempOld) {
      TempOldStart = (xptrint)(TempOld);
      TempOldEnd = TempOldStart + TempOld->NameNode->VarSize;
      if ((TempOldStart <= OldArea) && (TempOldEnd > OldArea)) {
        /* TempOlds data area is referenced by current IN/OUT par */
        PRINTF4("xSet Address %s Procedure %s %x\n", IdNode->Name,
                xPrdInstance(TempOld), OldArea - TempOldStart);
        break;
      }
      if (TempOld->pREPLY_Signal) { /* Check pointer into RPC reply signal */
        TempOldStart = (xptrint)(TempOld->pREPLY_Signal);
        TempOldEnd = TempOldStart +
          TempOld->pREPLY_Signal->NameNode->VarSize;
        if ((TempOldStart <= OldArea) && (TempOldEnd > OldArea)) {
          /* TempOld->pREPLY_Signals data area is referenced by current
             IN/OUT par */
          PRINTF5("xSet Address %s ProcedureSignal %s %s %x\n",
                  IdNode->Name,
                  xPrdInstance(TempOld),
                  TempOld->pREPLY_Signal->NameNode->Name,
                  OldArea - TempOldStart);
          break;
        }
      }
      TempOld = TempOld->DynamicFather;
    }
    if (TempOld)
      Found = (xbool)1;
#ifndef XNOUSEOFSERVICE
    if (!Found && SrvNode) {
      /* No procedure data area is referenced: Check service data area */
      TempOldStart = (xptrint)SrvNode;
      TempOldEnd = TempOldStart + SrvNode->NameNode->VarSize;
      if ((TempOldStart <= OldArea) && (TempOldEnd > OldArea)) {
        /* Service data area is referenced */
        PRINTF3("xSet Address %s Service %x\n", IdNode->Name,
                OldArea - TempOldStart);
        Found = (xbool)1;
      } else if (SrvNode->pREPLY_Signal) {
        TempOldStart = (xptrint)(PrsNode->pREPLY_Signal);
        TempOldEnd = TempOldStart + PrsNode->pREPLY_Signal->NameNode->VarSize;
        if ((TempOldStart <= OldArea) && (TempOldEnd > OldArea)) {
          /* Service RPC reply signal data area is referenced */
          PRINTF4("xSet Address %s ServiceSignal %s %x\n", IdNode->Name,
                  SrvNode->pREPLY_Signal->NameNode->Name,
                  OldArea - TempOldStart);
          Found = (xbool)1;
        }
      }
    }
#endif
    if (!Found) {
      /* No procedure data area is referenced: Check process data area */
      TempOldStart = (xptrint)PrsNode;
      TempOldEnd = TempOldStart + PrsNode->NameNode->VarSize;
      if ((TempOldStart <= OldArea) && (TempOldEnd > OldArea)) {
        /* Process data area is referenced */
        PRINTF4("xSet Address %s Process %s %x\n", IdNode->Name,
                xWri_SDL_PId(&(PrsNode->Self)), OldArea - TempOldStart);
      } else if (PrsNode->pREPLY_Signal) {
        TempOldStart = (xptrint)(PrsNode->pREPLY_Signal);
        TempOldEnd = TempOldStart + PrsNode->pREPLY_Signal->NameNode->VarSize;
        if ((TempOldStart <= OldArea) && (TempOldEnd > OldArea)) {
          /* Process RPC reply signal data area is referenced */
          PRINTF4("xSet Address %s Signal %s %x\n", IdNode->Name,
                  PrsNode->pREPLY_Signal->NameNode->Name,
                  OldArea - TempOldStart);
        }
      } else { /* Error */
        PRINTF("ERROR: IN/OUT parameter without matching referenced data area\n");
      }
    }
    if (IsOwnInOutPar(IdNode)) {
      PRINTF2("Assign-Value %s ", IdNode->Name);
      xxWriteSort((void *)((xptrint)PrdNode + IdNode->Offset), IdNode->TypeNode);
      PRINTF("\n");
    }
  }
  else {
    PRINTF2("Assign-Value %s ", IdNode->Name);
    xxWriteSort((void *)((xptrint)PrdNode + IdNode->Offset), IdNode->TypeNode);
    PRINTF("\n");
  }
}


/*---+---------------------------------------------------------------
     xPrintAllPrdVariables2
-------------------------------------------------------------------*/
static void xPrintAllPrdVariables2(
  xPrdNode   PrdNode,
#ifndef XNOUSEOFSERVICE
  xSrvNode   SrvNode,
#endif
  xPrsNode   PrsNode)
{
  xVarIdNode  VarId;
  xPrdIdNode  PrdId;
  int         count = 0;

  for (VarId = (xVarIdNode)PrdNode->NameNode->First;
       VarId != (xVarIdNode)0;
       VarId = (xVarIdNode)VarId->Suc ){
    if (VarId->EC == xSyntVariableEC) {
      count++;
      PRINTF2("xSet SyntVariable %d ", count);
      xxWriteSort((void *) ((xptrint)PrdNode + VarId->Offset), VarId->TypeNode);
      PRINTF("\n");
    }
    else if (VarId->EC == xVariableEC || VarId->EC == xFormalParEC) {
      xPrintPrdVariable2(VarId, PrdNode,
#ifndef XNOUSEOFSERVICE
                         SrvNode,
#endif
                         PrsNode);
    }
  }
  for (PrdId = PrdNode->NameNode->Super;
       PrdId != (xPrdIdNode)0;
       PrdId = PrdId->Super)
    for (VarId = (xVarIdNode)PrdId->First;
         VarId != (xVarIdNode)0;
         VarId = (xVarIdNode)VarId->Suc ){
      if (VarId->EC == xSyntVariableEC) {
        count++;
        PRINTF2("xSet SyntVariable %d ", count);
        xxWriteSort((void *) ((xptrint)PrdNode + VarId->Offset), VarId->TypeNode);
        PRINTF("\n");
      }
      else if (VarId->EC == xVariableEC || VarId->EC == xFormalParEC) {
        xPrintPrdVariable2(VarId, PrdNode,
#ifndef XNOUSEOFSERVICE
                           SrvNode,
#endif
                           PrsNode);
      }
    }
}


/*---+---------------------------------------------------------------
     xSavePrdList
-------------------------------------------------------------------*/
static void xSavePrdList(
  xPrdNode   PrdNode,
#ifndef XNOUSEOFSERVICE
  xSrvNode   SrvNode,
#endif
  xPrsNode   PrsNode)
{
  int           count;
  xPrdIdNode    PrdId;

  /* First treat dynamic father */
  if (PrdNode->DynamicFather) {
    xSavePrdList(PrdNode->DynamicFather,
#ifndef XNOUSEOFSERVICE
                 SrvNode,
#endif
                 PrsNode);
  }

  PRINTF2("\nxSet Call-Procedure %s", xWriteEntity((xIdNode)PrdNode->NameNode));
  PRINTF2(" %s\n", xWri_SDL_PId(&(PrsNode->Self)));
  PRINTF2("xSet Nextstate %d\n", PrdNode->State);
  PrdId = PrdNode->NameNode;
  if (PrdId->Super) {
    if (PrdId->Assoc_Function != PrdNode->RestartPRD) {
      count = 0;
      while (PrdId->Assoc_Function != PrdNode->RestartPRD) {
        count++;
        PrdId = PrdId->Super;
      }
      PRINTF2("xSet RestartPRD %d\n", count);
    }
  }
  PRINTF2("xSet RestartAddress %d\n", PrdNode->RestartAddress);
  if (PrdNode->StaticFather) {
    PRINTF2("xSet StaticFather %s\n", xPrdInstance(PrdNode->StaticFather));
  }
  if (PrdNode->pREPLY_Signal) {
    PRINTF2("xSet pREPLY_Signal %s",
            xWriteEntity((xIdNode)PrdNode->pREPLY_Signal->NameNode));
    xWriteSignalParameters2(PrdNode->pREPLY_Signal, "");
    PRINTF2(" %s",
            xWri_SDL_PId(&(XSIGNAL_RECEIVER(PrdNode->pREPLY_Signal))));
    PRINTF2(" %s\n",
            xWri_SDL_PId(&(XSIGNAL_SENDER(PrdNode->pREPLY_Signal))));
  }
  xPrintAllPrdVariables2(PrdNode,
#ifndef XNOUSEOFSERVICE
                         SrvNode,
#endif
                         PrsNode);
}


/*---+---------------------------------------------------------------
     HasFPars
-------------------------------------------------------------------*/
static xbool HasFPars(xPrsIdNode Prs)
{
  xIdNode       IdNode;

  for ( ; Prs; Prs = Prs->Super) {
    for (IdNode = Prs->First; IdNode; IdNode = IdNode->Suc) {
      if (IdNode->EC == xFormalParEC) {
        return (xbool)1;
      }
    }
  }
  return (xbool)0;
}

/*---+---------------------------------------------------------------
     xCreateAllPId
-------------------------------------------------------------------*/
static void xCreateAllPId (xIdNode FromNode)
{
  xIdNode       IdNode;
  int           count;

  for ( IdNode  = FromNode->First;
        IdNode != (xIdNode)0;
        IdNode  = IdNode->Suc ) {
    if (IdNode->EC == xProcessEC) {
      for (count = 1; count < ((xPrsIdNode)IdNode)->NextNr; count++) {
        PRINTF2("Create %s null", xWriteEntity(IdNode));
        if (HasFPars((xPrsIdNode)IdNode)) {
          PRINTF(" ()");
        }
        if (((xPrsIdNode)IdNode)->MaxNoOfInst != -1 &&  /* not infinity */
            count > ((xPrsIdNode)IdNode)->MaxNoOfInst) {
          PRINTF(" yes");
        }
        PRINTF("\n");
      }
    }
  }
  for ( IdNode  = FromNode->First;
        IdNode != (xIdNode)0;
        IdNode  = IdNode->Suc ){
    xCreateAllPId(IdNode);
  }
}

/*---+---------------------------------------------------------------
     xStopSomePId
-------------------------------------------------------------------*/
static void xStopSomePId (xIdNode FromNode)
{
  xIdNode       IdNode;
  xPrsNode      PrsNode;
  int           count;

  for ( IdNode  = FromNode->First;
        IdNode != (xIdNode)0;
        IdNode  = IdNode->Suc ) {
    if (IdNode->EC == xProcessEC) {
      PrsNode = *((xPrsIdNode)IdNode)->ActivePrsList;
      for (count = ((xPrsIdNode)IdNode)->NextNr - 1;
           count >= 1;
           count--) {
        if ( ! PrsNode || PrsNode->Self.LocalPId->InstNr != count) {
          PRINTF3("Stop %s:%d\n", xWriteEntity(IdNode), count);
        }
        else {
          PrsNode = PrsNode->NextPrs;
        }
      }
    }
  }
  for ( IdNode  = FromNode->First;
        IdNode != (xIdNode)0;
        IdNode  = IdNode->Suc ){
    xStopSomePId(IdNode);
  }
}

/*---+---------------------------------------------------------------
     xSaveAllSignals
-------------------------------------------------------------------*/
static void xSaveAllSignals (xPrsNode PrsNode)
{
  int           count;
  xSignalNode   Signal;
  xbool         First = (xbool)1;

  if (PrsNode->Signal) {
    if ( ! PrsNode->Signal->Pre &&  /* not in InputPort */
         ! XIS_STARTUP_SIGNAL(PrsNode->Signal)) {
      if (XIS_CONT_SIGNAL(PrsNode->Signal)) {
        PRINTF2("xSet ContSignal %d\n", PrsNode->Signal->Prio);
      }
      else {
        PRINTF2("Output-Internal %s",
                xWriteEntity((xIdNode)PrsNode->Signal->NameNode));
#if defined(XSIGPRIO) || defined(XSIGPRSPRIO) || defined(XPRSSIGPRIO)
# ifndef XNOSIGPRIOPROMPT
        PRINTF2(" %d", XCONT_SIG_PRIO(PrsNode->Signal));
# endif
#endif
        xWriteSignalParameters2(PrsNode->Signal, "");
        PRINTF2(" %s",
                xWri_SDL_PId(&(XSIGNAL_RECEIVER(PrsNode->Signal))));
        PRINTF2(" %s\n",
                xWri_SDL_PId(&(XSIGNAL_SENDER(PrsNode->Signal))));
      }
    }
    if (XIS_STARTUP_SIGNAL(PrsNode->Signal)) {
      if (HasFPars(PrsNode->NameNode)) {
        PRINTF("xSet StartUpSignalPar ");
        First = (xbool)1;
        xWriteFPars2(PrsNode->NameNode, PrsNode->Signal, &First, "");
        PRINTF("\n");
      }
    }
  }
  count = 0;
  for (Signal = PrsNode->InputPort.Suc;
       Signal != (xSignalNode)&PrsNode->InputPort;
       Signal = Signal->Suc) {
    if (! XIS_STARTUP_SIGNAL(Signal)) {
      count++;
      if (XIS_CONT_SIGNAL(Signal)) {
        PRINTF2("xSet ContSignal %d\n", Signal->Prio);
      }
      else if (Signal->NameNode == xNoneSigId) {
        xWriteBuf_Fmt("/*%c%d*/ Output-None %s",
                      (Signal == XPRS_NEXT_REC_SIG(PrsNode) ? '*' : ' '),
                      count,
                      xWri_SDL_PId(&PrsNode->Self));
#ifndef XNOUSEOFSERVICE
        if (PrsNode->ActiveSrv) {
          PRINTF2(" %s", PrsNode->ActiveSrv->NameNode->Name);
          PRINTF("/* PONTEMP NOT ALWAYS ActiveSrv */\n");
        }
#endif
        PRINTF("\n");
      }
      else {
        xWriteBuf_Fmt("/*%c%d*/ Output-Internal %s",
                      (Signal == XPRS_NEXT_REC_SIG(PrsNode) ? '*' : ' '),
                      count,
                      xWriteEntity((xIdNode)XSIGNAL_IDNODE(Signal)));
#if defined(XSIGPRIO) || defined(XSIGPRSPRIO) || defined(XPRSSIGPRIO)
# ifndef XNOSIGPRIOPROMPT
        PRINTF2(" %d", XCONT_SIG_PRIO(Signal));
# endif
#endif
        xWriteSignalParameters2(Signal, "");
        PRINTF2(" %s", xWri_SDL_PId(&PrsNode->Self));
        PRINTF2(" %s\n", xWri_SDL_PId(&(XSIGNAL_SENDER(Signal))));
      }
    }
  }
}

/*---+---------------------------------------------------------------
     xSaveAllPId
-------------------------------------------------------------------*/
static void xSaveAllPId (xIdNode FromNode)
{
  xIdNode       IdNode;
  xPrsNode      PrsNode;
  xPrsIdNode    PrsIdNode;
  int           count;
#ifndef XNOUSEOFSERVICE
  xSrvNode      SrvNode;
  xSrvIdNode    SrvIdNode;
  int           i;
#endif

  for ( IdNode  = FromNode->First;
        IdNode != (xIdNode)0;
        IdNode  = IdNode->Suc ) {
    if (IdNode->EC == xProcessEC) {
      for (PrsNode = *((xPrsIdNode)IdNode)->ActivePrsList;
           PrsNode != (xPrsNode)0;
           PrsNode = PrsNode->NextPrs) {
        PRINTF("\n");
        PRINTF2("Set-Scope %s\n", xWri_SDL_PId(&(PrsNode->Self)));
        xSaveAllSignals(PrsNode);
#ifndef XNOUSEOFSERVICE
        if (PrsNode->ActiveSrv == (xSrvNode)0) {
#endif
          PRINTF2("xSet Nextstate %d\n", PrsNode->State);
#ifndef XNOUSEOFSERVICE
        }
#endif
        PrsIdNode = PrsNode->NameNode;
        if (PrsIdNode->Super) {
          if (PrsIdNode->PAD_Function != PrsNode->RestartPAD) {
            count = 0;
            while (PrsIdNode->PAD_Function != PrsNode->RestartPAD) {
              count++;
              PrsIdNode = PrsIdNode->Super;
            }
            PRINTF2("xSet RestartPAD %d\n", count);
          }
        }
        PRINTF2("xSet RestartAddress %d\n", PrsNode->RestartAddress);
        if (PrsNode->InTransition) {
          PRINTF2("xSet InTransition %d\n", PrsNode->InTransition);
        }
        if (PrsNode->BlockInstNumber != 1) {
          /* Default is 1 */
          PRINTF2("xSet BlockInstNumber %d\n", PrsNode->BlockInstNumber);
        }
        if (PrsNode->pREPLY_Waited_For) {
          PRINTF2("xSet pREPLY_Waited_For %s\n",
                  xWriteEntity((xIdNode)PrsNode->pREPLY_Waited_For));
        }
        if (PrsNode->pREPLY_Signal) {
          PRINTF2("xSet pREPLY_Signal %s",
                  xWriteEntity((xIdNode)PrsNode->pREPLY_Signal->NameNode));
          xWriteSignalParameters2(PrsNode->pREPLY_Signal, "");
          PRINTF2(" %s",
                  xWri_SDL_PId(&(XSIGNAL_RECEIVER(PrsNode->pREPLY_Signal))));
          PRINTF2(" %s\n",
                  xWri_SDL_PId(&(XSIGNAL_SENDER(PrsNode->pREPLY_Signal))));
        }
        PRINTF2("Assign-Value Parent %s\n",
                xWri_SDL_PId(&XPRS_PARENT(PrsNode)));
        PRINTF2("Assign-Value Offspring %s\n",
                xWri_SDL_PId(&XPRS_OFFSPRING(PrsNode)));
        PRINTF2("Assign-Value Sender %s\n",
                xWri_SDL_PId(&XPRS_SENDER(PrsNode)));
        xPrintAllPrsVariables2((xIdNode)PrsNode->NameNode,
                              (xptrint)PrsNode);

        if (PrsNode->ActivePrd) {
          xSavePrdList(PrsNode->ActivePrd,
#ifndef XNOUSEOFSERVICE
                       (xSrvNode)0,
#endif
                       PrsNode);
        }

#ifndef XNOUSEOFSERVICE
        if (PrsNode->SrvList) {
          PRINTF("\nxSet Services\n");
        }
#endif

#ifndef XNOUSEOFSERVICE
        if (PrsNode->SrvList) {
          SrvIdNode = (xSrvIdNode)(PrsNode->NameNode->Contents[0]);
          i = 1;
          while (SrvIdNode != (xSrvIdNode)0) {
            if (SrvIdNode->EC == xServiceEC) {
              for (SrvNode = PrsNode->SrvList;
                   SrvNode != (xSrvNode)0;
                   SrvNode = SrvNode->NextSrv) {
                if (SrvNode->NameNode == SrvIdNode)
                  break;
              }
              if ( ! SrvNode ) {
                PRINTF3("xSet Stop %s %s\n",
                        xWri_SDL_PId(&(PrsNode->Self)), SrvIdNode->Name);
              }
            }
            SrvIdNode = (xSrvIdNode)(PrsNode->NameNode->Contents[i++]);
          }
        }

        for (SrvNode = PrsNode->SrvList;
             SrvNode != (xSrvNode)0;
             SrvNode = SrvNode->NextSrv) {
          PRINTF3("\nSet-Scope %s %s\n", xWri_SDL_PId(&(PrsNode->Self)),
                  SrvNode->NameNode->Name);
          PRINTF2("xSet Nextstate %d\n", SrvNode->State);
          SrvIdNode = SrvNode->NameNode;
          if (SrvIdNode->Super) {
            if (SrvIdNode->PAD_Function != SrvNode->RestartPAD) {
              count = 0;
              while (SrvIdNode->PAD_Function != SrvNode->RestartPAD) {
                count++;
                SrvIdNode = SrvIdNode->Super;
              }
              PRINTF2("xSet RestartPAD %d\n", count);
            }
          }
          PRINTF2("xSet RestartAddress %d\n", SrvNode->RestartAddress);
          if (SrvNode->InTransition) {
            PRINTF2("xSet InTransition %d\n", SrvNode->InTransition);
          }
          if (SrvNode->pREPLY_Waited_For) {
            PRINTF2("xSet pREPLY_Waited_For %s\n",
                    xWriteEntity((xIdNode)SrvNode->pREPLY_Waited_For));
          }
          if (SrvNode->pREPLY_Signal) {
            PRINTF2("!pREPLY_Signal : %s",
                    xWriteEntity((xIdNode)SrvNode->pREPLY_Signal->NameNode));
            xWriteSignalParameters2(SrvNode->pREPLY_Signal, "");
            PRINTF2(" %s",
                    xWri_SDL_PId(&(XSIGNAL_RECEIVER(SrvNode->pREPLY_Signal))));
            PRINTF2(" %s\n",
                    xWri_SDL_PId(&(XSIGNAL_SENDER(SrvNode->pREPLY_Signal))));
          }
          xPrintAllPrsVariables2((xIdNode)SrvNode->NameNode,
                                 (xptrint)SrvNode);

          if (SrvNode->ActivePrd) {
            xSavePrdList(SrvNode->ActivePrd, SrvNode, PrsNode);
          }
        }
#endif

#ifndef XNOUSEOFSERVICE
        if (PrsNode->SrvList) {
          if (PrsNode->ActiveSrv) {
            PRINTF2("\nxSet ActiveSrv %s\n",
                    xWriteEntity((xIdNode)PrsNode->ActiveSrv->NameNode));
          }
        }
#endif

        if ( ! PrsNode->Signal ) {
          PRINTF("xSet SignalEntry 0\n");
        }
        else if ( ! XIS_STARTUP_SIGNAL(PrsNode->Signal) ) {
          xSignalNode   Signal;
          xbool         StartSigFound = (xbool)0;

          if (XINPUTPORT_EMPTY(PrsNode)) {
            PRINTF("xSet SignalEntry 10001\n");
          }
          else {
            count = 0;
            for (Signal = PrsNode->InputPort.Suc;
                 Signal != (xSignalNode)&PrsNode->InputPort;
                 Signal = Signal->Suc) {
              if (XIS_STARTUP_SIGNAL(Signal)) {
                StartSigFound = (xbool)1;
              }
              if (! XIS_STARTUP_SIGNAL(Signal)) {
                count++;
              }
              if (Signal == PrsNode->Signal)
                break;
            }
            if ( ! StartSigFound ) {
              PRINTF("xSet SignalEntry 20000\n");
            }
            if (Signal != (xSignalNode)&PrsNode->InputPort) {
              PRINTF2("xSet SignalEntry %d\n", count);
            }
            else {
              PRINTF("xSet SignalEntry 10001\n");
            }
          }
        }

      }
    }
  }
  for ( IdNode  = FromNode->First;
        IdNode != (xIdNode)0;
        IdNode  = IdNode->Suc ){
    xSaveAllPId(IdNode);
  }
}

/*---+---------------------------------------------------------------
     xSaveStateCom
-------------------------------------------------------------------*/
static void xSaveStateCom(char * strVar)
{
  int           No;
  xSignalNode   tmpT;
  xPrsNode      tmpPrs;
  FILE        * TempFile;
  xbool         save_NewRef_Syntax;
  xbool         save_DeRef_Syntax;

  if (xSysD.InteractionLog.Active) {
    PRINTF("Interaction Logfile is closed\n");
    if (xSysD.InteractionLog.File)
      if (fclose(xSysD.InteractionLog.File) != 0)
        PRINTF("Error closing Interaction Logfile\n");
  }

  if ( !xGetAndOpenFile(&TempFile, (xbool)0, strVar, "sta") )
    return;

  strcpy(xSysD.InteractionLog.Filename, strVar);
  xSysD.InteractionLog.File = TempFile;
  xSysD.InteractionLog.Active = (xbool)1;

  /* Use REF-Value-Notation */
  save_NewRef_Syntax = xSysD.xUse_NewRef_Syntax;
  save_DeRef_Syntax = xSysD.xUse_DeRef_Syntax;
  xSysD.xUse_NewRef_Syntax = (xbool)1;
  xSysD.xUse_DeRef_Syntax = (xbool)0;

  xSysD.xSavingState = (xbool)1;
  PRINTF2("! System %s\n", xSysD.SystemName);
  xCreateAllPId(xSymbolTableRoot);

  PRINTF2("xSet Now %s\n", xWriteNow(xSysD.NowInMonitor));
  if ( ! XTIMERQ_EMPTY ) {
    No = 0;
    for (tmpT = xSysD.xTimerQueue->Suc;
         tmpT != xSysD.xTimerQueue;
         tmpT = tmpT->Suc) {
      PRINTF2("Set-Scope %s\n", xWri_SDL_PId(&(XTIMER_RECEIVER(tmpT))));
      xWriteBuf_Fmt("/*%d*/ Set-Timer %s",
                    ++No,
                    XTIMER_IDNODE(tmpT)->Name);
      xWriteSignalParameters2(tmpT, "");
      PRINTF2(" %s\n", xWriteNow(((xTimerNode)tmpT)->TimerTime));
    }
  }

  xSaveAllPId(xSymbolTableRoot);
  xStopSomePId(xSymbolTableRoot);

  if ( ! XREADYQ_EMPTY ) {
    PRINTF("\n");
    No = 0;
    for (tmpPrs = xSysD.xReadyQueue->Suc;
         tmpPrs != xSysD.xReadyQueue;
         tmpPrs = tmpPrs->Suc) {
      PRINTF3("xSet ReadyQ %d %s\n", ++No, xWri_SDL_PId(&(tmpPrs->Self)));
    }
  }
  PRINTF("xSet RestoreDone\n");
  xReleasexLoopRefWriteList();
  xSysD.xSavingState = (xbool)0;

  if (fclose(xSysD.InteractionLog.File))
    PRINTF("Error closing State file\n");
  xSysD.InteractionLog.Active = (xbool)0;

  /* Restore REF-Notation */
  xSysD.xUse_NewRef_Syntax = save_NewRef_Syntax;
  xSysD.xUse_DeRef_Syntax = save_DeRef_Syntax;
}

/*---+---------------------------------------------------------------
     xCheckStopAllPId
-------------------------------------------------------------------*/
static xbool xCheckStopAllPId (xIdNode FromNode)
{
  xIdNode       IdNode;

  for ( IdNode  = FromNode->First;
        IdNode != (xIdNode)0;
        IdNode  = IdNode->Suc ) {
    if (IdNode->EC == xProcessEC &&
        *((xPrsIdNode)IdNode)->ActivePrsList) {
      return (xbool)0;
    }
  }
  for ( IdNode  = FromNode->First;
        IdNode != (xIdNode)0;
        IdNode  = IdNode->Suc ){
    if ( ! xCheckStopAllPId(IdNode) )
      return (xbool)0;
  }
  return (xbool)1;
}

/*---+---------------------------------------------------------------
     xStopAllPId
-------------------------------------------------------------------*/
static void xStopAllPId (xIdNode FromNode)
{
  xIdNode       IdNode;
  xPrsNode      PrsNode;
  xPrsNode      NextPrsNode;
#ifndef XPRSOPT
  SDL_PId       OldP;
#endif
#ifndef XNOUSEOFSERVICE
  xSrvNode      SrvNode;
#endif

  for ( IdNode  = FromNode->First;
        IdNode != (xIdNode)0;
        IdNode  = IdNode->Suc ) {
    if (IdNode->EC == xProcessEC) {
      for (PrsNode = *((xPrsIdNode)IdNode)->ActivePrsList;
           PrsNode != (xPrsNode)0;
           PrsNode = NextPrsNode) {
        NextPrsNode = PrsNode->NextPrs;
        if (PrsNode->InTransition || PrsNode->ActivePrd) {
          /* Within transition */
          xSysD.xRestoringState = (xbool)0;
          PRINTF("Stop command on the executing process may not be used\n");
          xSysD.xRestoringState = (xbool)1;
        }
        else {
          if (XPRS_NEXT_REC_SIG(PrsNode) != (xSignalNode)0)
            xRemoveFromQueue((void *)XPRS_NEXT_REC_SIG(PrsNode));
          PRINTF2("%s stopped\n", xWri_SDL_PId(&PrsNode->Self));
#ifndef XPRSOPT
          OldP = PrsNode->Self;
#endif
#ifndef XNOUSEOFSERVICE
          /* PONTEMP SHOULD NOT ALLOW ANY SERVICE IN START STATE */
          if (PrsNode->ActiveSrv) {
            /* first stop all services */
            PrsNode->ActiveSrv = PrsNode->SrvList;
            while (PrsNode->ActiveSrv != (xSrvNode)0) {
              SrvNode = PrsNode->ActiveSrv->NextSrv;
              SDL_Stop(PrsNode);
              if (XPRS_NEXT_REC_SIG(PrsNode) != (xSignalNode)0)
                xRemoveFromQueue((void *)XPRS_NEXT_REC_SIG(PrsNode));
              PrsNode->ActiveSrv = SrvNode;
            }
            /* last services also stopped process */
          }
          else
#endif
            SDL_Stop(PrsNode);
#ifndef XPRSOPT
          xFree((void **)&OldP.LocalPId);
#endif
        }
      }
      ((xPrsIdNode)IdNode)->NextNr = 1;
    }
  }
  for ( IdNode  = FromNode->First;
        IdNode != (xIdNode)0;
        IdNode  = IdNode->Suc ){
    xStopAllPId(IdNode);
  }
}

/*---+---------------------------------------------------------------
     xRestoreStateCom
-------------------------------------------------------------------*/
static void xRestoreStateCom(char * strVar)
{
  xCommandFileNode  tmpCF;
  int           count;
  FILE        * TempFile;

  if ( ! XREADYQ_EMPTY && xSysD.xReadyQueue->Suc->InTransition ) {
    PRINTF("Command not possible when in transition\n");
    return;
  }

  if (xSysD.CommandFile != (xCommandFileNode)0) {
    count = 1;
    for (tmpCF = xSysD.CommandFile->Next;
         tmpCF != (xCommandFileNode)0;
         tmpCF = tmpCF->Next)
      count++;
    if (count >= 5) {
      PRINTF("Too many nested include files, maximum is 5\n");
      return;
    }
  }
  if ( !xGetAndOpenFile(&TempFile, (xbool)1, strVar, "sta") )
    return;

  xSysD.xRestoringState = (xbool)1;
  xStopAllPId(xSymbolTableRoot);
  if ( ! xCheckStopAllPId(xSymbolTableRoot) ) {
    xSysD.xRestoringState = (xbool)0;
    PRINTF("All PId's not stopped, please restart simulation\n");
    fclose(TempFile);
    return;
  }

#ifndef XNOUSEOFSERVICE
  xSysD.xSrvScope = (xSrvNode)0;
#endif
  xSysD.xPrsScope = (xPrsNode)0;
  xSysD.xPrdScope = (xPrdNode)0;

  tmpCF = (xCommandFileNode)xAlloc((xptrint)sizeof( xCommandFileRec ));
  tmpCF->Next = xSysD.CommandFile;
  tmpCF->File = TempFile;
  xSysD.CommandFile = tmpCF;
}


/*---+---------------------------------------------------------------
     xCallProcedure
-------------------------------------------------------------------*/
static void xCallProcedure (void)
{
  xPrdIdNode    ProcedureId;
  xPrdNode      yTempPrd;
  int           RestartAddress;
  xPrsIdNode    ParentId;
  xbool         xEmptyInput;
  xPrsNode      PrsNode;

  ProcedureId = (xPrdIdNode)xGetIdNodeInECSet("Procedure name : ",
         (1L<<((long)xProcedureEC)) | (1L<<((long)xOperatorEC)),
         xSymbolTableRoot, &xEmptyInput, (xbool)0, (xIdNode)0);
  if (ProcedureId == (xPrdIdNode)0)
    return;

  PrsNode = xReadProcess("Parent process name : ", &ParentId, (xIdNode)0);
  if (PrsNode == (xPrsNode)0 && ParentId != xNullId)
    return;

  yTempPrd = xGetPrd(ProcedureId);
#ifndef XNOUSEOFSERVICE
  if (PrsNode->ActiveSrv) {
    PrsNode->ActiveSrv = xSysD.xSrvScope;
    if (PrsNode->ActiveSrv->ActivePrd) {
      RestartAddress = PrsNode->ActiveSrv->ActivePrd->RestartAddress;
    } else {
      RestartAddress = PrsNode->ActiveSrv->RestartAddress;
    }
  } else {
#endif
    if (PrsNode->ActivePrd) {
      RestartAddress = PrsNode->ActivePrd->RestartAddress;
    } else {
      RestartAddress = PrsNode->RestartAddress;
    }
#ifndef XNOUSEOFSERVICE
  }
#endif
  xAddPrdCall(yTempPrd, PrsNode, -1, RestartAddress);
  xChangeScope(PrsNode);
  xDownCom();
}


/*---+---------------------------------------------------------------
     xReadPrdInstance
-------------------------------------------------------------------*/
xPrdNode xReadPrdInstance(char * strVar)
{
  xbool         xEmptyInput;
  xxToken       Token;
  xPrdIdNode    ProcedureId;
  xPrdNode      PrdNode;
  int           intVar;
  int           count;

  ProcedureId = (xPrdIdNode)xGetIdNodeInECSet("Procedure name : ",
         (1L<<((long)xProcedureEC)) | (1L<<((long)xOperatorEC)),
         xSymbolTableRoot, &xEmptyInput, (xbool)0, (xIdNode)0);
  if (ProcedureId == (xPrdIdNode)0)
    return NULL;

  Token = xScanToken(strVar);
  if (Token != xxColon) {
    PRINTF("Procedure instance number missing (no colon)\n");
    return NULL;
  }
  if ( ! xReadInstanceNumber("Instance number : ", &intVar, &xEmptyInput) ) {
    PRINTF("Procedure instance number missing\n");
    return NULL;
  }

  if (xEmptyInput) {
    PRINTF("Procedure instance number missing\n");
    return NULL;
  }

  count = 0;
  for (PrdNode = XSYSD xPrdScope;
       PrdNode;
       PrdNode = PrdNode->DynamicFather) {
    if (PrdNode->NameNode == ProcedureId)
      count++;
  }

  if (intVar > count) {
    PRINTF("Procedure instance number too large\n");
    return NULL;
  }

  count = count - intVar;
  for (PrdNode = XSYSD xPrdScope;
       PrdNode;
       PrdNode = PrdNode->DynamicFather) {
    if (PrdNode->NameNode == ProcedureId) {
      count--;
      if (count < 0)
        break;
    }
  }
  return PrdNode;
}

/*---+---------------------------------------------------------------
     xSetAddress
-------------------------------------------------------------------*/
static void xSetAddress (char * strVar)
{
  xVarIdNode    xIdNodeVariable;
  xbool         xEmptyInput;
  xptrint       VarPointer;
  xptrint       AreaAddress;
  xxToken       Token;
  xPrsIdNode    ProcessId;
  xPrsNode      PrsNode;
  xPrdNode      PrdNode;
  xptrint       Offset;
  XSIGTYPE      SignalId;

  if (! XSYSD xPrdScope ) {
    PRINTF("Must be in a procedure\n");
    return;
  }

  Token = xReadVariable("Variable name : ", strVar, &xEmptyInput, (xbool)0);
  if (Token != xxId) {
    PRINTF("Illegal variable name\n");
    return;
  }

  if (*xInputPos == '!') {
    /* Handle procedureresult! */
    strcat(strVar, "!");
    xInputPos++;
  }

  if ( ! xVariableInProcess(strVar, &xIdNodeVariable, &VarPointer) )
    return;

  if (xIdNodeVariable->EC != xFormalParEC ||
      ! (XIS_ADDRESS(xIdNodeVariable) ||
         IsOwnInOutPar(xIdNodeVariable))) {
    PRINTF("Illegal variable\n");
    return;
  }

  Token = xPromptQuestionMark("Entity : ", "Entity : ", strVar);
  if (Token == xxProcess) {
    PrsNode = xReadProcess(" (PId) : ", &ProcessId, (xIdNode)0);
    if ( ! PrsNode ) {
      return;
    }
    AreaAddress = (xptrint)PrsNode;
  }
  else if (Token == xxProcedure) {
    PrdNode = xReadPrdInstance(strVar);
    if ( ! PrdNode ) {
      return;
    }
    AreaAddress = (xptrint)PrdNode;
  }
#ifndef XNOUSEOFSERVICE
  else if (Token == xxService) {
    AreaAddress = (xptrint)xSysD.xSrvScope;
  }
#endif
  else if (Token == xxId && ! strcmp(strVar, "Signal") ) {
    if ( ! xSysD.xPrsScope || ! xSysD.xPrsScope->pREPLY_Signal ) {
      return;
    }

    SignalId = (xSignalIdNode)xGetIdNodeInECSet("Signal name : ",
         1L<<((long)xRPCSignalEC), xSymbolTableRoot,
         &xEmptyInput, (xbool)0, (xIdNode)0);
    if (SignalId == (xSignalIdNode)0)
      return;

    if (xSysD.xPrsScope->pREPLY_Signal->NameNode != SignalId) {
      PRINTF2("Wrong signal %s\n", SignalId->Name);
      return;
    }

    AreaAddress = (xptrint)(xSysD.xPrsScope->pREPLY_Signal);
  }
#ifndef XNOUSEOFSERVICE
  else if (Token == xxId && ! strcmp(strVar, "ServiceSignal") ) {
    if ( ! xSysD.xSrvScope || ! xSysD.xSrvScope->pREPLY_Signal ) {
      return;
    }

    SignalId = (xSignalIdNode)xGetIdNodeInECSet("Signal name : ",
         1L<<((long)xRPCSignalEC), xSymbolTableRoot,
         &xEmptyInput, (xbool)0, (xIdNode)0);
    if (SignalId == (xSignalIdNode)0)
      return;

    if (xSysD.xSrvScope->pREPLY_Signal->NameNode != SignalId) {
      PRINTF2("Wrong signal %s\n", SignalId->Name);
      return;
    }

    AreaAddress = (xptrint)(xSysD.xSrvScope->pREPLY_Signal);
  }
#endif
  else if (Token == xxId && ! strcmp(strVar, "ProcedureSignal") ) {
    PrdNode = xReadPrdInstance(strVar);
    if ( ! PrdNode || ! PrdNode->pREPLY_Signal ) {
      return;
    }

    SignalId = (xSignalIdNode)xGetIdNodeInECSet("Signal name : ",
         1L<<((long)xRPCSignalEC), xSymbolTableRoot,
         &xEmptyInput, (xbool)0, (xIdNode)0);
    if (SignalId == (xSignalIdNode)0)
      return;

    if (PrdNode->pREPLY_Signal->NameNode != SignalId) {
      PRINTF2("Wrong signal %s\n", SignalId->Name);
      return;
    }

    AreaAddress = (xptrint)(PrdNode->pREPLY_Signal);
  }
  else {
    return;
  }

  Token = xPromptQuestionMark("Offset : ", "Offset : ", strVar);
  if (Token != xxId || ! sscanf(strVar, "%x", &Offset) ) {
    return;
  }

  if (IsOwnInOutPar(xIdNodeVariable)) {
    *(xptrint *)((xptrint)(XSYSD xPrdScope) + xIdNodeVariable->Offset +
                 xIdNodeVariable->TypeNode->SortSize) =
      AreaAddress + Offset;
  }
  else {
    *(xptrint *)((xptrint)(XSYSD xPrdScope) + xIdNodeVariable->Offset) =
      AreaAddress + Offset;
  }
}

static xbool xReadTime(char *Prompt, SDL_Time *timeVar);

/*---+---------------------------------------------------------------
     xSetCom
-------------------------------------------------------------------*/
static void xSetCom (char * strVar)
{
  xxToken       Token;
  int           Value;
  SDL_Time      timeVar;
  xPrdNode      PrdNode;
  xPrsNode      PrsNode;
  XSIGTYPE      SignalId;
  xPrsIdNode    ProcessId;
  xSignalNode   Signal;
  xbool         xEmptyInput;

  Token = xPromptQuestionMark("Choose : ",
                              "ActiveSrv "
                              "Address "
                              "BlockInstNumber "
                              "Call-Procedure "
                              "ContSignal "
                              "ExportedValue "
                              "InTransition "
                              "Nextstate "
                              "Now "
                              "pREPLY_Signal "
                              "pREPLY_Waited_For "
                              "ReadyQ "
                              "RestartPAD "
                              "RestartPRD "
                              "RestartAddress "
                              "RestoreDone "
                              "Services "
                              "SignalEntry "
                              "StartUpSignalPar "
                              "StaticFather "
                              "Stop "
                              "SyntVariable "
                              ": ",
                              strVar);
  if (Token != xxId) {
    PRINTF("Illegal choice\n");
    return;
  }
  if ( ! strcmp(strVar, "BlockInstNumber") ) {
    Token = xPromptQuestionMark("Value : ", "Value : ", strVar);
    if (Token != xxId || ! sscanf(strVar, "%d", &Value) ) {
      return;
    }
    (XSYSD xPrsScope)->BlockInstNumber = Value;
  }
  else if ( ! strcmp(strVar, "Address") ) {
    xSetAddress(strVar);
  }
  else if ( ! strcmp(strVar, "Call-Procedure") ) {
    xCallProcedure();
  }
  else if ( ! strcmp(strVar, "ExportedValue") ) {
    xptrint       VarPointer;
    xVarIdNode    xIdNodeVariable;

    Token = xReadVariable("Variable name : ", strVar, &xEmptyInput, (xbool)0);
    if (Token != xxId) {
      PRINTF("Illegal variable name\n");
      return;
    }
    if ( ! xVariableInProcess(strVar, &xIdNodeVariable, &VarPointer) )
      return;

    if ( ! (xIdNodeVariable->EC == xVariableEC && xIdNodeVariable->Offset2) ) {
      PRINTF("Illegal variable\n");
      return;
    }

    /* Fix VarPointer to point at exported value */
    VarPointer = VarPointer - xIdNodeVariable->Offset + xIdNodeVariable->Offset2;
    xAssignVariable(xIdNodeVariable->TypeNode, VarPointer);
  }
  else if ( ! strcmp(strVar, "RestoreDone") ) {
    xReleasexRefReadList();
    xSysD.xRestoringState = (xbool)0;
  }
  else if ( ! strcmp(strVar, "SyntVariable") ) {
    xVarIdNode    VarId;
    xptrint       VarPointer;
    int           count;
#ifndef XNOUSEOFSERVICE
    xSrvIdNode    ServiceId;
#endif
    xPrdIdNode    PrdId;

    Token = xPromptQuestionMark("Number : ", "Number : ", strVar);
    if (Token != xxId || ! sscanf(strVar, "%d", &Value) ) {
      return;
    }

    if (xSysD.xPrdScope) {
      count = 0;
      for (VarId = (xVarIdNode)xSysD.xPrdScope->NameNode->First;
           VarId != (xVarIdNode)0;
           VarId = (xVarIdNode)VarId->Suc) {
        if (VarId->EC == xSyntVariableEC) {
          count++;
          if (count == Value) {
            VarPointer = (xptrint)xSysD.xPrdScope + VarId->Offset;
            xAssignVariable(VarId->TypeNode, VarPointer);
            return;
          }
        }
      }
      for (PrdId = xSysD.xPrdScope->NameNode->Super;
           PrdId != (xPrdIdNode)0;
           PrdId = PrdId->Super) {
        for (VarId = (xVarIdNode)PrdId->First;
             VarId != (xVarIdNode)0;
             VarId = (xVarIdNode)VarId->Suc) {
          if (VarId->EC == xSyntVariableEC) {
            count++;
            if (count == Value) {
              VarPointer = (xptrint)xSysD.xPrdScope + VarId->Offset;
              xAssignVariable(VarId->TypeNode, VarPointer);
              return;
            }
          }
        }
      }
    }
#ifndef XNOUSEOFSERVICE
    else if (xSysD.xSrvScope) {
      count = 0;
      for ( ServiceId = xSysD.xSrvScope->NameNode;
            ServiceId != (xSrvIdNode)0;
            ServiceId = ServiceId->Super) {
        for ( VarId = (xVarIdNode)ServiceId->First;
              VarId != (xVarIdNode)0;
              VarId = (xVarIdNode)VarId->Suc ) {
          if (VarId->EC == xSyntVariableEC) {
            count++;
            if (count == Value) {
              VarPointer = (xptrint)xSysD.xSrvScope + VarId->Offset;
              xAssignVariable(VarId->TypeNode, VarPointer);
              return;
            }
          }
        }
      }
    }
#endif
    else {
      count = 0;
      for ( ProcessId = xSysD.xPrsScope->NameNode;
            ProcessId != (xPrsIdNode)0;
            ProcessId = ProcessId->Super) {
        for ( VarId = (xVarIdNode)ProcessId->First;
              VarId != (xVarIdNode)0;
              VarId = (xVarIdNode)VarId->Suc ) {
          if (VarId->EC == xSyntVariableEC) {
            count++;
            if (count == Value) {
              VarPointer = (xptrint)xSysD.xPrsScope + VarId->Offset;
              xAssignVariable(VarId->TypeNode, VarPointer);
              return;
            }
          }
        }
      }
    }
  }
  else if ( ! strcmp(strVar, "ReadyQ") ) {
    int           No;
    xPrsNode      tmpPrs;

    Token = xPromptQuestionMark("Value : ", "Value : ", strVar);
    if (Token != xxId || ! sscanf(strVar, "%d", &Value) ) {
      return;
    }
    PrsNode = xReadProcess("Process : ", &ProcessId, (xIdNode)0);
    if ( ! PrsNode )
      return;
    No = 0;
    for (tmpPrs = xSysD.xReadyQueue->Suc;
         tmpPrs != xSysD.xReadyQueue;
         tmpPrs = tmpPrs->Suc) {
      No++;
      if (No == Value) {
        if (PrsNode != tmpPrs) {
          /* Must rearrange the Ready Queue */
          /* PONTEMP ASSUME PrsNode in RQ - ERROR*/
          if (PrsNode->Suc) {
            PrsNode->Suc->Pre = PrsNode->Pre;
            PrsNode->Pre->Suc = PrsNode->Suc;
          }
          PrsNode->Suc = tmpPrs;
          PrsNode->Pre = tmpPrs->Pre;
          PrsNode->Suc->Pre = PrsNode;
          PrsNode->Pre->Suc = PrsNode;
        }
        return;
      }
    }
    PRINTF("PONTEMP Add process LAST to Ready Queue\n");
    tmpPrs = xSysD.xReadyQueue->Pre;
    PrsNode->Pre = tmpPrs;
    PrsNode->Suc = tmpPrs->Suc;
    tmpPrs->Suc->Pre = PrsNode;
    tmpPrs->Suc = PrsNode;
  }
  else if ( ! strcmp(strVar, "ContSignal") ) {
    xSignalNode  ToInsertAfter;
    xSignalNode  S;

    Token = xPromptQuestionMark("Value : ", "Value : ", strVar);
    if (Token != xxId || ! sscanf(strVar, "%d", &Value) ) {
      return;
    }
    S = xGetSignal(xContSigId, xSysD.xPrsScope->Self,
                   xSysD.xPrsScope->Self);
    S->Prio = Value;
    /* PONTEMP Always put LAST  first in InputPort ??? */
    /* xInsertIntoInputPort(xSysD.xPrsScope, xSysD.xPrsScope->Signal); */
    ToInsertAfter = xSysD.xPrsScope->InputPort.Pre;
    S->Pre = ToInsertAfter;
    S->Suc = ToInsertAfter->Suc;
    ToInsertAfter->Suc->Pre = S;
    ToInsertAfter->Suc = S;
  }
  else if ( ! strcmp(strVar, "ActiveSrv") ) {
#ifndef XNOUSEOFSERVICE
    xSrvIdNode    ServiceId;

    if (xSysD.xPrsScope) {
      xSysD.xPrsScope->ActiveSrv = xReadService("Service : ", &ServiceId,
                                                xSysD.xPrsScope, &xEmptyInput);
    }
#endif
  }
  else if ( ! strcmp(strVar, "RestartAddress") ) {
    Token = xPromptQuestionMark("Value : ", "Value : ", strVar);
    if (Token != xxId || ! sscanf(strVar, "%d", &Value) ) {
      return;
    }
    if (XSYSD xPrdScope)
      (XSYSD xPrdScope)->RestartAddress = Value;
#ifndef XNOUSEOFSERVICE
    else if (XSYSD xSrvScope)
      (XSYSD xSrvScope)->RestartAddress = Value;
#endif
    else
      (XSYSD xPrsScope)->RestartAddress = Value;
  }
  else if ( ! strcmp(strVar, "RestartPAD") ) {
    Token = xPromptQuestionMark("Value : ", "Value : ", strVar);
    if (Token != xxId || ! sscanf(strVar, "%d", &Value) ) {
      return;
    }
#ifndef XNOUSEOFSERVICE
    if (xSysD.xSrvScope) {
      xSrvIdNode    SrvId;

      SrvId = xSysD.xSrvScope->NameNode;
      while (Value > 0) {
        SrvId = SrvId->Super;
        Value--;
      }
      xSysD.xSrvScope->RestartPAD = SrvId->PAD_Function;
    }
    else
#endif
    if (xSysD.xPrsScope) {
      xPrsIdNode    PrsId;

      PrsId = xSysD.xPrsScope->NameNode;
      while (Value > 0) {
        PrsId = PrsId->Super;
        Value--;
      }
      xSysD.xPrsScope->RestartPAD = PrsId->PAD_Function;
    }
  }
  else if ( ! strcmp(strVar, "RestartPRD") ) {
    Token = xPromptQuestionMark("Value : ", "Value : ", strVar);
    if (Token != xxId || ! sscanf(strVar, "%d", &Value) ) {
      return;
    }
    if (xSysD.xPrdScope) {
      xPrdIdNode    PrdId;

      PrdId = xSysD.xPrdScope->NameNode;
      while (Value > 0) {
        PrdId = PrdId->Super;
        Value--;
      }
      xSysD.xPrdScope->RestartPRD = PrdId->Assoc_Function;
    }
  }
  else if ( ! strcmp(strVar, "InTransition") ) {
    Token = xPromptQuestionMark("Value : ", "Value : ", strVar);
    if (Token != xxId || ! sscanf(strVar, "%d", &Value) ) {
      return;
    }
    if (Value && (XSYSD xPrsScope)->Signal)    /* PONTEMP */
      /* Probably not needed - Removed when SignalEntry negative */
      xRemoveFromQueue((void *)(XSYSD xPrsScope)->Signal);
#ifndef XNOUSEOFSERVICE
    if (XSYSD xSrvScope)
      (XSYSD xSrvScope)->InTransition = (xbool)Value;
    else
#endif
      (XSYSD xPrsScope)->InTransition = (xbool)Value;
  }
  else if ( ! strcmp(strVar, "Nextstate") ) {
    Token = xPromptQuestionMark("Statenumber : ", "Statenumber : ", strVar);
    if (Token != xxId || ! sscanf(strVar, "%d", &Value) ) {
      return;
    }
    if (xSysD.xPrdScope)
      xSysD.xPrdScope->State = Value;
#ifndef XNOUSEOFSERVICE
    else if (xSysD.xSrvScope)
      xSysD.xSrvScope->State = Value;
#endif
    else {
      xSysD.xPrsScope->State = Value;
    }
  }
  else if ( ! strcmp(strVar, "Now") ) {
#ifndef XCALENDARCLOCK
    if ( ! xReadTime("Time : ", &timeVar))
      return;

#ifdef XCLOCK
    xSysD.xStartTime = xMinus_SDL_Duration(SDL_Clock(), timeVar);
    xSysD.xTimeInMonitor = SDL_Duration_Lit( (xint32)0, (xint32)0 );
#else
    xSysD.xSystemTime = timeVar;
#endif
    xSysD.NowInMonitor = SDL_Now();
#endif
  }
  else if ( ! strcmp(strVar, "pREPLY_Signal") ) {
    xReadSignal(&SignalId, &Signal, (xIdNode)0);
    PrsNode = xReadProcess("To Process : ", &ProcessId, (xIdNode)0);
    if ( ! Signal || ! PrsNode )
      return;
    Signal->Receiver = PrsNode->Self;
    PrsNode = xReadProcess("From Process : ", &ProcessId, (xIdNode)0);
    if ( ! PrsNode )
      return;
    Signal->Sender = PrsNode->Self;
    if (XSYSD xPrdScope)
      (XSYSD xPrdScope)->pREPLY_Signal = Signal;
#ifndef XNOUSEOFSERVICE
    else if (XSYSD xSrvScope)
      (XSYSD xSrvScope)->pREPLY_Signal = Signal;
#endif
    else
      (XSYSD xPrsScope)->pREPLY_Signal = Signal;
  }
  else if ( ! strcmp(strVar, "pREPLY_Waited_For") ) {
    SignalId = (xSignalIdNode)xGetIdNodeInECSet("Signal name : ",
         1L<<((long)xRPCSignalEC), xSymbolTableRoot,
         &xEmptyInput, (xbool)0, (xIdNode)0);
#ifndef XNOUSEOFSERVICE
    if (XSYSD xSrvScope) {
      (XSYSD xSrvScope)->pREPLY_Waited_For = SignalId;
    }
    else {
#endif
      (XSYSD xPrsScope)->pREPLY_Waited_For = SignalId;
#ifndef XNOUSEOFSERVICE
    }
#endif
  }
  else if ( ! strcmp(strVar, "SignalEntry") ) {
    int           count;
    xbool         removeIP = (xbool)0;
    xSignalNode   StartupSignal = (xSignalNode)0;

    Token = xPromptQuestionMark("Value : ", "Value : ", strVar);
    if (Token != xxId || ! sscanf(strVar, "%d", &Value) ) {
      return;
    }
    /* Value == 0 remove Signal */
    if (Value == 0) {
      if (xSysD.xPrsScope->Signal) {
        xRemoveFromQueue((void *)xSysD.xPrsScope->Signal);
        xReleaseSignalNotPara(&xSysD.xPrsScope->Signal);
        xRemoveFromQueue((void *)xSysD.xPrsScope);
      }
      return;
    }
    /* Value == 20000 remove STARTUPSignal from in inputport */
    if (Value == 20000) {
      for (Signal = xSysD.xPrsScope->InputPort.Suc;
           Signal != (xSignalNode)&xSysD.xPrsScope->InputPort;
           Signal = Signal->Suc) {
        if (XIS_STARTUP_SIGNAL(Signal)) {
          if (Signal == xSysD.xPrsScope->Signal) {
            xSysD.xPrsScope->Signal = (xSignalNode)0;
          }
          xRemoveFromQueue((void *)Signal);
          xReleaseSignalNotPara(&Signal);
          return;
        }
      }
    }
    /* Value > 10000 remove Signal from in inputport */
    if (Value > 10000) {
      Value = Value - 10000;
      removeIP = (xbool)1;
    }
    /* Value > 0 set Signal to entry in inputport */
    count = 0;
    for (Signal = xSysD.xPrsScope->InputPort.Suc;
         Signal != (xSignalNode)&xSysD.xPrsScope->InputPort;
         Signal = Signal->Suc) {
      if (! XIS_STARTUP_SIGNAL(Signal)) {
        count++;
      }
      else {
        StartupSignal = Signal;
      }
      if (count == Value) {
        if (xSysD.xPrsScope->Signal) {
          xRemoveFromQueue((void *)xSysD.xPrsScope->Signal);
          xReleaseSignalNotPara(&xSysD.xPrsScope->Signal);
        }
        xSysD.xPrsScope->Signal = Signal;
        if (removeIP) {
          xRemoveFromQueue((void *)Signal);
        }
        if (StartupSignal) {
          xRemoveFromQueue((void *)StartupSignal);
        }
        return;
      }
    }
  }
#ifndef XNOUSEOFSERVICE
  else if ( ! strcmp(strVar, "Services") ) {
    if (xSysD.xPrsScope->Signal) {
      xRemoveFromQueue((void *)(XSYSD xPrsScope)->Signal);
    }
    xStart_Services(XSYSD xPrsScope);
  }
#endif
  else if ( ! strcmp(strVar, "StaticFather") ) {
    PrdNode = xReadPrdInstance(strVar);
    if (PrdNode && XSYSD xPrdScope)
      (XSYSD xPrdScope)->StaticFather = PrdNode;
  }
  else if ( ! strcmp(strVar, "StartUpSignalPar") ) {
    if (xSysD.xPrsScope->Signal &&
        XIS_STARTUP_SIGNAL(xSysD.xPrsScope->Signal)) {
      (void)xReadFPars(xSysD.xPrsScope->NameNode,
                       &xSysD.xPrsScope->Signal, strVar);
    }
  }
#ifndef XNOUSEOFSERVICE
  else if ( ! strcmp(strVar, "Stop") ) {
    xSrvIdNode    ServiceId;
    xSrvNode      SrvNode;

    PrsNode = xReadProcess("Process : ", &ProcessId, (xIdNode)0);
    if ( ! PrsNode )
      return;

    SrvNode = xReadService("Service : ", &ServiceId,
                           PrsNode, &xEmptyInput);
    if ( ! SrvNode )
      return;

    xReleaseService(&SrvNode);
  }
#endif
  else {
    PRINTF("Illegal choice\n");
  }
}


/*---+---------------------------------------------------------------
     xCreateCom
-------------------------------------------------------------------*/
static void xCreateCom (void)
{
  xPrsIdNode    ProcessId;
  xPrsIdNode    ParentId;
  XSIGTYPE      SignalId;
  xbool         xEmptyInput;
  xPrsNode      PrsNode;
  xPrsNode      tmpPrs;
  xSignalNode   Signal;
  int           count;

  ProcessId = (xPrsIdNode)xGetIdNodeInECSet("Process name : ",
         1L<<((long)xProcessEC), xSymbolTableRoot,
         &xEmptyInput, (xbool)0, (xIdNode)0);
  if (ProcessId == (xPrsIdNode)0)
    return;
  PrsNode = xReadProcess("Parent process name : ", &ParentId, (xIdNode)0);
  if (PrsNode == (xPrsNode)0 && ParentId != xNullId)
    return;
  count = 0;
  for (tmpPrs = *ProcessId->ActivePrsList;
       tmpPrs != (xPrsNode)0;
       tmpPrs = tmpPrs->NextPrs)
    count++;
  if (ProcessId->MaxNoOfInst != -1 &&  /* not infinity */
      count >= ProcessId->MaxNoOfInst) {
    if ( ! xVerify("Attempt to create more than the max number of \
concurrent instances.\nDo you still want to create the instance : ")
         ) { 
      xPrintString("No process created\n");
      return;
    }
  }
#ifndef XNO_MONITOR_CHANGES
  if (ProcessId->Super == (xPrsIdNode)0) {
    SignalId = (XSIGTYPE)ProcessId->Suc;
  } else {
    SignalId = (XSIGTYPE)ProcessId->Super->Suc;
  }

  if (! xReadSignalParameters(SignalId, &Signal, SDL_NULL) ) {
    XRELEASE_SIGNAL(Signal);
    return;
  }

  if (ParentId != xNullId)
    Signal->Sender = PrsNode->Self;
#ifdef XTRACE
  xSysD.xSilent++;
#endif
  xSysD.xMonitorCreate = (xbool)1;   /* Do not check max number of instances */
  if (ParentId != xNullId)
    SDL_Create(Signal, ProcessId, PrsNode->BlockInstNumber);
  else
    SDL_Create(Signal, ProcessId, 1);
  if (ProcessId == xEnvId && xSysD.xRestoringState && count == 0) {
    xEnv = XSIGNAL_RECEIVER(Signal);
  }
  xSysD.xMonitorCreate = (xbool)0;
#ifdef XTRACE
  xSysD.xSilent--;
#endif
  PRINTF2("Process instance %s created\n",
          xWri_SDL_PId(&XSIGNAL_RECEIVER(Signal)));
  xChangeScope(XPID_TO_PRS(XSIGNAL_RECEIVER(Signal)));
#else
  xPrintString("Create not implemented\n");
#endif
}


/*---+---------------------------------------------------------------
     xNextStateCom
-------------------------------------------------------------------*/
static void xNextStateCom (void)
{
  xPrsNode      PrsNode;
  xIdNode       xIdNodeProcess;
  xStateIdNode  StateId;
  xbool         xEmptyInput;

  if (xSysD.xPrsScope == (xPrsNode)0) {
    xPrintScope((xbool)1);
    return;
  }
  PrsNode = xSysD.xPrsScope;
#ifndef XNOUSEOFSERVICE
  if (xSysD.xSrvScope != (xSrvNode)0) {
    if (xSysD.xSrvScope->InTransition) {   /* Within transition */
      xPrintString(
               "Nextstate command on the executing service may not be used\n");
      return;
    }
    if (xSysD.xSrvScope->State == START_STATE) {   /* In start state */
      xPrintString(
               "Nextstate command on service in START state may not be used\n");
      return;
    }
  } else
#endif
    if (PrsNode->InTransition) {   /* Within transition */
      xPrintString(
             "Nextstate command on the executing process may not be used\n");
      return;
    }
#ifndef XNOUSEOFSERVICE
  if (xSysD.xSrvScope != (xSrvNode)0) {
    if (xSysD.xSrvScope->ActivePrd != (xPrdNode)0)
      xIdNodeProcess = (xIdNode)xSysD.xSrvScope->ActivePrd->NameNode;
    else
      xIdNodeProcess = (xIdNode)xSysD.xSrvScope->NameNode;
  } else
#endif
    if (PrsNode->ActivePrd != (xPrdNode)0)
      xIdNodeProcess = (xIdNode)PrsNode->ActivePrd->NameNode;
    else
      xIdNodeProcess = (xIdNode)PrsNode->NameNode;

  StateId = (xStateIdNode)xGetIdNodeInECSet("State name : ",
        1L<<((long)xStateEC), xIdNodeProcess, &xEmptyInput,
        (xbool)1, xIdNodeProcess);
  if (xEmptyInput) {
#ifndef XNOUSEOFSERVICE
    if (xSysD.xSrvScope != (xSrvNode)0) {
      if ( xSysD.xSrvScope->ActivePrd != (xPrdNode)0 )
        StateId = xGetState(PrsNode, xSysD.xSrvScope->ActivePrd,
                            xSysD.xSrvScope->ActivePrd->NameNode->StateList,
                            xSysD.xSrvScope->ActivePrd->State);
      else
        StateId = xGetState(PrsNode, (xPrdNode)0,
                            xSysD.xSrvScope->NameNode->StateList,
                            XPRS_STATEID(xSysD.xSrvScope));
    } else
#endif
      if ( PrsNode->ActivePrd != (xPrdNode)0 )
        StateId = xGetState(PrsNode, PrsNode->ActivePrd,
                            PrsNode->ActivePrd->NameNode->StateList,
                            PrsNode->ActivePrd->State);
      else
        StateId = xGetState(PrsNode, (xPrdNode)0, PrsNode->NameNode->StateList,
                            XPRS_STATEID(PrsNode));
  }
  if (StateId == (xStateIdNode)0)
    return;
  if (StateId->Parent != xIdNodeProcess &&
#ifndef XNOUSEOFSERVICE
      (xIdNodeProcess->EC != xServiceEC ||
       StateId->Parent != (xIdNode)((xSrvIdNode)xIdNodeProcess)->Super) &&
#endif
      (xIdNodeProcess->EC != xProcessEC ||
       StateId->Parent != (xIdNode)((xPrsIdNode)xIdNodeProcess)->Super) ) {
    xPrintString("Only states in active procedure/process may be used\n");
    return;
  }
#ifndef XNO_MONITOR_CHANGES
  if (XPRS_NEXT_REC_SIG(PrsNode) != (xSignalNode)0)
    if (XSIGNAL_IDNODE(XPRS_NEXT_REC_SIG(PrsNode)) == xContSigId) {
      /* Remove the continuous signal */
/* ERROR: only if continuous signal to this service! */
      xRemoveFromQueue((void *)XPRS_NEXT_REC_SIG(PrsNode));
      XRELEASE_SIGNAL(XPRS_NEXT_REC_SIG(PrsNode));
    }
  XPRS_NEXT_REC_SIG(PrsNode) = (xSignalNode)0;
#ifdef XTRACE
  xSysD.xSilent++;
#endif
#ifndef XNOUSEOFSERVICE
  if (xSysD.xSrvScope != (xSrvNode)0) {
    if (xSysD.xSrvScope == PrsNode->ActiveSrv)
      SDL_NextState(PrsNode, StateId->StateNumber);
    else
      xSysD.xSrvScope->State = StateId->StateNumber;
  } else
#endif
    SDL_NextState(PrsNode, StateId->StateNumber);
#ifdef XTRACE
  xSysD.xSilent--;
#endif
#ifndef XNOUSEOFSERVICE
  if (xSysD.xSrvScope != (xSrvNode)0) {
    PRINTF4("Nextstate %s for service %s in process %s\n",
            StateId->Name, xSysD.xSrvScope->NameNode->Name,
            xWri_SDL_PId(&PrsNode->Self));
  } else {
#endif
    PRINTF3("Nextstate %s for process %s\n",
            StateId->Name, xWri_SDL_PId(&PrsNode->Self));
#ifndef XNOUSEOFSERVICE
  }
#endif
#else
  xPrintString("Nextstate not implemented\n");
#endif
}


/*---+---------------------------------------------------------------
     xStopCom
-------------------------------------------------------------------*/
static void xStopCom (void)
{
  xPrsIdNode    ProcessId;
  xPrsNode      PrsNode;
#ifndef XNOUSEOFSERVICE
  xSrvNode      SrvNode = (xSrvNode)0;
  xSrvNode      SrvNode1;
  xSrvIdNode    ServiceId;
  xbool         xEmptyInput = (xbool)0;
#endif
  xbool         Found;

  PrsNode = xReadProcess("Process name : ", &ProcessId, (xIdNode)0);
  if (PrsNode == (xPrsNode)0) {
    xPrintString("No process\n");
    return;
  }
#ifndef XNO_MONITOR_CHANGES
#ifndef XNOUSEOFSERVICE
  if (PrsNode->ActiveSrv != (xSrvNode)0) {
    SrvNode = xReadService("Service : ", &ServiceId,
                           PrsNode, &xEmptyInput);
    if (ServiceId != (xSrvIdNode)0 && SrvNode == (xSrvNode)0) {
      xPrintString("Service is stopped\n");
      return;
    }

    Found = (xbool)0;
    for (SrvNode1=PrsNode->SrvList;
         SrvNode1!=(xSrvNode)0;
         SrvNode1=SrvNode1->NextSrv) {
      if (SrvNode1->State == START_STATE &&
          SrvNode1->pREPLY_Waited_For == (XSIGTYPE)0) {
        Found = (xbool)1;
        xPrintString("Cannot stop a service if any service in the process is in start state\n");
        break;
      }
    }
    if (Found) return;

    if (xEmptyInput) {
      Found = (xbool)0;
      for (SrvNode1=PrsNode->SrvList;
           SrvNode1!=(xSrvNode)0;
           SrvNode1=SrvNode1->NextSrv) {
        if (SrvNode1->InTransition || SrvNode1->ActivePrd != (xPrdNode)0) {
          Found = (xbool)1;
          PRINTF2("Stop command on process may not be used as service %s is currently executing\n",
                  SrvNode1->NameNode->Name);
          break;
        }
      }
      if (Found) return;
    } else {
      if (SrvNode->InTransition || SrvNode->ActivePrd != (xPrdNode)0) {
        /* Within transition */
        xPrintString("Stop command on the executing service may not be used\n");
        return;
      }
    }
  } else {
#endif
    if (PrsNode->InTransition || PrsNode->ActivePrd != (xPrdNode)0) {
      /* Within transition */
      xPrintString("Stop command on the executing process may not be used\n");
      return;
    }
#ifndef XNOUSEOFSERVICE
  }
#endif
#ifndef XNOUSEOFSERVICE
  if (PrsNode->ActiveSrv == (xSrvNode)0 || xEmptyInput)
    /* only if process is to be stopped */
#endif
    if (XPRS_NEXT_REC_SIG(PrsNode) != (xSignalNode)0)
      xRemoveFromQueue((void *)XPRS_NEXT_REC_SIG(PrsNode));
#ifdef XTRACE
  xSysD.xSilent++;
#endif
#ifndef XNOUSEOFSERVICE
  if (PrsNode->ActiveSrv != (xSrvNode)0 && !xEmptyInput) {
    /* only if service is to be stopped */
    PRINTF2("Service %s in process ", SrvNode->NameNode->Name);
  }
#endif
  PRINTF2("%s stopped\n", xWri_SDL_PId(&PrsNode->Self));
  Found = (xSysD.xPrsScope == PrsNode);
#ifndef XNOUSEOFSERVICE
  if (PrsNode->ActiveSrv != (xSrvNode)0 && xEmptyInput) {
    /* only if all services is to be stopped */
    PrsNode->ActiveSrv = PrsNode->SrvList;
    while (PrsNode->ActiveSrv != (xSrvNode)0) {
      SrvNode = PrsNode->ActiveSrv->NextSrv;
      SDL_Stop(PrsNode);
      PrsNode->ActiveSrv = SrvNode;
    }        
  } else if (PrsNode->ActiveSrv != (xSrvNode)0) {
    PrsNode->ActiveSrv = SrvNode;
    SDL_Stop(PrsNode);
  } else
#endif
    SDL_Stop(PrsNode);
  if (Found) {
    xInitScope();
    xPrintScope((xbool)1);
  }
#ifdef XTRACE
  xSysD.xSilent--;
#endif
#else
  xPrintString("Stop not implemented\n");
#endif
}


/*---+---------------------------------------------------------------
     xRearrangeInputPort
-------------------------------------------------------------------*/
static void xRearrangeInputPort (void)
{
  xPrsNode      PrsNode;
  int           intVar, intVar2, No;
  int           count;
  xSignalNode   Signal, SignalEntry1, SignalEntry2;

  if (xSysD.xPrsScope == (xPrsNode)0) {
    xPrintScope((xbool)1);
    return;
  }
  PrsNode = xSysD.xPrsScope;
  count = SignalsInPort(PrsNode);
  if (count == 0) {
    xPrintString("The input port is empty\n");
    return;
  }
  if (count == 1) {
    xPrintString("Only one entry in the input port\n");
    return;
  }
  if ( ! xReadEntryNumber("Input port entry : ", &intVar, count))
    return;
  if ( ! xReadEntryNumber("New input port entry : ", &intVar2, count))
    return;
  if (intVar == intVar2) {
    xPrintString("Entries equal. No rearrangement\n");
    return;
  }
#ifndef XNO_MONITOR_CHANGES
  SignalEntry1 = (xSignalNode)0;
  SignalEntry2 = (xSignalNode)0;
  No = 1;
  Signal = PrsNode->InputPort.Suc;
  if (XIS_STARTUP_SIGNAL(Signal))
    Signal = Signal->Suc;
  while ( (SignalEntry1 == (xSignalNode)0 ||
           SignalEntry2 == (xSignalNode)0) &&
          Signal != (xSignalNode)&PrsNode->InputPort ) {
    if (No == intVar)
      SignalEntry1 = Signal;
    if (No == intVar2)
      SignalEntry2 = Signal;
    Signal = Signal->Suc;
    No++;
  }
  if (intVar > intVar2)
    SignalEntry2 = SignalEntry2->Pre;
  /* place P after PNew */
  SignalEntry1->Suc->Pre = SignalEntry1->Pre;
  SignalEntry1->Pre->Suc = SignalEntry1->Suc;
  SignalEntry1->Suc = SignalEntry2->Suc;
  SignalEntry1->Pre = SignalEntry2;
  SignalEntry1->Suc->Pre = SignalEntry1;
  SignalEntry2->Suc = SignalEntry1;
  xPrintString("Rearranged!\n");
#else
  xPrintString("Rearrangement not implemented\n");
#endif
}


/*---+---------------------------------------------------------------
     xRearrangeReadyQueue
-------------------------------------------------------------------*/
static void xRearrangeReadyQueue (void)
{
  int           intVar, intVar2, No;
  int           count;
  xPrsNode      tmpPrs, Entry1, Entry2;

  if (XREADYQ_EMPTY) {
    xPrintString("The ready queue is empty\n");
    return;
  }
  count = 0;
  XBEGIN_PRS_READYQ_LOOP(tmpPrs)
    ++count;
  XEND_PRS_READYQ_LOOP
  if (count == 1) {
    xPrintString("Only one entry in the ready queue\n");
    return;
  }
  if ( ! xReadEntryNumber("Event queue entry : ", &intVar, count))
    return;
  if ( ! xReadEntryNumber("New event queue entry : ", &intVar2, count))
    return;
  if (intVar == intVar2) {
    xPrintString("Entries equal. No rearrangement\n");
    return;
  }
  Entry1 = (xPrsNode)0;
  Entry2 = (xPrsNode)0;
  No = 1;
  XBEGIN_PRS_READYQ_LOOP(tmpPrs)
    if (No == intVar)  Entry1 = tmpPrs;
    if (No == intVar2) Entry2 = tmpPrs;
    No++;
  XEND_PRS_READYQ_LOOP
#ifndef XNO_MONITOR_CHANGES
  if (intVar > intVar2)
    Entry2 = Entry2->Pre;
  /* place P after PNew */
  Entry1->Suc->Pre = Entry1->Pre;
  Entry1->Pre->Suc = Entry1->Suc;
  Entry1->Suc = Entry2->Suc;
  Entry1->Pre = Entry2;
  Entry1->Suc->Pre = Entry1;
  Entry2->Suc = Entry1;
  xSetUpCurrentSymbolRef();
  xPrintString("Rearranged!\n");
  xInitScope();
  xPrintScope((xbool)1);
#else
  xPrintString("Rearrangement not implemented\n");
#endif
}


/*---+---------------------------------------------------------------
     xExaminePId
-------------------------------------------------------------------*/
static void xExaminePId (char * strVar)
{
  xPrsIdNode    ProcessId;
  xPrsNode      PrsNode;
  xPrdNode      PrdNode;
#ifndef XNOUSEOFSERVICE
  xSrvNode      SrvNode;
#endif
  xxToken       Token;

  Token = xScanToken(strVar);
  if (Token == xxLPar) {
    PrsNode = xReadProcess("Process : ", &ProcessId, (xIdNode)0);
    if (PrsNode == (xPrsNode)0) {
      return;
    }
    Token = xScanToken(strVar);
    if (Token != xxRPar) xUngetToken(Token, strVar);
  } else {
    xUngetToken(Token, strVar);
    if (XSYSD xPrsScope == (xPrsNode)0) {
      xPrintScope((xbool)1);
      return;
    }
    PrsNode = XSYSD xPrsScope;
  }

  if (PrsNode->NameNode->Super != (xPrsIdNode)0) {
    ProcessId = PrsNode->NameNode->Super;
    PRINTF2("Instance of process type : %s\n", 
            xWriteEntity((xIdNode)ProcessId));
    while (ProcessId->Super != (xPrsIdNode)0) {
      ProcessId = ProcessId->Super;
      PRINTF2("Which inherits type      : %s\n", 
              xWriteEntity((xIdNode)ProcessId));
    }
    xPrintString("\n");
  }
  PRINTF2("Parent    : %s\n", xWri_SDL_PId(&XPRS_PARENT(PrsNode)));
  PRINTF2("Offspring : %s\n", xWri_SDL_PId(&XPRS_OFFSPRING(PrsNode)));
  PRINTF2("Sender    : %s\n\n", xWri_SDL_PId(&XPRS_SENDER(PrsNode)));

#ifndef XNOUSEOFSERVICE
  if (PrsNode->ActiveSrv == (xSrvNode)0) {
#endif
    for (PrdNode = PrsNode->ActivePrd;
         PrdNode != (xPrdNode)0;
         PrdNode = PrdNode->DynamicFather) {
      xWriteBuf_Fmt("Procedure %-*s in state %s%c\n",
              xfShortIdentifierLength+7,
              xPrdInstance(PrdNode),
              xGetState(PrsNode, PrdNode, PrdNode->NameNode->StateList,
                        PrdNode->State)->Name,
              (PrdNode == PrsNode->ActivePrd &&
               ! PrsNode->InTransition) ? ' ' : '*');
    }
    xWriteBuf_Fmt("PId       %-*s in state %s%c\n",
            xfShortIdentifierLength+7,
            xWri_SDL_PId(&(PrsNode->Self)),
            xGetState(PrsNode, (xPrdNode)0, PrsNode->NameNode->StateList,
                      XPRS_STATEID(PrsNode))->Name,
            (PrsNode->InTransition || PrsNode->ActivePrd != (xPrdNode)0)
            ? '*' : ' ');
#ifndef XNOUSEOFSERVICE
  } else {
    for (SrvNode = PrsNode->SrvList;
         SrvNode != (xSrvNode)0;
         SrvNode = SrvNode->NextSrv) {
      xWriteBuf_Fmt("Service %-*s in state %s%c\n",
              xfShortIdentifierLength+7,
              xWriteEntity((xIdNode)SrvNode->NameNode),
              xGetState(PrsNode, (xPrdNode)0, SrvNode->NameNode->StateList,
                        SrvNode->State)->Name,
              (SrvNode->ActivePrd == (xPrdNode)0 &&
               ! SrvNode->InTransition) ? ' ' : '*');
      for (PrdNode = SrvNode->ActivePrd;
           PrdNode != (xPrdNode)0;
           PrdNode = PrdNode->DynamicFather) {
        xWriteBuf_Fmt("  Procedure %-*s in state %s%c\n",
                xfShortIdentifierLength+7,
                xPrdInstance(PrdNode),
                xGetState(PrsNode, PrdNode, PrdNode->NameNode->StateList,
                          PrdNode->State)->Name,
                (PrdNode == SrvNode->ActivePrd &&
                 ! SrvNode->InTransition) ? ' ' : '*');
      }
    }
  }
#endif
}


#if defined(XCOVERAGE) && defined(XCONNECTPM)
/*---+---------------------------------------------------------------
     xShowCoverageViewer
-------------------------------------------------------------------*/
static void xShowCoverageViewer (void)
{
  int  totalSymb = 0;
  int  execSymb = 0;
  char TempFileName[256];
#ifdef _Windows
  char *pathname;
#endif

  /* Print coverage statistics */
  xCoverageStatistics((xIdNode)xSymbolTableRoot, &execSymb, &totalSymb);
  PRINTF2("\nSymbol coverage : %6.2f\n", (double)execSymb*100/totalSymb);

#ifdef _Windows
  pathname = getenv("TEMP");
  if (pathname)
    sprintf(TempFileName, "%s\\sdtsim%d.cov", pathname, xGlobalNodeNumber());
  else
    sprintf(TempFileName, "sdtsim%d.cov", xGlobalNodeNumber());
#else
  sprintf(TempFileName, "/tmp/sdtsim%d.cov", xGlobalNodeNumber());
#endif
  if ((xSysD.xCoverageFile = fopen(TempFileName, "w")) == NULL) {
    PRINTF2("File %s could not be created\n", TempFileName);
    return;
  }

  xPrintCoverageArray(xSymbolTableRoot, 1, 1);
  xPrintCoverageArray(xSymbolTableRoot, 1, 2);

  if (fclose(xSysD.xCoverageFile) != 0)
    xPrintString("Error closing Test coverage file\n");

  if (xStartCoverageViewer(TempFileName) == 0) {
    xPrintString( "\nUnable to start coverage viewer.\n" );
  }
}
#endif

#if defined(XSIGPRIO) || defined(XSIGPRSPRIO) || defined(XPRSSIGPRIO)
/*---+---------------------------------------------------------------
     xReadSignalPrio
-------------------------------------------------------------------*/
static xbool xReadSignalPrio(
  char  * Prompt,
  int   * intVar)
{
  xxToken Token;
  char    strVar[256];

  Token = xPromptQuestionMark(Prompt, "integer >= 0 : ", strVar);
  if (Token == xxEoln || Token == xxMinus) {
    *intVar = xDefaultPrioSignal;
    return (xbool)1;
  }
  
  if (sscanf(strVar, "%d", intVar) != 1) {
    xPrintString("Illegal input\n");
    return (xbool)0;
  }
  return (xbool)1;
}
#endif


/*---+---------------------------------------------------------------
     xReadTime
-------------------------------------------------------------------*/
static xbool xReadTime(
  char      * Prompt,
  SDL_Time  * timeVar)
{
  xxToken Token;
  char    strVar[256];

  Token = xPromptQuestionMark(Prompt, " time value >= Now : ", strVar);
  xUngetToken(Token, strVar);
  return xReadSDL_Time(timeVar);
}


/*---+---------------------------------------------------------------
     xGetPrdLevel
-------------------------------------------------------------------*/
static int xGetPrdLevel (void)
{
  xPrdNode Prd;
  int Count = 0;

  for ( Prd = XREADYQ_FIRST->ActivePrd;
        Prd != (xPrdNode)0;
        Prd = Prd->DynamicFather )
    Count++;
  return Count;
}

#ifdef XGRTRACE
/*---+---------------------------------------------------------------
     xGRShowPreviousSymbol
-------------------------------------------------------------------*/
static xbool xGRShowPreviousSymbol (void)
{
  if ( strlen(xSysD.xPreviousSymbolRef) < (unsigned)2 ) {
    return (xbool)0;
  }
  xGRTraceSymbol(xSysD.xPreviousSymbolRef);
  return (xbool)1;
}


/*---+---------------------------------------------------------------
     xGRShowNextSymbol
-------------------------------------------------------------------*/
static xbool xGRShowNextSymbol (void)
{
  if ( strlen(xSysD.xCurrentSymbolRef) < (unsigned)2 ) {
    return (xbool)0;
  }
  xGRTraceSymbol(xSysD.xCurrentSymbolRef);
  return (xbool)1;
}
#endif
        /* XGRTRACE */

/*---+---------------------------------------------------------------
     xGetUnit
-------------------------------------------------------------------*/
static void xGetUnit(
  xbool      ForSignalLog,
  xIdNode   *IdNode,
  xPrsNode  *PrsNode)
{
  int               intVar;
  long              ECSet;
  xbool             xEmptyInput;
  char              strVar[256];
  xxToken           Token;

  *PrsNode = (xPrsNode)0;
  *IdNode = (xIdNode)0;

  Token = xScanToken(strVar);
  if (Token == xxEOF) return;
  if (Token == xxEoln) {
    if (xSysD.xSaveLine != (char *)0) return;
    xPrintString("Unit name : ");
    Token = xScanToken(strVar);
  }

  if (Token == xxMinus || 
      ( Token == xxId && strVar[0] >= '0' && strVar[0] <= '9')) {
    *IdNode = xSymbolTableRoot;
    if (Token == xxId) xUngetToken(Token, strVar);
    return;
  }
  while (Token == xxQuestionMark || Token == xxEoln) {
    xMonListIdNodeECSet(1L<<((long)xSystemEC),
       xSymbolTableRoot, (xIdNode)0, (xbool)1);
    xMonListIdNodeECSet(1L<<((long)xBlockEC),
       xSymbolTableRoot, (xIdNode)0, (xbool)1);
    xMonListIdNodeECSet(1L<<((long)xProcessEC),
       xSymbolTableRoot, (xIdNode)0, (xbool)1);
    if (ForSignalLog) {
      xMonListIdNodeECSet(1L<<((long)xChannelEC),
         xSymbolTableRoot, (xIdNode)0, (xbool)1);
      xMonListIdNodeECSet(1L<<((long)xSignalrouteEC),
         xSymbolTableRoot, (xIdNode)0, (xbool)1);
    }
    xPrintString(": ");
    if (Token != xxEoln) xSkipLine();
    Token = xScanToken(strVar);
    if (Token == xxMinus || Token == xxEoln || 
        (Token == xxId && strVar[0] >= '0' && strVar[0] <= '9')) {
      *IdNode = xSymbolTableRoot;
      if (Token == xxId || Token == xxEoln) xUngetToken(Token, strVar);
      return;
    }
  }

  if (Token == xxSystem) {
    ECSet = 1L << ((long)xSystemEC);
    Token = xScanToken(strVar);
  } else if (Token == xxBlock) {
    ECSet = 1L << ((long)xBlockEC);
    Token = xScanToken(strVar);
  } else if (Token == xxProcess) {
    ECSet = 1L << ((long)xProcessEC);
    Token = xScanToken(strVar);
  } else if (Token == xxChannel) {
    ECSet = 1L << ((long)xChannelEC);
    Token = xScanToken(strVar);
  } else if (Token == xxSignalroute) {
    ECSet = 1L << ((long)xSignalrouteEC);
    Token = xScanToken(strVar);
  } else if (ForSignalLog) {
    ECSet = (1L << ((long)xSystemEC))  | (1L << ((long)xBlockEC))   |
            (1L << ((long)xProcessEC)) | (1L << ((long)xChannelEC)) |
            (1L << ((long)xSignalrouteEC));
  } else {
    ECSet = (1L << ((long)xSystemEC))  | (1L << ((long)xBlockEC))   |
            (1L << ((long)xProcessEC));
  }

  *IdNode = xReadIdNodeInECSet(Token, strVar, ECSet,
              xSymbolTableRoot, (xIdNode)0);
  if (*IdNode == (xIdNode)0) return;

  Token = xScanToken(strVar);
  if (Token == xxColon) {
    if ( xReadInstanceNumber("Instance number : ", &intVar, &xEmptyInput) ) {
      if (xEmptyInput &&
          *((xPrsIdNode)(*IdNode))->ActivePrsList != (xPrsNode)0 &&
          (*((xPrsIdNode)(*IdNode))->ActivePrsList)->NextPrs == (xPrsNode)0
         ) {
        *PrsNode = *((xPrsIdNode)(*IdNode))->ActivePrsList;
        return;
      }
      if (xEmptyInput) {
        xPrintString("Instance number missing\n");
        *IdNode = (xIdNode)0;
        return;
      }
      for (*PrsNode = *((xPrsIdNode)(*IdNode))->ActivePrsList;
           *PrsNode != (xPrsNode)0;
           *PrsNode = (*PrsNode)->NextPrs)
        if (XPRS_INSTNR((*PrsNode)) == intVar)
          break;
      if (*PrsNode == (xPrsNode)0) {
        xPrintString("Instance with specified number is not active\n");
        *IdNode = (xIdNode)0;    
        return;
      }
      return;
    }
    *IdNode = (xIdNode)0;
    return;
  }
  xUngetToken(Token, strVar);
  return;
}


/*---+---------------------------------------------------------------
     xSetSignalLog
-------------------------------------------------------------------*/
static void xSetSignalLog (char * strVar)
{
  xSignalLogNode SignalLogP;
  xSignalLogNode NewSignalLogP;
  xSignalLogRec  SignalLog;

  SignalLog.Next = (xSignalLogNode)0;
  xGetUnit((xbool)1, &SignalLog.UnitId, &SignalLog.PrsNode);
  if (SignalLog.UnitId == (xIdNode)0 && SignalLog.PrsNode == (xPrsNode)0)
    return;
  if (SignalLog.UnitId != (xIdNode)0 &&
      SignalLog.UnitId->EC != xSystemEC &&
      SignalLog.UnitId->EC != xBlockEC &&
      SignalLog.UnitId->EC != xProcessEC &&
      SignalLog.UnitId->EC != xChannelEC &&
      SignalLog.UnitId->EC != xSignalrouteEC) {
    PRINTF2("Not possible to set signallog on %s\n",
             xEntityString[SignalLog.UnitId->EC]);
    return;
  }
  if (SignalLog.UnitId != (xIdNode)0)
    PRINTF3("%s %s\n",
           xEntityString[SignalLog.UnitId->EC], 
           xWriteEntity(SignalLog.UnitId));
  if (SignalLog.PrsNode != (xPrsNode)0)
    PRINTF2("PId %s\n", xWri_SDL_PId(&(SignalLog.PrsNode->Self)))

  if (! xGetAndOpenFile(&SignalLog.File, (xbool)0, strVar, "log") )
    return;
  fprintf(SignalLog.File, "Signal log for system %s with unit ",
          xSysD.SystemName);
  if (SignalLog.UnitId != (xIdNode)0)
    fprintf(SignalLog.File, "%s %s",
            xEntityString[SignalLog.UnitId->EC], SignalLog.UnitId->Name);
  if (SignalLog.PrsNode != (xPrsNode)0)
    fprintf(SignalLog.File, "PId %s",
            xWri_SDL_PId(&(SignalLog.PrsNode->Self)));
  fprintf(SignalLog.File, " on file %s\n", strVar);
  strcpy(SignalLog.Filename, strVar);

  NewSignalLogP = (xSignalLogNode)xAlloc((xptrint)sizeof(*NewSignalLogP));
  *NewSignalLogP = SignalLog;
  if (xSysD.SignalLogList == (xSignalLogNode)0) {
    xSysD.SignalLogList = NewSignalLogP;
  }
  else {
    for (SignalLogP = xSysD.SignalLogList;
         SignalLogP->Next != (xSignalLogNode)0;
         SignalLogP = SignalLogP->Next)
      ;
    SignalLogP->Next = NewSignalLogP;
  }
  xPrintString("New signal log was defined\n");
}


/*---+---------------------------------------------------------------
     xCloseSignalLog
-------------------------------------------------------------------*/
static void xCloseSignalLog (void)
{
  xSignalLogNode SignalLogP;
  xSignalLogNode SignalLogPtmp;
  int            count;
  int            intVar;

  if (xSysD.SignalLogList == (xSignalLogNode)0) {
    xPrintString("No signal log defined\n");;
    return;
  }
  count = 0;
  for (SignalLogP = xSysD.SignalLogList;
       SignalLogP != (xSignalLogNode)0;
       SignalLogP = SignalLogP->Next)
    ++count;
  if ( ! xReadEntryNumber("Signal log entry : ", &intVar, count))
    return;
  if (intVar == 1) {
    SignalLogPtmp = xSysD.SignalLogList;
    xSysD.SignalLogList = xSysD.SignalLogList->Next;
  }
  else {
    count = 0;
    for (SignalLogP = xSysD.SignalLogList;
         SignalLogP != (xSignalLogNode)0;
         SignalLogP = SignalLogP->Next) {
      if (++count == intVar - 1)
        if (SignalLogP->Next != (xSignalLogNode)0)
          break;
    }
    SignalLogPtmp = SignalLogP->Next;
    SignalLogP->Next = SignalLogP->Next->Next;
  }
  if (fclose(SignalLogPtmp->File) != 0)
    xPrintString("Error closing signal log file\n");
  xFree((void **)&SignalLogPtmp);
  xPrintString("Signal log was closed\n");
}


/*---+---------------------------------------------------------------
     xListSignalLog
-------------------------------------------------------------------*/
static void xListSignalLog (void)
{
  xSignalLogNode SignalLogP;
  int            count;

  if (xSysD.SignalLogList == (xSignalLogNode)0) {
    xPrintString("No signal log defined\n");;
    return;
  }
  count = 0;
  for (SignalLogP = xSysD.SignalLogList;
       SignalLogP != (xSignalLogNode)0;
       SignalLogP = SignalLogP->Next) {
    PRINTF2("\n%d\n", ++count);
    if (SignalLogP->UnitId != (xIdNode)0)
      PRINTF3("Unit name : %s %s\n",
              xEntityString[SignalLogP->UnitId->EC], 
              xWriteEntity(SignalLogP->UnitId));
    if (SignalLogP->PrsNode != (xPrsNode)0)
      PRINTF2("Unit name : PId %s\n",
              xWri_SDL_PId(&(SignalLogP->PrsNode->Self)));
/*  ***   Either no signal or a list of signals    ***
        if (SignalLogP->SignalId != (xIdNode)0)
          PRINTF2("Signals : %s\n", 
                  xWriteEntity((xIdNode)SignalLogP->SignalId));
        else
          xPrintString("Signals : any\n");
    ***                                            ***   */
    PRINTF2("File name : %s\n", SignalLogP->Filename);
  }
}


/*---+---------------------------------------------------------------
     xGetHelp
-------------------------------------------------------------------*/
static void xGetHelp(
  char * strVar,
  xbool  IsHelp)
{
  FILE        * Helpfile;
  char        * StrP;
  int           intVar;
  xxToken       Token;
  int           No;
  xMonitorCommandIdNode HelpCommandIdNode;
  xfCodeType    Code;
  char          Line[256];
  char          strVar2[256];
  char          strVar3[256];
  int           cmds;
  xIdNode       xIdNodeVar;

#ifdef XCONNECTPM
  StrP = xGetInstallDirectory();
  if (StrP) {
    strcpy(strVar, StrP);
    free(StrP);
#ifdef _Windows
    strcat(strVar, "\\sdt\\sdtdir\\wini386\\help_sct.hlp");
#else
    strcat(strVar, "/sdt/sdtdir/sunos5sdtdir/help_sct.hlp");
#endif
    if ((Helpfile = fopen(strVar, "r")) != NULL) {
      goto helpfileopenedlabel;
    }
  }
#endif

  StrP = getenv("SDTSCTHELP");
  if (StrP) {
    strcpy(strVar, StrP);
#ifdef _Windows
    strcat(strVar, "\\help_sct.hlp");
#else
    strcat(strVar, "/help_sct.hlp");
#endif
    if ((Helpfile = fopen(strVar, "r")) != NULL) {
      goto helpfileopenedlabel;
    }
  }

#ifdef _Windows
  StrP = getenv("SDTDIR");
#else
  StrP = getenv("sdtdir");
#endif
  if (StrP == NULL) {
    PRINTF("Sorry, the help file is not available.\n");
    PRINTF("Environment variable \"SDTSCTHELP\" is not set.\n");
    PRINTF("\nPlease set the environment variable \"SDTSCTHELP\" to:\n");
#ifdef _Windows
    PRINTF("<TAU installation>\\sdt\\sdtdir\\wini386\n");
#else
    PRINTF("<TAU installation>/sdt/sdtdir/<architecture>\n");
#endif
    return;
  }
  /* Try to open file without "/" -- useful on VAX/VMS */
  strcpy(strVar, StrP);
  strcat(strVar, "help_sct.hlp");
  if ((Helpfile = fopen(strVar, "r")) == NULL) {
    strcpy(strVar, StrP);
#ifdef _Windows
    strcat(strVar, "\\help_sct.hlp");
#else
    strcat(strVar, "/help_sct.hlp");
#endif
    if ((Helpfile = fopen(strVar, "r")) == NULL) {
      PRINTF2("File %s not found\n", strVar);
      return;
    }
  }

helpfileopenedlabel:

  Token = xScanToken(strVar);
  if ( Token != xxEoln || ! IsHelp) {
    HelpCommandIdNode = (xMonitorCommandIdNode)0;
    if (IsHelp) {
      HelpCommandIdNode = xGetCommand(strVar, Token, xSysD.xCommandTable);
    }
    if (HelpCommandIdNode != (xMonitorCommandIdNode)0 || !IsHelp) {
      /* Skip up to text of interest */
      No = 999;
      while ((intVar = fgetc(Helpfile)) != EOF) {
        if (intVar == '\n') {
          if ((intVar = fgetc(Helpfile)) == '#') {
            if (fscanf(Helpfile, "%d", &No) != 1) {
              xPrintString("Sorry, an error is found in the help file\n");
              No = 999;
              break;
            }
            else if (IsHelp && No == HelpCommandIdNode->CommandNo)
              break;
            else if (!IsHelp && No == 998)
              break;
          }
        }
      }
      if (No >= 999) {
        xPrintString("Sorry, no help is available about this\n");
        fclose(Helpfile);
        return;
      }
    }
    else {
      xPrintString("Type help to get available commands\n");
      fclose(Helpfile);
      return;
    }
    /* Read and copy text to outfile up to line starting with # */
    No = 0;
    while ((intVar = fgetc(Helpfile)) != EOF) {
      Line[No++] = (char)intVar;
      if (intVar == '\n') {
        Line[No] = '\0';
        xPrintString(Line);
        No = 0;
        if ((intVar = fgetc(Helpfile)) == '#')
          break;
        else if (intVar == EOF)
          break;
        else
          Line[No++] = (char)intVar;
      }
    }
  }
  else {
    /* Read and copy text to outfile up to line starting with # while   */
    /* removing commands not found                                      */
    No = 0;
    Line[No++] = '\n';   /* Start with heading */
    while ((intVar = fgetc(Helpfile)) != EOF) {
      Line[No++] = (char)intVar;
      if (intVar == '\n') {
        Line[No] = '\0';
        if (Line[0] == '\n') {  /* This is a heading */
          xPrintString(Line);
        }
        else {
          cmds = sscanf(Line, "%s%s%s" , strVar, strVar2, strVar3);
          Line[0] = '\0';
          xfDecodeId(strVar, xSysD.xCommandTable,
               1L << ((long)xMonitorCommandEC), &xIdNodeVar, &Code, (xIdNode)0);
          if (Code == xfOk)
            sprintf(Line, "%-27s", strVar);
          if (cmds > 1) {
            xfDecodeId(strVar2, xSysD.xCommandTable,
               1L << ((long)xMonitorCommandEC), &xIdNodeVar, &Code, (xIdNode)0);
            if (Code == xfOk)
              sprintf(Line + strlen(Line),
                      "%-27s", strVar2);
          }
          if (cmds > 2) {
            xfDecodeId(strVar3, xSysD.xCommandTable,
               1L << ((long)xMonitorCommandEC), &xIdNodeVar, &Code, (xIdNode)0);
            if (Code == xfOk)
              strcat(Line, strVar3);
          }
          if (strlen(Line) != 0) {
            strcat(Line, "\n");
            xPrintString(Line);
          }
        }
        No = 0;
        if ((intVar = fgetc(Helpfile)) == '#')
          break;
        else if (intVar == EOF)
          break;
        else
          Line[No++] = (char)intVar;
      }
    }
  }
  fclose(Helpfile);
}


#ifdef XMSCE
/*---+---------------------------------------------------------------
     xMSC_Level
-------------------------------------------------------------------*/
static xbool xMSC_Level (void)
{
  xxToken  Token;
  char     strVar[256];
  int      intVar;

  Token = xScanToken(strVar);
  if (Token == xxEoln) {
    xPrintString("MSC symbols : ");
    Token = xScanToken(strVar);
  }
  while (Token == xxQuestionMark || Token == xxEoln) {
    xPrintString("0 /* Basic MSC */\n");
    xPrintString("1 /* MSC with states */\n");
    xPrintString("2 /* MSC with states and actions */\n");
    xPrintString(": ");  /* Extra xPrintString for UI */
    if (Token != xxEoln) xSkipLine();
    Token = xScanToken(strVar);
  }
  if (Token == xxId) {
    if (sscanf(strVar, "%d", &intVar) != 1) {
      xPrintString("Illegal value\n");
      return (xbool)0;
    }
  } else {
    xPrintString("Illegal value\n");
    return (xbool)0;
  }
  if (intVar<0 || intVar>2) {
    xPrintString("Illegal value\n");
    return (xbool)0;
  }
  xSysD.MSCSymbolLevel = intVar;
  return (xbool)1;
}
#endif


/*---+---------------------------------------------------------------
     xSetResetTrace
-------------------------------------------------------------------*/
static void xSetResetTrace (int CommandNo)
{
  xPrsNode PrsNode;
  xIdNode  xIdNodeVar;
  int      intVar;
  xxToken  Token;
  char     strVar[256];

  /* Read the unit to set trace for */
  xGetUnit((xbool)0, &xIdNodeVar, &PrsNode);
  if (xIdNodeVar == (xIdNode)0 && PrsNode == (xPrsNode)0)
    return;

  if (xIdNodeVar != (xIdNode)0 && xIdNodeVar->EC != xSystemEC &&
      xIdNodeVar->EC != xBlockEC && xIdNodeVar->EC != xProcessEC) {
    PRINTF2("Trace cannot be assigned to %s\n", 
            xEntityString[xIdNodeVar->EC]);
    return;
  }

  /* Read the trace value. If reset then -1 (0 for xSymbolTableRoot). */
  if (CommandNo == 4 ||
#ifdef XMSCE
      CommandNo == 89 ||              /* Set-MSC-Trace */
#endif
      CommandNo == 58) {
                                      /* Set-Trace */ /* Set-GR-Trace */
    Token = xScanToken(strVar);
    if (Token == xxEoln) {
      xPrintString("Trace value : ");
      Token = xScanToken(strVar);
    }
    while (Token == xxQuestionMark || Token == xxEoln) {
      if (CommandNo == 4) {
                                                      /* Set-Trace */
        xPrintString("0 /* No trace */\n");
        xPrintString("1 /* Signals to and from environment */\n");
        xPrintString("2 /* Transition start and timer outputs */\n");
        xPrintString("3 /* Important SDL actions */\n");
        xPrintString("4 /* All SDL actions */\n");
        xPrintString("5 /* All SDL actions + Result */\n");
        xPrintString("6 /* All SDL actions + Result + Parameters */\n");

#ifdef XMSCE
      } else if (CommandNo == 89)  {
                                                      /* Set-MSC-Trace */
        xPrintString("0 /* No MSC trace */\n");
        xPrintString("1 /* Conditional MSC trace */\n");
        xPrintString("2 /* Unconditional MSC trace */\n");
        if (xIdNodeVar != (xIdNode)0 && xIdNodeVar->EC != xProcessEC) {
          xPrintString("3 /* Block trace */\n");
        }
#endif
      } else {                                       /* Set-GR-Trace */
        xPrintString("0 /* GR trace off */\n");
        xPrintString("1 /* Show next symbol when entering monitor */\n");
        xPrintString("2 /* Show all symbols */\n");
      }
      xPrintString(": ");  /* Extra xPrintString for UI */
      if (Token != xxEoln) xSkipLine();
      Token = xScanToken(strVar);
    }
    if (Token == xxId) {
      if (sscanf(strVar, "%d", &intVar) != 1) {
        xPrintString("Illegal value\n");
        return;
      }
    } else {
      xPrintString("Illegal value\n");
      return;
    }
  }
  else if (xIdNodeVar == xSymbolTableRoot)
    intVar = 0;
  else
    intVar = -1;

  /* Assign new trace value to PId */
  if (PrsNode != (xPrsNode)0) {
    if (CommandNo == 4 || CommandNo == 8)
                                  /* Set-Trace */ /* Reset-Trace */
#ifdef XTRACE
      PrsNode->Trace_Default = intVar
#endif
      ;
#ifdef XMSCE
    else if (CommandNo == 89 || CommandNo == 90) {
                                  /* Set-MSC-Trace */ /* Reset-MSC-Trace */
      if (intVar == 3) {
        xPrintString("MSC trace on block level cannot be assigned to a PId\n");
        return;
      }
      PrsNode->MSCETrace = intVar;
    }
#endif
#ifdef XGRTRACE
    else
      PrsNode->GRTrace = intVar;
#endif
    if (CommandNo == 4 ||
#ifdef XMSCE
        CommandNo == 89 ||
                                  /* Set-MSC-Trace */
#endif
        CommandNo == 58)
                                  /* Set-Trace */ /* Set-GR-Trace */
      PRINTF3("Trace for PId %s set to %d\n",
             xWri_SDL_PId(&PrsNode->Self), intVar)
    else
      PRINTF2("Trace reset for PId %s\n", xWri_SDL_PId(&PrsNode->Self))
    xSysD.xNoTraceOn = xCheckTrace(xSymbolTableRoot);
    return;
  }

  /* Assign new trace value to default values */
  else if (xIdNodeVar == xSymbolTableRoot) {
    if (CommandNo == 4 || CommandNo == 8)
                                      /* Set-Trace */ /* Reset-Trace */
#ifdef XTRACE
      xSysD.Trace_Default = intVar
#endif
      ;
#ifdef XMSCE
    else if (CommandNo == 89 || CommandNo == 90)
                                  /* Set-MSC-Trace */ /* Reset-MSC-Trace */
      xSysD.MSCETrace = intVar;
#endif
#ifdef XGRTRACE
    else {
                                                       /* Reset-GR-Trace */
      xSysD.GRTrace = intVar;
    }
#endif
  }

  /* Assign new trace value to System */
  else if (xIdNodeVar->EC == xSystemEC) {
    if (CommandNo == 4 || CommandNo == 8)
                                      /* Set-Trace */ /* Reset-Trace */
#ifdef XTRACE
      ((xSystemIdNode)xIdNodeVar)->Trace_Default = intVar
#endif
      ;
#ifdef XMSCE
    else if (CommandNo == 89 || CommandNo == 90)
                                  /* Set-MSC-Trace */ /* Reset-MSC-Trace */
      ((xSystemIdNode)xIdNodeVar)->MSCETrace = intVar;
#endif
#ifdef XGRTRACE
    else {
                                                       /* Reset-GR-Trace */
      ((xSystemIdNode)xIdNodeVar)->GRTrace = intVar;
    }
#endif
  }

  /* Assign new trace value to Block */
  else if (xIdNodeVar->EC == xBlockEC) {
    if (CommandNo == 4 || CommandNo == 8)
                                      /* Set-Trace */ /* Reset-Trace */
#ifdef XTRACE
      ((xBlockIdNode)xIdNodeVar)->Trace_Default = intVar
#endif
      ;
#ifdef XMSCE
    else if (CommandNo == 89 || CommandNo == 90)
                                  /* Set-MSC-Trace */ /* Reset-MSC-Trace */
      ((xBlockIdNode)xIdNodeVar)->MSCETrace = intVar;
#endif
#ifdef XGRTRACE
    else
      ((xBlockIdNode)xIdNodeVar)->GRTrace = intVar;
#endif
  }

  /* Assign new trace value to Process instance set */
  else if (xIdNodeVar->EC == xProcessEC) {
    if (CommandNo == 4 || CommandNo == 8)
                                  /* Set-Trace */ /* Reset-Trace */
#ifdef XTRACE
      ((xPrsIdNode)xIdNodeVar)->Trace_Default = intVar
#endif
      ;
#ifdef XMSCE
    else if (CommandNo == 89 || CommandNo == 90) {
                                  /* Set-MSC-Trace */ /* Reset-MSC-Trace */
      if (intVar == 3) {
        xPrintString(
                 "MSC trace on block level cannot be assigned to a Process\n");
        return;
      }
      ((xPrsIdNode)xIdNodeVar)->MSCETrace = intVar;
    }
#endif
#ifdef XGRTRACE
    else
      ((xPrsIdNode)xIdNodeVar)->GRTrace = intVar;
#endif
  }

  /* Command response */
  if (xIdNodeVar == xSymbolTableRoot) {
    PRINTF2("Default trace set to %d\n", intVar);
  } else if (CommandNo == 4 ||
#ifdef XMSCE
           CommandNo == 89 ||
                                      /* Set-MSC-Trace */
#endif
           CommandNo == 58) {
                                      /* Set-Trace */ /* Set-GR-Trace */

    PRINTF4("Trace for %s %s set to %d\n",
            xEntityString[xIdNodeVar->EC], xWriteEntity(xIdNodeVar), intVar);
  } else {
    PRINTF3("Trace reset for %s %s\n",
            xEntityString[xIdNodeVar->EC], xWriteEntity(xIdNodeVar));
  }
  xSysD.xNoTraceOn = xCheckTrace(xSymbolTableRoot);
}


/*---+---------------------------------------------------------------
     xOutputVia
-------------------------------------------------------------------*/
static void xOutputVia (void)
{
  XSIGTYPE        SignalId;
  xChannelIdNode  ChannelIdNode;
  xPrsIdNode      xIdNodeSender;
  xPrsNode        PrsNode;
  xPrsNode        PrsNodeSender;
  xIdNode         yViaList[2];
  xIdNode        *ViaList;
  xbool           xEmptyInput;
  xSignalNode     Signal;
#if defined(XSIGPRIO) || defined(XSIGPRSPRIO) || defined(XPRSSIGPRIO)
  int             intVar;
#endif
  int             No;
#ifdef XSIGPATH
  xIdNode         Path[xSizeOfPathStack];
  int             PathLength = -1;
#endif

  xReadSignal(&SignalId, &Signal, (xIdNode)xEnvId);
  if (SignalId == (XSIGTYPE)0)
    return;
  ChannelIdNode = (xChannelIdNode)xGetIdNodeInECSet("Channel name : ", 
    xChannelOrSignalRoute, xSymbolTableRoot, &xEmptyInput,
    (xbool)1, (xIdNode)SignalId);

  if (xEmptyInput)
    ViaList = (xIdNode *)0;
  else {
    if (ChannelIdNode == (xChannelIdNode)0) {
      XRELEASE_SIGNAL(Signal);
      return;
    }
    if (ChannelIdNode->ToId[0] == (xIdNode)xEnvId)
      ChannelIdNode = ChannelIdNode->Reverse;
    yViaList[0] = (xIdNode)ChannelIdNode;
    yViaList[1] = (xIdNode)0;
    ViaList = &yViaList[0];
  }

  xIdNodeSender = xEnvId;
  PrsNodeSender = *xIdNodeSender->ActivePrsList;
#ifdef XSIGPATH
  XSET_RECEIVER(Signal,
      xFindReceiver(XSIGNAL_CODE(Signal), PrsNodeSender->Self,
        ViaList, &No, Path, &PathLength))
#else
  XSET_RECEIVER(Signal,
      xFindReceiver(XSIGNAL_CODE(Signal), PrsNodeSender->Self,
        ViaList, &No, &ChannelIdNode))
#endif
  if (No < 1) {
    xPrintString("No possible receiver\n");
    XRELEASE_SIGNAL(Signal);
    return;
  }
  if (No > 1) {
    if (xEq_SDL_PId_NULL(XSIGNAL_RECEIVER(Signal))) {
      xPrintString("Several receivers are found\n");
      XRELEASE_SIGNAL(Signal);
      return;
    }
    else
      xPrintString("Several receivers are found - choosing one\n");
  }
#if defined(XSIGPRIO) || defined(XSIGPRSPRIO) || defined(XPRSSIGPRIO)
# ifdef XNOSIGPRIOPROMPT
  intVar = XSIGNAL_IDNODE(Signal)->Prio;
# else
  if ( ! xReadSignalPrio("Signal Priority : ", &intVar) )
    return;
# endif
#endif
  xSysD.xMonitorOutput = (xbool)1;
    /* Do not check path, already performed in xFindReceiver */
#ifdef XTRACE
  xSysD.xSilent++;
#endif
  SEND_SIGNAL_IN_MONITOR
  xSysD.xMonitorOutput = (xbool)0;
#ifdef XTRACE
  xSysD.xSilent--;
#endif
  PrsNode = XPID_TO_PRS(XSIGNAL_RECEIVER(Signal));
  PRINTF2("Signal %s", xWriteEntity((xIdNode)SignalId));
  PRINTF2(" was sent to %s", xWri_SDL_PId(&PrsNode->Self));
  PRINTF2(" from %s\n", xWri_SDL_PId(&(PrsNodeSender->Self)));
  if ( ! SIGNAL_IN_INPUT_PORT(Signal)) {
    PRINTF2("Signal %s caused an immediate null-transition\n",
            xWriteEntity((xIdNode)SignalId));
  } else {
    xChangeScope(PrsNode);
  }
}


/*---+---------------------------------------------------------------
     xOutputTo
-------------------------------------------------------------------*/
static void xOutputTo (int CommandNo)
{
  XSIGTYPE        SignalId;
  xPrsIdNode      ProcessId;
  xPrsIdNode      xIdNodeSender;
  xPrsNode        PrsNode;
  xPrsNode        PrsNodeSender;
  xIdNode        *ViaList;
  xSignalNode     Signal;
#if defined(XSIGPRIO) || defined(XSIGPRSPRIO) || defined(XPRSSIGPRIO)
  int             intVar;
#endif
  int             No;
  int             count;
  xbool           Found;
#ifdef XSIGPATH
  xIdNode         Path[xSizeOfPathStack];
  int             PathLength = -1;
#endif

  if (CommandNo == 26)
    xReadSignal(&SignalId, &Signal, (xIdNode)xEnvId); /* Output-To */
  else
    xReadSignal(&SignalId, &Signal, (xIdNode)0);      /* Output-Internal */
  if (SignalId == (XSIGTYPE)0)
    return;
  if (xSysD.xRestoringState) {
    /* No LimId if Restore-State */
    PrsNode = xReadProcess("To Process : ", &ProcessId, (xIdNode)0);
  }
  else {
    PrsNode = xReadProcess("To Process : ", &ProcessId, (xIdNode)SignalId);
  }
  if (PrsNode == (xPrsNode)0) {
    XRELEASE_SIGNAL(Signal);
    return;
  }
  XSET_RECEIVER(Signal, PrsNode->Self)

  if (CommandNo == 25) {
                                                    /* Output-Internal */
    if ( ! xSysD.xRestoringState ) {
      /* No test of valid input signal if Restore-State */
      Found = (xbool)0;
      if (ProcessId->SignalSet != (XSIGTYPE *)0) {
        for (count = 0;
             ProcessId->SignalSet[count] != (XSIGTYPE)0;
             count++) {
          if (XSIGNALID_CODE(SignalId) == ProcessId->SignalSet[count]) {
            Found = (xbool)1;
            break;
          }
        }
      }
      if ( ! Found) {
        PRINTF2("Signal %s", xWriteEntity((xIdNode)SignalId));
        PRINTF2(" is not in valid input signal set of process %s\n",
                xWriteEntity((xIdNode)ProcessId));
        XRELEASE_SIGNAL(Signal);
        return;
      }
    }
    PrsNodeSender = xReadProcess("From Process : ", &xIdNodeSender, (xIdNode)0);
    if (PrsNodeSender == (xPrsNode)0 && xIdNodeSender != xNullId) {
      XRELEASE_SIGNAL(Signal);
      return;
    }
  }
  else {
                                                    /* Output-To */
    xIdNodeSender = xEnvId;
    PrsNodeSender = *xIdNodeSender->ActivePrsList;
#ifdef XEOUTPUT
#ifdef XSIGPATH
    No = xIsPath(XSIGNAL_CODE(Signal), (xIdNode)xIdNodeSender,
                 ProcessId, (xIdNode *)0, Path, &PathLength);
#else
    No = xIsPath(XSIGNAL_CODE(Signal), (xIdNode)xIdNodeSender,
                 ProcessId, (xIdNode *)0);
#endif

    if (No < 1) {
      xPrintString("No path to receiver\n");
      XRELEASE_SIGNAL(Signal);
      return;
    }
#endif
  }
#if defined(XSIGPRIO) || defined(XSIGPRSPRIO) || defined(XPRSSIGPRIO)
# ifdef XNOSIGPRIOPROMPT
  intVar = XSIGNAL_IDNODE(Signal)->Prio;
# else
  if ( ! xReadSignalPrio("Signal Priority : ", &intVar) )
    return;
# endif
#endif
  ViaList = (xIdNode *)0;
  if (CommandNo == 25)
    xSysD.xMonitorOutput = (xbool)1; /* Do not check path */
#ifdef XTRACE
  xSysD.xSilent++;
#endif
  SEND_SIGNAL_IN_MONITOR
  xSysD.xMonitorOutput = (xbool)0;
#ifdef XTRACE
  xSysD.xSilent--;
#endif
  if (SIGNAL_IN_INPUT_PORT(Signal)) {
    PRINTF2("Signal %s", xWriteEntity((xIdNode)SignalId));
    PRINTF2(" was sent to %s", xWri_SDL_PId(&PrsNode->Self));
    PRINTF2(" from %s\n", xWri_SDL_PId(&(XSIGNAL_SENDER(Signal))));
    xChangeScope(PrsNode);
  } else {
    PRINTF2("Signal %s caused an immediate null-transition\n",
            xWriteEntity((xIdNode)SignalId))
  }
}


/*---+---------------------------------------------------------------
     xListAllEnvSignals
-------------------------------------------------------------------*/
static void xListAllEnvSignals(xIdNode FromNode, char sep, int *count)
{
  xIdNode       IdNode;
  xPrsNode      PrsNode;
  int           SignalNo;
  xSignalIdNode SignalId;
  xInputAction  InputAction;
  xIdNode       Path[xSizeOfPathStack];
  int           PathLength = -1;

  for ( IdNode  = FromNode->First;
        IdNode != (xIdNode)0;
        IdNode  = IdNode->Suc ){
    if (IdNode->EC == xProcessEC) {
      for (PrsNode = *((xPrsIdNode)IdNode)->ActivePrsList;
           PrsNode != (xPrsNode)0;
           PrsNode = PrsNode->NextPrs) {
        if (PrsNode->Signal) {
          continue;
        }
        if (PrsNode->NameNode->SignalSet == (xSignalIdNode *)0) {
          continue;
        }
        /* Loop for all signals in signal set */
        for (SignalNo = 0;
             (SignalId = PrsNode->NameNode->SignalSet[SignalNo]) !=
               (xSignalIdNode)0;
             SignalNo++) {
          InputAction = xFindInputAction(SignalId, PrsNode, (xbool)1);
          if ((InputAction == xInput || InputAction == xPrioInput) &&
              xIsPath(SignalId, (xIdNode)xEnvId, PrsNode->NameNode,
                      (xIdNode *)0, Path, &PathLength) == 1) {
            if (count) {
              (*count)++; /* Just count no output */
            }
            else {
              PRINTF5("%s%s  %s%c", SignalId->Name,
                      SignalId->First ? "()" : "",   /* Has parameters? */
                      xWri_SDL_PId(&(PrsNode->Self)), sep);
            }
          }
        }
      }
    }
  }
  for ( IdNode  = FromNode->First;
        IdNode != (xIdNode)0;
        IdNode  = IdNode->Suc ){
    xListAllEnvSignals(IdNode, sep, count);
  }
}


/*---+---------------------------------------------------------------
           xOutputFromEnv
-------------------------------------------------------------------*/
static void xOutputFromEnv (char * strVar)
{
  xxToken  Token;
  int      count = 0;

  xListAllEnvSignals(xSymbolTableRoot, ' ', &count);
  if (count == 0) {
    PRINTF("No signals to send\n");
    return;
  }

  Token = xScanToken(strVar);
  if (Token == xxEoln) {
    if (XNOTINCLUDEFILE) {
      /* If reading include file do no output Prompt
         to prevent UI from trigger on ": " in Prompt */
      PRINTF("Choose signal : ");
    }
    Token = xScanToken(strVar);
  }
  if (Token == xxEoln || Token == xxMinus) {
    xListAllEnvSignals(xSymbolTableRoot, '\n', NULL);
    return;
  }

  while (Token == xxQuestionMark || Token == xxEoln) {
    xListAllEnvSignals(xSymbolTableRoot, ' ', NULL);
    xPrintString(": ");
    if (Token != xxEoln)
      xSkipLine();
    Token = xScanToken(strVar);
  }
  if (Token == xxLBracket) { /* Cancel */
    return;
  }
  xUngetToken(Token, strVar);
  xOutputTo(26);   /* Output-To */
}


/*---+---------------------------------------------------------------
     xOutputNone
-------------------------------------------------------------------*/
static void xOutputNone (void)
{
  xStateIdNode    StateId;
  xPrsIdNode      ProcessId;
  xPrsIdNode      xIdNodeSender;
  xPrsNode        PrsNode;
  xPrsNode        PrsNodeSender;
  xIdNode        *ViaList;
  xSignalNode     Signal;
#if defined(XSIGPRIO) || defined(XSIGPRSPRIO) || defined(XPRSSIGPRIO)
  int             intVar;
#endif
#ifndef XNOUSEOFSERVICE
  xSrvNode        SrvNode;
  xSrvIdNode      ServiceId;
  xbool           xEmptyInput;
#endif

  PrsNode = xReadProcess("Process name : ", &ProcessId, (xIdNode)0);
  if (PrsNode == (xPrsNode)0)
    return;
#ifndef XNOUSEOFSERVICE
  if (PrsNode->ActiveSrv != (xSrvNode)0) {
    SrvNode  = xReadService("Service : ", &ServiceId, PrsNode, &xEmptyInput);
    if (SrvNode == (xSrvNode)0) {
      if (ServiceId != (xSrvIdNode)0) xPrintString("Service is stopped\n");
      return; 
    }
    StateId = xGetState(PrsNode, (xPrdNode)0, SrvNode->NameNode->StateList,
                      XPRS_STATEID(SrvNode));
    PrsNode->ActiveSrv = SrvNode;
  } else
#endif
    StateId = xGetState(PrsNode, (xPrdNode)0, PrsNode->NameNode->StateList,
                        XPRS_STATEID(PrsNode));
  while (StateId && ! HASINPUTNONE(StateId) && ! HASVIRTINPUTNONE(StateId) ) {
    StateId = StateId->Super;
  }
  if (! StateId) {
    xPrintString("No spontaneous transition in current state\n");
    return;
  }

  XCREATE_SIGNAL(&Signal, xNoneSigId, PrsNode->Self, PrsNode->Self)
  XSET_RECEIVER(Signal, PrsNode->Self)
  xIdNodeSender = PrsNode->NameNode;
  PrsNodeSender = PrsNode;
#if defined(XSIGPRIO) || defined(XSIGPRSPRIO) || defined(XPRSSIGPRIO)
  intVar = xDefaultPrioSignal;
#endif
  ViaList = (xIdNode *)0;
  xSysD.xMonitorOutput = (xbool)1;
#ifdef XTRACE
  xSysD.xSilent++;
#endif
  SEND_SIGNAL_IN_MONITOR
  xSysD.xMonitorOutput = (xbool)0;
#ifdef XTRACE
  xSysD.xSilent--;
#endif
  PRINTF2("Signal 'none' sent to %s\n", PrsNode->NameNode->Name);
  if (SIGNAL_IN_INPUT_PORT(Signal))
    xChangeScope(PrsNode);
}

/*---+---------------------------------------------------------------
           CdCommand
-------------------------------------------------------------------*/
static void CdCommand (char * strVar)
{
  char    *dirname = NULL;
  char    *ErrStr;
  xbool    minusGiven;

  if ( ! xGetDirectoryName("Working directory : ", strVar, &minusGiven) )
    return;

  if ( ! minusGiven ) {
    ErrStr = xSetWorkdir(strVar);
    if (ErrStr) {
      PRINTF2("Could not set current working directory : %s\n", ErrStr);
    }
  }
  ErrStr = xGetWorkdir(&dirname);
  if (ErrStr) {
    PRINTF2("Could not show current working directory : %s\n", ErrStr);
  }
  else {
    PRINTF2("Current working directory : %s\n", dirname);
  }
  if (dirname)
    free(dirname);
}


#ifdef XPERFSIM
/*---+---------------------------------------------------------------
           ListAtDelayCommand
-------------------------------------------------------------------*/
static void ListAtDelayCommand (void)
{
  int          count = 0;
  xSymbolType  S;
  xAtDelayNode BP;

  for (BP = xAtDelays;
       BP != (xAtDelayNode)0;
       BP = BP->Next) {
    PRINTF2("\n%d\n", ++count);
    PRINTF2("SDT reference : %s\n", BP->GRReference);
    if (BP->PrsIdNode->EC == xProcedureEC)
      (void)((xPrdIdNode)BP->PrsIdNode)->GRrefFunc(BP->SymbolNumber, &S);
#ifndef XNOUSEOFSERVICE
    else if (BP->PrsIdNode->EC == xServiceEC ||
             BP->PrsIdNode->EC == xServiceTypeEC)
      (void)((xSrvIdNode)BP->PrsIdNode)->GRrefFunc(BP->SymbolNumber, &S);
#endif
    else
      (void)((xPrsIdNode)BP->PrsIdNode)->GRrefFunc(BP->SymbolNumber, &S);
    PRINTF4("Object        : %s %s\nSymbol type   : %s\n",
            xEntityString[BP->PrsIdNode->EC],
            xWriteEntity(BP->PrsIdNode),
            xSymbolTypeStr[S]);
    PRINTF2("Delay value   : %d\n", BP->Delay);
  }
}

/*---+---------------------------------------------------------------
           SaveAtDelayCommand
-------------------------------------------------------------------*/
static void SaveAtDelayCommand (FILE * TempFile)
{
  xAtDelayNode BP;

  for (BP = xAtDelays;
       BP != (xAtDelayNode)0;
       BP = BP->Next) {
    fprintf(TempFile, "Define-At-Delay %s %d\n", BP->GRReference, BP->Delay);
  }
}

/*---+---------------------------------------------------------------
           ListDelayCommand
-------------------------------------------------------------------*/
static void ListDelayCommand (void)
{
  int i;

  for (i=0; i<xsNoSuchSymbolType; i++) {
    PRINTF3("%s : %d\n", xSymbolTypeStr2[i], xSymbolTimes[i]);
  }
  ListAtDelayCommand();
}

/*---+---------------------------------------------------------------
           DefineDelayCommand
-------------------------------------------------------------------*/
static void DefineDelayCommand (char * strVar)
{
  int      i;
  int      intVar;
  xxToken  Token;

  Token = xScanToken(strVar);
  if (Token == xxEoln) {
    PRINTF("Delay values : ");
    Token = xScanToken(strVar);
  }
  for (i=0; i<xsNoSuchSymbolType; i++) {
    while (Token == xxQuestionMark || Token == xxEoln) {
      PRINTF2("Delay value for %s : ", xSymbolTypeStr2[i]);
      if (Token != xxEoln)
        xSkipLine();
      Token = xScanToken(strVar);
    }
    if (Token == xxId) {
      if (sscanf(strVar, "%d", &intVar) != 1) {
        PRINTF("Illegal value\n");
        return;
      }
    }
    else if (Token == xxLBracket) {
      return;
    }
    else {
      PRINTF("Illegal value\n");
      return;
    }
    xSymbolTimes[i] = intVar;
    Token = xScanToken(strVar);
  }
}

/*---+---------------------------------------------------------------
           SaveDelayCommand
-------------------------------------------------------------------*/
static void SaveDelayCommand (char * strVar)
{
  int   i;
  FILE  * TempFile;

  if (! xGetAndOpenFile(&TempFile, (xbool)0, strVar, "com") )
    return;

  fprintf(TempFile, "Define-Delay");
  for (i=0; i<xsNoSuchSymbolType; i++) {
    fprintf(TempFile, " %d", xSymbolTimes[i]);
  }
  fprintf(TempFile, "\n");
  SaveAtDelayCommand(TempFile);
  if (TempFile != stdout)
    if (fclose(TempFile) != 0)
      PRINTF("Error saving delays\n");
  PRINTF2("Delays saved on file %s\n", strVar);
}


/*---+---------------------------------------------------------------
           DefineAtDelayCommand
-------------------------------------------------------------------*/
static void DefineAtDelayCommand (char * strVar)
{
  int          intVar = -99;
  xxToken      Token;
  xIdNode      PrsIdNode;
  long int     SymbolNumber;
  xAtDelayNode BP;
  xAtDelayNode NewBP;
  xSymbolType  S;

  if ( ! xGetSDTRef(strVar, &PrsIdNode, &SymbolNumber) )
    return;

  NewBP = (xAtDelayNode)xAlloc((xptrint)sizeof(*NewBP));
  NewBP->Next = (xAtDelayNode)0;
  NewBP->GRReference = (char *)xAlloc((xptrint)(strlen(strVar) + 1));
  strcpy(NewBP->GRReference, strVar);
  NewBP->PrsIdNode = PrsIdNode;
  NewBP->SymbolNumber = SymbolNumber;

  Token = xPromptQuestionMark("Delay value : ", "integer >= 0 : ", strVar);
  if (Token != xxLBracket && sscanf(strVar, "%d", &intVar) != 1) {
    PRINTF("Illegal input\n");
  }

  if (intVar == -99) {
    xFree((void **)&NewBP->GRReference);
    xFree((void **)&NewBP);
    return;
  }

  NewBP->Delay = intVar;
  if (xAtDelays == (xAtDelayNode)0) {
    xAtDelays = NewBP;
  }
  else {
    for ( BP = xAtDelays;
          BP->Next != (xAtDelayNode)0;
          BP = BP->Next )
      ;
    BP->Next = NewBP;
  }
  PRINTF2("\nNew delay at : %s\n", NewBP->GRReference);
  if (NewBP->PrsIdNode->EC == xProcedureEC)
    (void)((xPrdIdNode)NewBP->PrsIdNode)->GRrefFunc(NewBP->SymbolNumber, &S);
#ifndef XNOUSEOFSERVICE
  else if (NewBP->PrsIdNode->EC == xServiceEC ||
           NewBP->PrsIdNode->EC == xServiceTypeEC)
    (void)((xSrvIdNode)NewBP->PrsIdNode)->GRrefFunc(NewBP->SymbolNumber, &S);
#endif
  else
    (void)((xPrsIdNode)NewBP->PrsIdNode)->GRrefFunc(NewBP->SymbolNumber, &S);
  PRINTF4("Object       : %s %s\nSymbol type  : %s\n",
     xEntityString[NewBP->PrsIdNode->EC],
     xWriteEntity(NewBP->PrsIdNode),
     xSymbolTypeStr[S]);
  PRINTF2("Delay value  : %d\n", NewBP->Delay);
}

/*---+---------------------------------------------------------------
           RemoveDelayCommand
-------------------------------------------------------------------*/
static void RemoveDelayCommand (char * strVar)
{
  int          No = 0;
  xIdNode      PrsIdNode;
  long int     SymbolNumber;
  xAtDelayNode BP;
  xAtDelayNode BPNext;
  xAtDelayNode BPLoop;

  if (xAtDelays == (xAtDelayNode)0) {
    PRINTF("No graphical delays defined\n");
    return;
  }

  if ( ! xGetSDTRef(strVar, &PrsIdNode, &SymbolNumber) )
    return;

  BP = xAtDelays;
  while (BP) {
    BPNext = BP->Next;
    if (BP->PrsIdNode == PrsIdNode && BP->SymbolNumber == SymbolNumber) {
      if (BP == xAtDelays)
        xAtDelays = BPNext;
      else {
        for (BPLoop = xAtDelays;
             BPLoop->Next;
             BPLoop = BPLoop->Next) {
          if (BPLoop->Next == BP)
            break;
        }
        BPLoop->Next = BP->Next;
      }
      xFree((void **)&BP->GRReference);
      xFree((void **)&BP);
      No++;
    }
    BP = BPNext;
  }
  if (No == 1) {
    PRINTF2("\n%d delay removed\n", No);
  }
  else {
    PRINTF2("\n%d delays removed\n", No);
  }
}
#endif


static int xContinueMode = 0;
static int xShouldContinue = 0;
static xbool WasForked = (xbool)0;
int xDisplayArrayWithIndex = 0;

/*---+---------------------------------------------------------------
     xCheckMonitors
-------------------------------------------------------------------*/
void xCheckMonitors (void)
{
#ifdef XCLOCK
  SDL_Time      xTimeEnteringMonitor;
#endif
  int           xCont;
  SDL_Time      timeVar;
  xPrsIdNode    ProcessId;
  XSIGTYPE      TimerId;
  xMonitorCommandIdNode CommandIdNode;
  char          strVar[MAX_READ_LENGTH];
  xxToken       Token;
  int           intVar, No;
  xPrsNode      PrsNode;
  int           count;
  xSignalNode   Signal;
  xSignalNode   tmpT;
  xPrsNode      tmpPrs;
  xbool         EmptyLine;
  xbool         xEmptyInput;
  FILE        * TempFile;
  xbool         WasInterrupted = (xbool)0;
  int           choice;
#ifdef XCONNECTPM
  char        * targetDir;
#endif
  long int      SymbolNumber;
  char          strVar2[256];
  int           i2;
  int           i3;
  xCommandFileNode NewCF;

#ifndef XNOSELECT
  if (! xSysD.Interrupted && xSysD.xDoCheckForInput)
    if (xCheckForInput())
      xSysD.Interrupted = 1;
#endif

  if (xSysD.Interrupted) {
    xSysD.StopInMonitor = 1;
    xSysD.Interrupted = 0;
    WasInterrupted = (xbool)1;
    if (xContinueMode)
      xShouldContinue = 1;
    else
      xPrintString("\nExecution interrupted by user\n");
    if (xSysD.CommandFile && ! WasBreakAfter) {
      fclose(xSysD.CommandFile->File);
      if (xSysD.CommandFile->Next != (xCommandFileNode)0) {
        fclose(xSysD.CommandFile->Next->File);
        for (i3=0; i3<99; i3++)
          xFree((void **)&xSysD.CommandFile->Next->A[i3]);
        xFree((void **)&xSysD.CommandFile->Next);
      }
      xSysD.CommandFile = NULL;
    }
    if (! XREADYQ_EMPTY)
      xIdentifyTransition(XREADYQ_FIRST, "");
  }

  if (xSysD.xProceedUntil == 0 && xSysD.xGoForever == 0)
    if (XREADYQ_EMPTY && XTIMERQ_EMPTY)
      xSysD.StopInMonitor = 1;

  if (xSysD.xProceedUntil == 1 &&
      xLE_SDL_Time(xSysD.xNextMonTimeVar, SDL_Now())) {
    xSysD.StopInMonitor = 1;
    xSysD.xNextMonTimeVar = xMaxTime;
    xSysD.xProceedUntil = 0;
  }

#ifdef XCLOCK
  if (xSysD.xProceedUntil == 3) {
#else
  if (xSysD.xProceedUntil == 2 &&
      XREADYQ_EMPTY && ! XTIMERQ_EMPTY) {
    xSysD.xSystemTime = XFIRST_TIMER_TIME;
#endif
    xSysD.StopInMonitor = 1;
    xSysD.xProceedUntil = 0;
  }

  if (xSysD.xDynamicError) {
    xSysD.xDynamicError = (xbool)0;
    xSysD.StopInMonitor = 1;
  }

  if (! XREADYQ_EMPTY && ! XREADYQ_FIRST->InTransition) {
    if (xCheckBreakpoint(XREADYQ_FIRST)) {
      xSysD.StopInMonitor = 1;
      xIdentifyTransition(XREADYQ_FIRST, "");
    }
    tmpPrs = XREADYQ_FIRST;
#ifndef XNOUSEOFSERVICE
    if (tmpPrs->ActiveSrv) {
      if (tmpPrs->ActiveSrv->ActivePrd)
        SymbolNumber = tmpPrs->ActiveSrv->ActivePrd->RestartAddress;
      else
        SymbolNumber = tmpPrs->ActiveSrv->RestartAddress;
    }
    else {
#endif
      if (tmpPrs->ActivePrd)
        SymbolNumber = tmpPrs->ActivePrd->RestartAddress;
      else
        SymbolNumber = tmpPrs->RestartAddress;
#ifndef XNOUSEOFSERVICE
    }
#endif
    if (xCheckBreakpointAt(XREADYQ_FIRST, SymbolNumber)) {
      xSysD.StopInMonitor = 1;
    }
  }

  if (xSysD.StopInMonitor != 1) {
#ifdef XPERFSIM
    if (! XREADYQ_EMPTY && ! XREADYQ_FIRST->InTransition) {
      xPerfSim(-1, (xbool)0);
    }
#endif
    return;
  }

#ifdef XCLOCK
  xTimeEnteringMonitor = SDL_Clock();
#endif

  if (xSysD.WelcomeMessagePrinted == 0) {
    xPrintString("\nWelcome to the SDL SIMULATOR. Simulating system ");
    xSysD.SystemName = xGetSystemIdNode((xIdNode)0)->Name;
    xPrintString(xSysD.SystemName);
    xPrintString(".\n");
    xSysD.WelcomeMessagePrinted = 1;
    if (xSysD.xCommandTable == (xIdNode)0)
      xInitMonitorCommands();
#ifdef XCONNECTPM
    targetDir = xGetTargetDirectory();
    if (targetDir) {
      (void)xSetWorkdir(targetDir);
      free(targetDir);
    }
    xInitGRConversion();
#endif
    /* Try to open siminit.com */
    TempFile = fopen("siminit.com", "r");
    if (TempFile) {
      xSysD.CommandFile =
        (xCommandFileNode)xAlloc((xptrint)sizeof( xCommandFileRec ));
      xSysD.CommandFile->File = TempFile;
    }
  }
  xSysD.NowInMonitor = SDL_Now();
  if ( ! xShouldContinue ) {
    xSysD.xNextMonTimeVar = xMaxTime;
    xSysD.xProceedUntil = 0;
    xSysD.xGoForever = 0;
    xSysD.StepSymbol = 0;
    xSysD.StepStatement = 0;
    xSysD.NextSymbol = 0;
    xSysD.NextStatement = 0;
    xSysD.Finish = 0;
    xSysD.NextLevel = 0;
    xSysD.xStepToVisible = 0;
  }
  xCont = 1;
  xSysD.StoppedInMonitor = 1;
  xInitScope();
  xPrintScope((xbool)0);
  while (xCont) {
#ifdef XSIMULATORUI
    if (PrintToxTrStr) {
      xSendxTrStrReply(CommandSourcePId, xTrStr);
      PrintToxTrStr = 0;
    }
#endif
    if (*xInputPos == '\0') {
#ifdef XSIMULATORUI
      if (xSysD.xNoticeBoard.SimulatorUIStarted) {
        if ( ! WasInterrupted || WasBreakAfter ) {
          xPrintString("\nCommand :");
          xPrintString(" ");
        }
      } else {
        xPrintString("\nCommand : ");
      }

      if (xSysD.CommandFile == NULL) {
        if (xSysD.WelcomeMessagePrinted == 1) {
          if (xSysD.xNoticeBoard.SimulatorUIStarted)
            xSendUIChange();
          xSysD.WelcomeMessagePrinted = 2;
        } else if (WasInterrupted && ! WasBreakAfter) {
          WasInterrupted = (xbool)0;
        } else if (xSysD.xNoticeBoard.PMConnected &&
                 xSysD.xNoticeBoard.SimulatorUIStarted) {
          if (WasBreakAfter) {
            WasInterrupted = (xbool)0;
            WasBreakAfter = (xbool)0;
          }
          xSendCommandReply();
          xSendUIChange();
        }
      }
#else
      xPrintString("\nCommand : ");
#endif
    }
#ifndef XNOSELECT
#if defined(XENV) || defined(XCONNECTPM)
    if (xSysD.CommandFile == NULL)
    if (xSysD.xDoLoopForInput)
    if (*xInputPos == '\0')
      xLoopForInput();
#endif
#endif
    EmptyLine = (xbool)0;
    Token = xScanToken(strVar);
#ifdef XSIMULATORUI
    if (Token == xxEoln && ! xSysD.SESIMUICOMFlag)
#else
    if (Token == xxEoln)
#endif
      EmptyLine = (xbool)1;
    else  if (Token == xxQuestionMark) {
      Token = xScanToken(strVar);
      switch (Token) {
      case xxQuestionMark:
        xSkipLine();
        /* fall through */
      case xxEoln:
        xPrintString("Enter a command : ");
        Token = xScanToken(strVar);
        if (Token == xxQuestionMark) {
          xSkipLine();
          xMonListIdNodeECSet(1L<<((long)xMonitorCommandEC),
                              xSysD.xCommandTable, (xIdNode)0, (xbool)0);
          xPrintString(": ");
          Token = xScanToken(strVar);
        }
        break;
      default:
        break;
      }
      if (Token == xxEoln)
        EmptyLine = (xbool)1;
    }
    if (xShouldContinue) {
      xShouldContinue = 0;
      if ( ! EmptyLine ) {
        xCont = 0;
        xSysD.StopInMonitor = 0;
      }
    }
    if (EmptyLine) {
      if (Token != xxEoln) xSkipLine();
      continue;
    }

    CommandIdNode = xGetCommand(strVar, Token, xSysD.xCommandTable);
    if (CommandIdNode == (xMonitorCommandIdNode)0) {
      xSkipLine();
      continue;
    }
    switch (CommandIdNode->CommandNo) {

    case  1:      /* Help */
      xGetHelp(strVar, (xbool)1);
      break;

    case  62:     /* News */
      xGetHelp(strVar, (xbool)0);
      break;

    case  2:      /* Now */
#ifdef XCALENDARCLOCK
      PRINTF2("Now = %s\n", xWriteNow(SDL_Now()));
#else
      PRINTF2("Now = %s\n", xWriteNow(xSysD.NowInMonitor));
#endif
      break;

    case  3:      /* Quit */

    case 53:      /* Exit */
      if (xfEqualIdString(strVar, "Quit") != 2 &&
          xfEqualIdString(strVar, "Exit") != 2)      /* Not exact match */
        if ( ! xVerify("Do you really want to exit program : "))
          break;
      xPrintString("Simulation terminated\n");
#ifdef XSIMULATORUI
      if (xSysD.xNoticeBoard.SimulatorUIStarted) {
        xSendCommandReply();
      }
#endif
      if (WasForked) {
        xHalt();
      }
      else {
        SDL_Halt();
      }
      break;

    case 37:      /* Stack */
      xStackCom();
      break;

    case 59:      /* Scope */
      xPrintScope((xbool)1);
      break;

    case 60:      /* Set-Scope */
      xSetScope();
      break;

    case 51:      /* Up */
      xUpCom();
      break;

    case 52:      /* Down */
      xDownCom();
      break;

    case 12:      /* List-Ready-Queue */
      if (XREADYQ_EMPTY) {
        xPrintString("The ready queue is empty\n");
        break;
      }
      xPrintString("Entry ");
      xWriteProcessHeading();
      No = 0;
      XBEGIN_PRS_READYQ_LOOP(tmpPrs)
        PRINTF2("%-6d", ++No);
        WriteProcessInfo(tmpPrs, "      ");
      XEND_PRS_READYQ_LOOP
      break;

#ifdef XGRTRACE
    case  58:     /* Set-GR-Trace */
    case  61:     /* Reset-GR-Trace */
      xSetResetTrace(CommandIdNode->CommandNo);
      break;
#endif

#ifdef XMSCE
    case  89:     /* Set-MSC-Trace */
    case  90:     /* Reset-MSC-Trace */
      if (xSysD.MSCLogStarted)
        xPrintString("Cannot change MSC trace when MSC-Log started\n");
      else
        xSetResetTrace(CommandIdNode->CommandNo);
      break;
#endif

    case  4:      /* Set-Trace */
    case  8:      /* Reset-Trace */
      xSetResetTrace(CommandIdNode->CommandNo);
      break;

    case 9:      /* Print-Paths */
      xPrintChannel(xSymbolTableRoot, -1);
      xPrintString("\n");
      break;

    case 10:     /* SymbolTable */
      Token = xScanToken(strVar);
      if ( Token != xxEoln ) {
        xSortIdNode SortNode;
        xIdNode     saveSuc;

        if ( Token != xxQuestionMark )
          xUngetToken(Token, strVar);
        /* Read sort node */
        SortNode = (xSortIdNode)xGetIdNodeInECSet("Sort name : ",
                                                  1L<<((long)xSortEC),
                                                  (xIdNode)xSymbolTableRoot,
                                                  &xEmptyInput, (xbool)1, NULL);
        if ( ! xEmptyInput ) {
          if (SortNode) {
            saveSuc = SortNode->Suc;
            SortNode->Suc = NULL;
            xSymbolTable((xIdNode)SortNode, 0);
            SortNode->Suc = saveSuc;
          }
          break;
        }
      }
      xSymbolTable(xSymbolTableRoot, -1);
      break;

    case 13:      /* List-Process */
      ProcessId = (xPrsIdNode)xGetIdNodeInECSet("Process name : ",
          1L<<((long)xProcessEC), xSymbolTableRoot,
          &xEmptyInput, (xbool)1, (xIdNode)0);
      if (xEmptyInput) {
        xWriteProcessHeading();
        xListAllPId(xSymbolTableRoot);
        break;
      }
      if (ProcessId == (xPrsIdNode)0)
        break;
      if (*ProcessId->ActivePrsList == (xPrsNode)0) {
        xPrintString("No active instance\n");
        break;
      }
      xWriteProcessHeading();
      for (PrsNode = *ProcessId->ActivePrsList;
           PrsNode != (xPrsNode)0;
           PrsNode = PrsNode->NextPrs) {
        WriteProcessInfo(PrsNode, "");
      }
      break;

    case 14:      /* List-Input-Port */
      xListInputPort(strVar);
      break;

    case 15:      /* List-Timer */
      if (XTIMERQ_EMPTY) {
        xPrintString("The timer queue is empty\n");
        break;
      }
      xWriteBuf_Fmt("%-8s%-*s%-*sTime\n",
            "Entry",
            xfShortIdentifierLength+1,
            "Timer name",
            xfShortIdentifierLength+6,
            "PId");
      count = 0;
      XBEGIN_TIMERQ_LOOP(tmpT)
        xWriteBuf_Fmt("%-8d%-*s%-*s%s\n",
		      ++count,
		      xfShortIdentifierLength+1,
		      XTIMER_IDNODE(tmpT)->Name,
		      xfShortIdentifierLength+6,
		      xWri_SDL_PId(&(XTIMER_RECEIVER(tmpT))),
		      xWriteNow(((xTimerNode)tmpT)->TimerTime)
		      );
      XEND_TIMERQ_LOOP
      break;

    case 16:      /* Examine-PId */
      xExaminePId(strVar);
      break;

    case 17:      /* Examine-Signal-Instance */
      if (xSysD.xPrsScope == (xPrsNode)0) {
        xPrintScope((xbool)1);
        break;
      }
      PrsNode = xSysD.xPrsScope;
      count = SignalsInPort(PrsNode);
      if (count == 0) {
        xPrintString("The input port is empty\n");
        break;
      }
      if ( ! xReadEntryNumber("Input port entry : ", &intVar, count))
        break;
      No = 0;
      XBEGIN_INPUTPORT_LOOP(PrsNode, Signal)
        if (! XIS_STARTUP_SIGNAL(Signal))
          No++;
        if (No == intVar) {
          if (! XIS_CONT_SIGNAL(Signal)) {
            PRINTF2("Signal name : %s\n", 
                    xWriteEntity((xIdNode)XSIGNAL_IDNODE(Signal)));
            xWriteSignalParameters(Signal, "");
          }
          else {
            PRINTF2("Continuous signal, priority %d\n", XCONT_SIG_PRIO(Signal));
          }
          break;
        }
      XEND_INPUTPORT_LOOP
      break;

    case 18:      /* Examine-Timer-Instance */
      if (XTIMERQ_EMPTY) {
        xPrintString("The timer queue is empty\n");
        break;
      }
      count = 0;
      XBEGIN_TIMERQ_LOOP(tmpT)
        ++count;
      XEND_TIMERQ_LOOP
      if ( ! xReadEntryNumber("Timer queue entry : ", &intVar, count))
        break;
      No = 1;
      XBEGIN_TIMERQ_LOOP(tmpT)
        if (No == intVar) {
          PRINTF2("Timer name : %s\n", XTIMER_IDNODE(tmpT)->Name);
          xWriteSignalParameters(XTIMERSIGNAL(tmpT), "");
          break;
        }
        No++;
      XEND_TIMERQ_LOOP
      break;

    case 19:      /* Examine-Variable */
      xExamineVariable(strVar);
      break;

    case 113:     /* Display-Array-With-Index */
      choice = xChoose2( "Display-Array-With-Index(on/off) : ", "On", "Off" );
      if (choice==1) {
        xDisplayArrayWithIndex = 1;
        xPrintString("Display-Array-With-Index is now on\n");
      } else if (choice==2) {
        xDisplayArrayWithIndex = 0;
        xPrintString("Display-Array-With-Index is now off\n");
      } else {
        PRINTF2( "Display-Array-With-Index not changed (%s).\n",
                 xDisplayArrayWithIndex ? "On" : "Off");
      }
      break;
 
    case 20:      /* Go */
      if (XREADYQ_EMPTY && XTIMERQ_EMPTY) {
        xPrintString("No process instance scheduled for a transition\n");
        break;
      }
      xSysD.StopInMonitor = 0;
      xCont = 0;
      break;

    case 21:      /* Next-Transition */
      if (XREADYQ_EMPTY && XTIMERQ_EMPTY) {
        xPrintString("No process instance scheduled for a transition\n");
        break;
      }
      xSysD.StopInMonitor = 1;
      xCont = 0;
      break;

    case 22:      /* Proceed-Until */
      if ( ! xReadTime("Time : ", &timeVar))
        break;
#ifdef XCALENDARCLOCK
      if (xLT_SDL_Time(timeVar, SDL_Now())) {
#else
      if (xLT_SDL_Time(timeVar, xSysD.NowInMonitor)) {
#endif
        xPrintString("Time value less than now\n");
        break;
      }
      xSysD.StopInMonitor = 0;
      xCont = 0;
      xSysD.xProceedUntil = 1;
      xSysD.xNextMonTimeVar = timeVar;
      break;

    case 23:      /* Proceed-To-Timer */
      if (XREADYQ_EMPTY && XTIMERQ_EMPTY) {
        xPrintString("No process instance scheduled for a transition\n");
        break;
      }
#ifndef XCLOCK
      if (XREADYQ_EMPTY && ! XTIMERQ_EMPTY) {
        xSysD.xSystemTime = XFIRST_TIMER_TIME;
        xSysD.NowInMonitor = SDL_Now();
        PRINTF2("Now = %s\n", xWriteNow(xSysD.NowInMonitor));
        break;
      }
#endif
      xSysD.StopInMonitor = 0;
      xCont = 0;
      xSysD.xProceedUntil = 2;
      break;

    case 24:      /* Next-Visible-Transition */
      if (XREADYQ_EMPTY && XTIMERQ_EMPTY) {
        xPrintString("No process instance scheduled for a transition\n");
        break;
      }
      xSysD.xStepToVisible = 1;
      xSysD.StopInMonitor = 0;
      xCont = 0;
      break;

    case 25:      /* Output-Internal */
    case 26:      /* Output-To */
      xOutputTo(CommandIdNode->CommandNo);
      break;

    case 27:      /* Output-Via */
      xOutputVia();
      break;

    case 108:     /* Output-From-Env */
      xOutputFromEnv(strVar);
      break;

    case 28:      /* Log-On */
      if (xSysD.InteractionLog.Active) {
        xPrintString("Log is already active\n");
        break;
      }
      Token = xScanToken(strVar);
      if (Token == xxEoln && xSysD.InteractionLog.File != NULL) {
        xSysD.InteractionLog.File = fopen(xSysD.InteractionLog.Filename, "a");
        xSysD.InteractionLog.Active = (xbool)1;
        break;
      }
      xUngetToken(Token, strVar);
      if (! xGetAndOpenFile(&TempFile, (xbool)0, strVar, "log") )
        break;
      strcpy(xSysD.InteractionLog.Filename, strVar);
      if ( ! strcmp(xSysD.InteractionLog.Filename, "xNoEcho.log") ) {
        PRINTF("No output on console. Give log-off to restore output.\n");
      }
      xSysD.InteractionLog.File = TempFile;
      xSysD.InteractionLog.Active = (xbool)1;
      break;

    case 29:      /* Log-Off */
      if ( ! xSysD.InteractionLog.Active) {
        xPrintString("Log is not active\n");
        break;
      }
      if (xSysD.InteractionLog.File != NULL)
        if (fclose(xSysD.InteractionLog.File) != 0)
           xPrintString("Error closing Interaction Logfile\n");
      xSysD.InteractionLog.Active = (xbool)0;
      break;

    case 31:      /* Show-Breakpoint */
      xShowBreakpointAt();
      break;

    case 30:     /* Remove-At */
      xRemoveBreakpointAt(strVar);
      break;

    case 32:      /* Breakpoint-Variable */
      xSetBreakpointVariable(strVar);
      break;

    case 33:      /* Breakpoint-At */
      xSetBreakpointAt(strVar);
      break;

    case 34:      /* Breakpoint-Transition */
      xSetBreakpoint();
      break;

    case 35:      /* Remove-Breakpoint */
      xRemoveBreakpoint();
      break;

    case 135:     /* Remove-All-Breakpoints */
      xRemoveAllBreakpoints();
      break;

    case 36:      /* Breakpoint-Output */
      xSetBreakpointOutput();
      break;

    case 38:      /* List-Breakpoints */
      xListBreakpoints();
      break;

    case 138:     /* Save-Breakpoints */
      xSaveBreakpoints(strVar);
      break;

    case 39:      /* Create */
      xCreateCom();
      break;

    case 40:      /* Nextstate */
      xNextStateCom();
      break;

    case 41:      /* Stop */
      xStopCom();
      break;

    case 42:      /* Assign-Value */
      xAssignValue(strVar);
      break;

    case 43:      /* Set-Timer */
      if (xSysD.xPrsScope == (xPrsNode)0) {
        xPrintScope((xbool)1);
        break;
      }
      PrsNode = xSysD.xPrsScope;
#ifndef XNOUSEOFSERVICE
      if (xSysD.xSrvScope != (xSrvNode)0)
        TimerId = (XSIGTYPE)xGetIdNodeInECSet("Timer name : ",
          1L<<((long)xTimerEC), (xIdNode)xSysD.xSrvScope->NameNode,
          &xEmptyInput, (xbool)0, (xIdNode)0);
      else
#endif
        TimerId = (XSIGTYPE)xGetIdNodeInECSet("Timer name : ",
          1L<<((long)xTimerEC), (xIdNode)PrsNode->NameNode, &xEmptyInput,
          (xbool)0, (xIdNode)0);
      if (TimerId == (XSIGTYPE)0) break;
#ifndef XNO_MONITOR_CHANGES
      if (! xReadSignalParameters(TimerId, &Signal, PrsNode->Self) ) {
        XRELEASE_SIGNAL(Signal);
        break;
      }
      if ( ! xReadTime("Time : ", &timeVar)) {
        XRELEASE_SIGNAL(Signal);
        break;
      }
#ifdef XTRACE
      xSysD.xSilent++;
#endif
#ifdef XCLOCK
      xSysD.xTimeInMonitor = xPlus_SDL_Duration(xSysD.xTimeInMonitor,
        xMinusT_SDL_Time(SDL_Clock(), xTimeEnteringMonitor));
      xTimeEnteringMonitor = SDL_Clock();
#endif
      SDL_Set(timeVar, Signal);
#ifdef XTRACE
      xSysD.xSilent--;
#endif
      PRINTF2("Set action performed for timer %s\n", TimerId->Name);
#else
      xPrintString("Set action not implemented\n");
#endif
      break;

    case 44:      /* Reset-Timer */
      if (xSysD.xPrsScope == (xPrsNode)0) {
        xPrintScope((xbool)1);
        break;
      }
      PrsNode = xSysD.xPrsScope;
#ifndef XNOUSEOFSERVICE
      if (xSysD.xSrvScope != (xSrvNode)0)
        TimerId = (XSIGTYPE)xGetIdNodeInECSet("Timer name : ",
          1L<<((long)xTimerEC), (xIdNode)xSysD.xSrvScope->NameNode,
          &xEmptyInput, (xbool)0, (xIdNode)0);
      else
#endif
        TimerId = (XSIGTYPE)xGetIdNodeInECSet("Timer name : ",
          1L<<((long)xTimerEC), (xIdNode)PrsNode->NameNode, &xEmptyInput,
          (xbool)0, (xIdNode)0);
      if (TimerId == (XSIGTYPE)0) break;
#ifndef XNO_MONITOR_CHANGES
      if (! xReadSignalParameters(TimerId, &Signal, PrsNode->Self) ) {
        XRELEASE_SIGNAL(Signal);
        break;
      }
#ifdef XTRACE
      xSysD.xSilent++;
#endif
      SDL_Reset(&Signal);
#ifdef XTRACE
      xSysD.xSilent--;
#endif
      PRINTF2("Reset action performed for timer %s\n", TimerId->Name);
#else
      xPrintString("Reset action not implemented\n");
#endif
      break;

    case 45:      /* Remove-Signal-Instance */
      if (xSysD.xPrsScope == (xPrsNode)0) {
        xPrintScope((xbool)1);
        break;
      }
      PrsNode = xSysD.xPrsScope;
      count = SignalsInPort(PrsNode);
      if (count == 0) {
        xPrintString("The input port is empty\n");
        break;
      }
      if ( ! xReadEntryNumber("Input port entry : ", &intVar, count))
        break;
#ifndef XNO_MONITOR_CHANGES
      Signal = PrsNode->InputPort.Suc;
      if (Signal != (xSignalNode)&PrsNode->InputPort) {
        if (XIS_STARTUP_SIGNAL(Signal))
          Signal = Signal->Suc;
        No = 1;
        while (Signal != (xSignalNode)&PrsNode->InputPort) {
          if (No == intVar) {
            xRemoveFromQueue((void *)Signal);
            if (Signal == XPRS_NEXT_REC_SIG(PrsNode)) {
              XPRS_NEXT_REC_SIG(PrsNode) = (xSignalNode)0;
#ifdef XTRACE
              xSysD.xSilent++;
#endif
              SDL_NextState(PrsNode, xFindState(PrsNode));
#ifdef XTRACE
              xSysD.xSilent--;
#endif
            }
            PRINTF2("Signal %s removed\n", 
                    xWriteEntity((xIdNode)XSIGNAL_IDNODE(Signal)));
            XRELEASE_SIGNAL(Signal);
            break;
          }
          Signal = Signal->Suc;
          No++;
        }
      }
#else
      xPrintString("Removing signals not implemented\n");
#endif
      break;

#ifdef XCOVERAGE
    case 46:      /* Print-Coverage-Table */
      if (! xGetAndOpenFile(&xSysD.xCoverageFile, (xbool)0, strVar, "cov") )
        break;
      xPrintCoverageArray(xSymbolTableRoot, 1, 1);
      xPrintCoverageArray(xSymbolTableRoot, 1, 2);
      if (xSysD.xCoverageFile != stdout)
        if (fclose(xSysD.xCoverageFile) != 0)
          xPrintString("Error closing Test coverage file\n");
      PRINTF2("Test coverage table printed on file %s\n", strVar);
      break;

    case 5:      /* Clear-Coverage-Table */
      xClearCoverage(xSymbolTableRoot);
      xPrintString("Coverage table cleared\n");
      break;

#ifdef XCONNECTPM
    case 6:      /* Show-Coverage-Viewer */
      xShowCoverageViewer();
      break;
#endif
#endif

    case 54:      /* List-Trace-Values */
#ifdef XTRACE
      WriteTraces(xSymbolTableRoot);
#else
      xPrintString("Trace not included\n");
#endif
      break;

    case 55:      /* Rearrange-Input-Port */
      xRearrangeInputPort();
      break;

    case 56:      /* Rearrange-Ready-Queue */
      xRearrangeReadyQueue();
      break;

    case 57:      /* Output-None */
      xOutputNone();
      break;
      
#ifdef XGRTRACE
    case 63:      /* List-GR-Trace-Values */
      WriteGRTraces(xSymbolTableRoot);
      break;
#endif

    case 64:      /* Step-Symbol */
      if (XREADYQ_EMPTY && XTIMERQ_EMPTY) {
        xPrintString("No process instance scheduled for a transition\n");
        break;
      }
      xSysD.StepSymbol = xReadNumberOfSteps();
      xSysD.StopInMonitor = 1;
      xCont = 0;
      break;

    case 47:      /* Next-Symbol */
      if (XREADYQ_EMPTY && XTIMERQ_EMPTY) {
        xPrintString("No process instance scheduled for a transition\n");
        break;
      }
      xSysD.NextLevel = xGetPrdLevel();
      xSysD.NextSymbol = xReadNumberOfSteps();
      xSysD.StopInMonitor = 1;
      xCont = 0;
      break;

    case 48:      /* Next-Statement */
      if (XREADYQ_EMPTY && XTIMERQ_EMPTY) {
        xPrintString("No process instance scheduled for a transition\n");
        break;
      }
      xSysD.NextLevel = xGetPrdLevel();
      xSysD.NextStatement = xReadNumberOfSteps();
      xSysD.StopInMonitor = 1;
      xCont = 0;
      break;

    case 49:      /* Step-Statement */
      if (XREADYQ_EMPTY && XTIMERQ_EMPTY) {
        xPrintString("No process instance scheduled for a transition\n");
        break;
      }
      xSysD.StepStatement = xReadNumberOfSteps();
      xSysD.StopInMonitor = 1;
      xCont = 0;
      break;

    case 50:      /* Finish */
      if (XREADYQ_EMPTY && XTIMERQ_EMPTY) {
        xPrintString("No process instance scheduled for a transition\n");
        break;
      }
      xSysD.NextLevel = xGetPrdLevel();
      xSysD.Finish = 1;
      xSysD.StopInMonitor = 1;
      xCont = 0;
      break;

    case 65:      /* Show-Versions */
      PRINTF2("%s\n", xTranslatorVersion);
      PRINTF2("%s\n", xKernelVersion);
      break;

    case 66:      /* Signal-Log */
      xSetSignalLog(strVar);
      break;

    case 67:      /* Close-Signal-Log */
      xCloseSignalLog();
      break;

    case 68:      /* List-Signal-Log */
      xListSignalLog();
      break;

#ifdef XPMCOMM
    case 69:     /* Start-SDL-Env */
      if ( ! xSysD.xNoticeBoard.PMConnected ) {
        xPrintString("No connection with the Postmaster\n");
        break;
      }
      if ( xSysD.xNoticeBoard.CommStarted ) {
        xPrintString("Handling of SDL environment already on\n");
        break;
      }
#ifdef XITEXCOMM
      if ( xSysD.xNoticeBoard.ITEXCommStarted ) {
        xPrintString("You cannot have both ITEX communication and communicating\n");
        xPrintString("simulation at the same time\n");
        break;
      }
#endif
      if ( xSysD.xNoticeBoard.PMConnected )
        xSysD.xNoticeBoard.CommStarted = (xbool)1;
      xPrintString("Handling of SDL environment started\n");
      break;

    case 70:     /* Stop-SDL-Env */
      if ( ! xSysD.xNoticeBoard.PMConnected ) {
        xPrintString("No connection with the Postmaster\n");
        break;
      }
      if ( ! xSysD.xNoticeBoard.CommStarted ) {
        xPrintString("Handling of SDL environment already off\n");
        break;
      }
      xSysD.xNoticeBoard.CommStarted = (xbool)0;
      xPrintString("Handling of SDL environment stopped\n");
      break;

    case 71:     /* Call-SDL-Env */
      if ( ! xSysD.xNoticeBoard.PMConnected ) {
        xPrintString("No connection with the Postmaster\n");
        break;
      }
      xPrintString(
        "Checking for incoming signals from the Postmaster\n");
      xInPM();
      break;
#endif

#ifdef XITEXCOMM
    case 82:     /* Start-ITEX-Com */
      if ( ! xSysD.xNoticeBoard.PMConnected ) {
        xPrintString("No connection with the Postmaster\n");
        break;
      }
      if ( xSysD.xNoticeBoard.ITEXCommStarted ) {
        xPrintString("Handling of ITEX communication already on\n");
        break;
      }
      if ( xSysD.xNoticeBoard.CommStarted ) {
        xPrintString("You cannot have both ITEX communication and communicating\n");
        xPrintString("simulation at the same time\n");
        break;
      }
      if ( xSysD.xNoticeBoard.PMConnected )
        xSysD.xNoticeBoard.ITEXCommStarted = (xbool)1;
      xPrintString("Handling of ITEX communication started\n");
      break;

    case 111: {   /* ITEX-Channel */
      xChannelIdNode  channel;

      if ( ! xSysD.xNoticeBoard.PMConnected ) {
        xPrintString("No connection with the Postmaster\n");
        break;
      }

      channel = (xChannelIdNode)xGetIdNodeInECSet("Channel name : ", 
                                                  1L<<((long)xChannelEC),
                                                  xSymbolTableRoot,
                                                  &xEmptyInput,
                                                  (xbool)0, (xIdNode)xEnvId);
      if ( ! channel )
        break;

      if ( ! xAddToITEXChannelList(channel) )
        break;

      xSysD.xNoticeBoard.ITEXCommStarted = (xbool)1;
      xPrintString("Handling of ITEX communication started\n");
      xSysD.xNoticeBoard.CommStarted = (xbool)1;
      xPrintString("Handling of SDL environment started\n");
      break;
    }
#endif

#ifdef XENV
    case 72:     /* Start-Env */
      if ( xSysD.xInEnvOn ) {
        xPrintString("InEnv polling is already on\n");
        break;
      }
      xSysD.xInEnvOn = (xbool)1;
      xPrintString("InEnv polling is now on\n");
      break;

    case 73:     /* Stop-Env */
      if ( ! xSysD.xInEnvOn ) {
        xPrintString("InEnv polling is already off\n");
        break;
      }
      xSysD.xInEnvOn = (xbool)0;
      xPrintString("InEnv polling is now off\n");
      break;

    case 74:     /* Call-Env */
      /* Read rest of input line, so cleared when in xInEnv */
      xSkipLine();
      xInEnv(SDL_Time_Lit( (xint32)0, (xint32)0 ));
      break;
#endif

#ifdef XSDLENVUI
    case 75:     /* Start-UI */
      if ( ! xSysD.xNoticeBoard.PMConnected ) {
        xPrintString("No connection with the Postmaster\n");
        break;
      }
      xPrintString("Starting UI...\n");
      if (xInit_UI_sdlenv())
        xPrintString("UI is started\n");
      else
        xPrintString("Error during start up of UI\n");
      break;
#endif

    case 76:     /* '@' DoCheckForInput */
#ifndef XNOSELECT
      if (xSysD.xDoCheckForInput) {
        xSysD.xDoCheckForInput = (xbool)0;
        xPrintString("Keyboard polling is now off\n");
      }
      else {
        xSysD.xDoCheckForInput = (xbool)1;
        xPrintString("Keyboard polling is now on\n");
      }
#else
      xPrintString("Keyboard polling not implemented\n");
#endif
      break;

    case 77:      /* Go-Forever */
      xSysD.StopInMonitor = 0;
      xCont = 0;
      xSysD.xGoForever = 1;
      break;

    case 78:      /* Show-Next-Symbol */
      if ( strlen(xSysD.xCurrentSymbolRef) < (unsigned)1 ) {
        xPrintString("No symbol reference\n");
        break;
      }
#ifdef XGRTRACE
      if ( xSysD.xNoticeBoard.PMConnected ) {
        if ( !xGRShowNextSymbol() )
          xPrintString("No next symbol\n");
        break;
      }
#endif
      PRINTF2("%s\n", xSysD.xCurrentSymbolRef);
      break;

    case 79:      /* Include-File */
      if (xSysD.CommandFile != (xCommandFileNode)0) {
	xCommandFileNode  tmpCF;

        count = 1;
        for (tmpCF = xSysD.CommandFile->Next;
             tmpCF != (xCommandFileNode)0;
             tmpCF = tmpCF->Next)
          count++;
        if (count >= 5) {
          xPrintString("Too many nested include files, maximum is 5\n");
          break;
        }
      }
      if ( !xGetAndOpenFile(&TempFile, (xbool)1, strVar, "com") )
        break;

      NewCF = (xCommandFileNode)xAlloc((xptrint)sizeof( xCommandFileRec ));
      NewCF->Next = xSysD.CommandFile;
      NewCF->File = TempFile;
      xSysD.CommandFile = NewCF;
      while (*xInputPos != ' ' && *xInputPos != '\t' &&
             *xInputPos != '\n' && *xInputPos != EOF)
        xInputPos++;
      while (*xInputPos == ' ' || *xInputPos == '\t')
        xInputPos++;
      i2=0;
      while (*xInputPos != '\n' && *xInputPos != EOF && i2 < 99) {
        Token = xScanToken(strVar2);
        xSysD.CommandFile->A[i2] = (char *)xAlloc((xptrint)(strlen(strVar2)+1));
        strcpy(xSysD.CommandFile->A[i2], strVar2);
        while (*xInputPos == ' ' || *xInputPos == '\t')
          xInputPos++;
        i2++;
      }
      xSkipLine();
      break;

    case 80:      /* Show-Previous-Symbol */
      if ( strlen(xSysD.xPreviousSymbolRef) < (unsigned)1 ) {
        xPrintString("No symbol reference\n");
        break;
      }
#ifdef XGRTRACE
      if ( xSysD.xNoticeBoard.PMConnected ) {
        if ( !xGRShowPreviousSymbol() )
          xPrintString("No previous symbol\n");
        break;
      }
#endif
      PRINTF2("%s\n", xSysD.xPreviousSymbolRef);
      break;

#ifdef XCTRACE
    case 81:      /* Show-C-Line-Number */
      if ( xSysD.xCFileName == (char *)0) {
         xPrintString ("No transition started\n");
         break;
      }
      if ( xSysD.xBetweenTrans ) {
        xPrintString("Between transitions.\nLast operation was Nextstate or Stop that follows after position:\n");
      }
      PRINTF3("C-File: %s, Line: %ld\n", xSysD.xCFileName, xSysD.xCLineNo);
#ifdef XCONNECTPM
      sprintf(strVar, "#SDTREF(TEXT,%s,%ld)", xSysD.xCFileName, xSysD.xCLineNo);
      xGRTraceSymbol(strVar);
#endif
      break;
#endif

#ifdef XCONNECTPM
    case 110: {   /* GR-Conversion */
      char        *fromStr, *toStr;
      unsigned int length;

      Token = xPromptQuestionMark("From string : ", (char *)0, strVar);
      if (Token != xxString && Token != xxASN1String && Token != xxId &&
          Token != xxEnv) {
        if (Token == xxMinus) {
          xSetGRConversion((xbool)0, "", "");
        }
        else if (Token != xxLBracket) {
          PRINTF("Conversion value should start with ' or \"\n");
        }
        break;
      }
      if (Token == xxId || Token == xxEnv) {
        length = strlen(strVar) + 1;
        fromStr = (char *)xAlloc(length);
        strcpy(fromStr, strVar);
      }
      else {
        length = strlen(strVar) - 1;
        /* Remove starting and ending ' or " */
        strVar[length] = '\0';
        fromStr = (char *)xAlloc(length);
        strcpy(fromStr, strVar + 1);
      }

      Token = xPromptQuestionMark("To string : ", (char *)0, strVar);
      if (Token != xxString && Token != xxASN1String && Token != xxId &&
          Token != xxEnv) {
        if (Token != xxLBracket) {
          PRINTF("Conversion value should start with ' or \"\n");
        }
        xFree((void **)&fromStr);
        xSetGRConversion((xbool)0, "", "");
        break;
      }
      if (Token == xxId || Token == xxEnv) {
        length = strlen(strVar) + 1;
        toStr = (char *)xAlloc(length);
        strcpy(toStr, strVar);
      }
      else {
        length = strlen(strVar) - 1;
        /* Remove starting and ending ' or " */
        strVar[length] = '\0';
        toStr = (char *)xAlloc(length);
        strcpy(toStr, strVar + 1);
      }

      xSetGRConversion((xbool)1, fromStr, toStr);
      break;
    }
#endif

    case 83:      /* Command-Log-On */
      if (xSysD.CommandLog.Active) {
        xPrintString("Command Log is already active\n");
        break;
      }
      Token = xScanToken(strVar);
      if (Token == xxEoln && xSysD.CommandLog.File != NULL) {
        xSysD.CommandLog.File = fopen(xSysD.CommandLog.Filename, "a");
        xSysD.CommandLog.Active = (xbool)1;
        break;
      }
      xUngetToken(Token, strVar);
      if ( !xGetAndOpenFile(&TempFile, (xbool)0, strVar, "com") )
        break;
      strcpy(xSysD.CommandLog.Filename, strVar);
      xSysD.CommandLog.File = TempFile;
      xSysD.CommandLog.Active = (xbool)1;
      break;

    case 84:      /* Command-Log-Off */
      if ( ! xSysD.CommandLog.Active) {
        xPrintString("Command Log is not active\n");
        break;
      }
      if (xSysD.CommandLog.File != NULL)
        if (fclose(xSysD.CommandLog.File) != 0)
           xPrintString("Error closing Command Logfile\n");
      xSysD.CommandLog.Active = (xbool)0;
      break;

#ifdef XMSCE
#ifdef XCONNECTPM
    case 85:      /* Start-Interactive-MSC-Log */
      if (xSysD.MSCLogStarted) {
        xPrintString("MSC-Log already started\n");
        (void)xStartMSC(); /* Just make the MSC editor popup */
        break;
      }
      if ( ! xSysD.xNoticeBoard.PMConnected ) {
        xPrintString("No connection with the Postmaster\n");
        break;
      }
      if (! xMSC_Level())
        break;
      xPrintString("Starting MSC...\n");
      if ( xStartMSC() ) goto MSCLogLabel;
      break;
#endif

    case 86:      /* Start-Batch-MSC-Log */
      if (xSysD.MSCLogStarted) {
        xPrintString("MSC-Log already started\n");
        break;
      }
      if (! xMSC_Level())
        break;
      if (! xGetAndOpenFile(&xSysD.MSCLog.File, (xbool)0, strVar, "mpr"))
        break;
      PRINTF2("Batch-MSC-Log started on file %s\n", strVar);
      strcpy(xSysD.MSCLog.Filename, strVar);
#ifdef XCONNECTPM
    MSCLogLabel:
#endif
      xSysD.MSCLogStarted = 1;
      xMSCEInit();
      break;

    case 87:      /* List-MSC-Log */
      if (xSysD.MSCLogStarted) {
#ifdef XCONNECTPM
        if (xSysD.xNoticeBoard.MSCEStarted) {
          xPrintString("Interactive-MSC-Log started\n");
        }
        else
#endif
             {
          PRINTF2("Batch-MSC-Log on file %s\n", xSysD.MSCLog.Filename);
        }
      }
      else
        xPrintString("No MSC-Log started\n");
      break;

    case 88:      /* Stop-MSC-Log */
      if ( ! xSysD.MSCLogStarted) {
        xPrintString("No MSC-Log started\n");
        break;
      }
#ifdef XCONNECTPM
      if (xSysD.xNoticeBoard.MSCEStarted) {
        xSysD.xNoticeBoard.MSCEStarted = 0;
      }
      else
#endif
        xMSCEClose();
      xSysD.MSCLogStarted = 0;
      break;

    case  91:     /* List-MSC-Trace-Values */
      WriteMSCETraces(xSymbolTableRoot);
      break;

    case  99:     /* Define-MSC-Trace-Channels */
      if (xSysD.MSCLogStarted) {
        xPrintString("Cannot change MSC trace when MSC-Log started\n");
        break;
      }
      choice = xChoose2( "MSC trace channels (on/off) : ", "On", "Off" );
      if (choice==1) {
        xPrintString( "MSC trace channels on.\n" );
      } else if (choice==2) {
        xPrintString( "MSC trace channels off.\n" );
      } else {
        PRINTF2( "MSC trace channels not changed (%s).\n",
                 xIsEnvSplitIntoChannels() ? "On" : "Off");
        break;
      }
      xSetEnvSplitIntoChannels(choice == 1);
      break;
#endif
       /* XMSCE */

    case  92:     /* ASN1-Value-Notation */
      xSysD.xUse_ASN1_Syntax = (xbool)1;
      xPrintString("Now using ASN1 value notation.\n");
      break;

    case  93:     /* SDL-Value-Notation */
      xSysD.xUse_ASN1_Syntax = (xbool)0;
      xPrintString("Now using SDL value notation.\n");
      break;

    case  94:     /* REF-Address-Notation */
      xSysD.xUse_NewRef_Syntax = (xbool)0;
      xSysD.xUse_DeRef_Syntax = (xbool)0;
      xPrintString("Now printing HEX address for REF value.\n");
      break;

    case  95:     /* REF-Value-Notation */
      xSysD.xUse_NewRef_Syntax = (xbool)1;
      xSysD.xUse_DeRef_Syntax = (xbool)0;
      xPrintString("Now printing value of data referenced by REF pointer.\n");
      break;

    case  109:    /* REF-Deref-Value-Notation */
      xSysD.xUse_NewRef_Syntax = (xbool)1;
      xSysD.xUse_DeRef_Syntax = (xbool)1;
      PRINTF("Now printing value of data referenced by REF pointer without new.\n");
      break;

    case  107:    /* Define-Integer-Output-Mode */
    {
      char *choices[] = { "dec", "hex", "oct", NULL };
#ifdef X_LONG_INT
      char *pFormat[] = { "%ld", "%#lx", "%#lo" };
      char *sFormat[] = { "%ld", "%li", "%li" };
#else
      char *pFormat[] = { "%d", "%#x", "%#o" };
      char *sFormat[] = { "%d", "%i", "%i" };
#endif

      choice = xChooseAlternative("Integer-Output-Mode : ", choices);
      if (choice >= 0) {
        strcpy(xSysD.xPrintIntFormat, pFormat[choice]);
        strcpy(xSysD.xScanIntFormat, sFormat[choice]);
        xSysD.xIntegerOutputMode = choice;
        PRINTF2("Integer-Output-Mode is now %s\n", choices[choice]);
      }
      else if (choice != -3) {
        if (choice == -2) {
          PRINTF("Invalid input\n");
        }
        PRINTF2("Integer-Output-Mode not changed (%s).\n",
                choices[xSysD.xIntegerOutputMode]);
      }
      break;
    }

#ifdef XCONNECTPM
#ifdef XSIMULATORUI
    case   7:     /* Start-SimUI */
      if (xSysD.xNoticeBoard.SimulatorUIStarted) {
        xPrintString("SimUI already started\n");
        break;
      }
      if (StartSimUI()) {
        xSendUIChange();
        xPrintString("SimUI started\n");
      }
      else
        xPrintString("SimUI could not be started\n");
      break;
#endif
#endif

    case  11:     /* Define-Continue-Mode */
      choice = xChoose2( "Continue-Mode (on/off) : ", "On", "Off" );
      if (choice==1) {
        xContinueMode = 1;
        xPrintString("Continue-Mode is now on\n");
      } else if (choice==2) {
        xContinueMode = 0;
        xPrintString("Continue-Mode is now off\n");
      } else {
        PRINTF2( "Continue-Mode not changed (%s).\n",
                 xContinueMode ? "On" : "Off");
      }
      break;

#ifdef XCONNECTPM
    case  96:     /* Connect-To-Editor */
      if (xConnectToEditor()) {
        xPrintString("Editor connected\n");
      }
      break;

    case  97:     /* Disconnect-Editor */
      xDisconnectEditor((xbool)0);
      break;
#endif

    case  98:     /* Cd */
      CdCommand(strVar);
      break;

#ifdef XPERFSIM
    case  101:    /* List-Delay */
      ListDelayCommand();
      break;

    case  102:    /* Define-Delay */
      DefineDelayCommand(strVar);
      break;

    case  103:    /* Save-Delay */
      SaveDelayCommand(strVar);
      break;

    case  104:    /* Define-At-Delay */
      DefineAtDelayCommand(strVar);
      break;

    case  105:    /* Remove-Delay */
      RemoveDelayCommand(strVar);
      break;

    case  106:    /* Performance-Simulation */
      choice = xChoose2( "Performance Simulation (on/off) : ", "On", "Off" );
      if (choice==1) {
        xPerfSimOn = 1;
        PRINTF("Performance Simulation is now on\n");
      } else if (choice==2) {
        xPerfSimOn = 0;
        PRINTF("Performance Simulation is now off\n");
      } else {
        PRINTF2( "Performance Simulation mode not changed (%s).\n",
                 xPerfSimOn ? "On" : "Off");
      }
      break;
#endif

#ifdef FORK_PROCESS
#ifndef _Windows
    case 112:     /* Fork-Process */
      {
        int pid;
        int status, childid;

        pid = fork();
        if (pid == -1) {
          PRINTF("Could not create child process\n");
        }
        else if (pid) {
          childid = wait(&status);
          PRINTF("Back to parent process\n");
#ifdef DEBUG
          PRINTF4("pid = %d, childid = %d, status = %d\n",
                  pid, childid, status);
#endif
        }
        else {
          PRINTF("Child process created\n");
          WasForked = (xbool)1;
        }
      }
      break;
#endif
#endif

    case 114:      /* Save-State */
      xSaveStateCom(strVar);
      break;

    case 115:      /* Restore-State */
      xRestoreStateCom(strVar);
      break;

    case 116:      /* xSet */
      if (xSysD.xRestoringState) {
        xSetCom(strVar);
      }
      else {
        PRINTF("Command only allowed when doing Restore-State\n");
      }
      break;

#ifdef XDEBUGPM
    case -1:     /* '' status-PostMaster */
      if (WasForked) {
        PRINTF("\nWasForked is TRUE\n");
      }
      else {
        PRINTF("\nWasForked is FALSE\n");
      }
      PRINTF2("getpid() returns %d\n\n", getpid());
#ifdef XCONNECTPM
      PRINTF2("PMConnected           : %d\n", xSysD.xNoticeBoard.PMConnected);
      PRINTF2("MyPID                 : %d\n", xSysD.xNoticeBoard.MyPID);
      PRINTF2("StartedFromPostmaster : %d\n", xSysD.xNoticeBoard.StartedFromPostmaster);
#ifdef XITEXCOMM
      PRINTF2("ITEXCommStarted       : %d\n", xSysD.xNoticeBoard.ITEXCommStarted);
      PRINTF2("TimeManager           : %d\n", xSysD.xNoticeBoard.TimeManager);
#endif
#ifdef XPMCOMM
      PRINTF2("CommStarted           : %d\n", xSysD.xNoticeBoard.CommStarted);
#endif
#ifdef XSDLENVUI
      PRINTF2("UIStarted             : %d\n", xSysD.xNoticeBoard.UIStarted);
#endif
#ifdef XSIMULATORUI
      PRINTF2("SimulatorUIStarted    : %d\n", xSysD.xNoticeBoard.SimulatorUIStarted);
#endif
#ifdef XMSCE
      PRINTF2("MSCEStarted           : %d\n", xSysD.xNoticeBoard.MSCEStarted);
      PRINTF2("MSCDiagram            : %d\n", xSysD.xNoticeBoard.MSCDiagram);
#endif
#endif
      break;
#endif


    default :
      xPrintString("Illegal command\n");
      break;
    }   /* end switch */

    /* Rest of input line already skipped when Call-Env */
    if (CommandIdNode->CommandNo != 74) {  /* Call-Env */
      while (*xInputPos != ';' && *xInputPos != '\0')
        xInputPos++;
      if (*xInputPos == ';')
        xInputPos++;
    }
#ifndef TARGETSIM
#ifdef XCONNECTPM
#ifdef XSIMULATORUI
    if (!xSysD.xNoticeBoard.SimulatorUIStarted && !xCont) {
#else
    if (!xCont) {
#endif
      if (!SPCheck(strVar)) {
        xPrintString(strVar); xPrintString("\n");
        xCont = (xbool)1;
      }
    }
#endif
#endif

#ifdef XSIMULATORUI
    if (PrintToxTrStr) {
      xSendxTrStrReply(CommandSourcePId, xTrStr);
      PrintToxTrStr = 0;
    }
#endif

    continue;
  }  /* end while */

#ifdef XPERFSIM
  if (! XREADYQ_EMPTY && ! XREADYQ_FIRST->InTransition) {
    xPerfSim(-1, (xbool)0);
  }
#endif
#ifdef XCLOCK
  xSysD.xTimeInMonitor = xPlus_SDL_Duration(xSysD.xTimeInMonitor,
    xMinusT_SDL_Time(SDL_Clock(), xTimeEnteringMonitor));
#endif
  xSysD.StoppedInMonitor = 0;
}
    /* end of xCheckMonitors */


/*---+---------------------------------------------------------------
     xNextMonTime
-------------------------------------------------------------------*/
SDL_Time xNextMonTime (void)
{
 return xSysD.xNextMonTimeVar;
}


/*---+---------------------------------------------------------------
     xMonBreakAtSymbol
-------------------------------------------------------------------*/
xbool xMonBreakAtSymbol(
  long int  SymbolNumber,
  xbool     BetweenSymbols )
{
  int Level;
#if defined(XCONNECTPM)
  static int NoSymbolsSinceInPM = 0;
#endif

  if (xSysD.xDynamicError) {
    xSysD.xDynamicError = (xbool)0;
    xSysD.StopInMonitor = 1;
    return (xbool)1;
  }
  if (xSysD.Interrupted)
    return (xbool)1;
#if defined(XCONNECTPM)
  NoSymbolsSinceInPM++;
  if (NoSymbolsSinceInPM > 100) {
    NoSymbolsSinceInPM = 0;
    xInPM();
  }
#endif
#ifndef XNOSELECT
  if (xSysD.xDoCheckForInput)
    if (xCheckForInput()) {
      xSysD.Interrupted = 1;
      return (xbool)1;
    }
#endif

  if (xCheckBreakpointVariable()) {
    xSysD.StopInMonitor = 1;
    return (xbool)1;
  }
  if (xCheckBreakpointAt(XREADYQ_FIRST, SymbolNumber)) {
    xSysD.StopInMonitor = 1;
    return (xbool)1;
  }

  if (BetweenSymbols) {
    if (xSysD.StepSymbol == 1)
      return (xbool)1;
    else if (xSysD.StepSymbol > 1)
      xSysD.StepSymbol--;
  }
  if (xSysD.StepStatement == 1)
    return (xbool)1;
  else if (xSysD.StepStatement > 1)
    xSysD.StepStatement--;

  Level = xGetPrdLevel();
  if (Level <= xSysD.NextLevel) {
    if (BetweenSymbols) {
      if (xSysD.NextSymbol == 1)
	return (xbool)1;
      else if (xSysD.NextSymbol > 1)
	xSysD.NextSymbol--;
    }
    if (xSysD.NextStatement == 1)
      return (xbool)1;
    else if (xSysD.NextStatement > 1)
      xSysD.NextStatement--;
    if (Level < xSysD.NextLevel && xSysD.Finish == 1)
      return (xbool)1;
  }
  return (xbool)0;
}


/*---+---------------------------------------------------------------
     xMonitorOneSignalLog
-------------------------------------------------------------------*/
static void xMonitorOneSignalLog(
  xSignalNode  Signal,
  int          NrOfReceivers,
  xIdNode     *Path,
  int          PathIndex,
  xSignalLogNode SignalLog)
{
  int       i;
  xIdNode   xIdNodeSigPar, IdNode;
  xbool     Found;
  SDL_PId   Receiver;
  WriteBuf *Buf;

  if ( NrOfReceivers != 1 ) return;
/*  ***   Either no signal or a list of signals    ***
  if (SignalLog->SignalId != (xIdNode)0)
    if (XSIGNAL_IDNODE(Signal) != SignalLog->SignalId)
      return;
    ***                                            ***   */
  Receiver = XSIGNAL_RECEIVER(Signal);
  if (SignalLog->UnitId != (xIdNode)0) {
    Found = (xbool)0;
    if (SignalLog->UnitId->EC == xSystemEC)
      Found = (xbool)1;
    else if (SignalLog->UnitId->EC == xBlockEC) {
      for (IdNode = XPID_TO_PRS(XSIGNAL_SENDER(Signal))->NameNode->Parent;
           IdNode != (xIdNode)0;
           IdNode = IdNode->Parent) {
        if (IdNode->EC == xBlockEC)
          if (SignalLog->UnitId == IdNode) {
            Found = (xbool)1;
            break;
          }
      }
      if ( ! Found)
        for (IdNode = XPID_TO_PRS(Receiver)->NameNode->Parent;
             IdNode != (xIdNode)0;
             IdNode = IdNode->Parent) {
          if (IdNode->EC == xBlockEC)
            if (SignalLog->UnitId == IdNode) {
              Found = (xbool)1;
              break;
            }
        }
    }
    else if (SignalLog->UnitId->EC == xProcessEC) {
      if (SignalLog->UnitId ==
                      (xIdNode)XPID_TO_PRS(XSIGNAL_SENDER(Signal))->NameNode ||
          SignalLog->UnitId == (xIdNode)XPID_TO_PRS(Receiver)->NameNode)
        Found = (xbool)1;
    }
    else if (SignalLog->UnitId->EC == xChannelEC ||
             SignalLog->UnitId->EC == xSignalrouteEC ||
             SignalLog->UnitId->EC == xGateEC) {
      if (PathIndex <= 0) {
        (void)xIsPath(XSIGNAL_IDNODE(Signal),
                      (xIdNode)XPID_TO_PRS(XSIGNAL_SENDER(Signal))->NameNode,
                      XPID_TO_PRS(XSIGNAL_RECEIVER(Signal))->NameNode,
                      (xIdNode *)0, Path, &PathIndex);
      }
      if ( Path != (xIdNode *)0 )
        for ( i=1; i<PathIndex; i++ )
          if (Path[i] == SignalLog->UnitId ||
              Path[i] == (xIdNode)((xChannelIdNode)SignalLog->UnitId)->Reverse)
            Found = (xbool)1;
    }
    if ( ! Found)
      return;
  }
  if (SignalLog->PrsNode != (xPrsNode)0) {
    if ( ! xEq_SDL_PId(SignalLog->PrsNode->Self, XSIGNAL_SENDER(Signal)) &&
         ! xEq_SDL_PId(SignalLog->PrsNode->Self, Receiver) )
      return;
  }
  if (xSysD.StoppedInMonitor)
    fprintf(SignalLog->File, "%s %s", xWriteNow(xSysD.NowInMonitor),
	    xWriteEntity((xIdNode)XSIGNAL_IDNODE(Signal)));
  else
    fprintf(SignalLog->File, "%s %s", xWriteNow(SDL_Now()),
	    xWriteEntity((xIdNode)XSIGNAL_IDNODE(Signal)));
  fprintf(SignalLog->File, " from %s", xWri_SDL_PId(&XSIGNAL_SENDER(Signal)));
  fprintf(SignalLog->File, " to %s\n", xWri_SDL_PId(&Receiver));
  if (XSIGNAL_IDNODE(Signal)->First != (xIdNode)0) {
    Buf = WriteBuf_New(60);
    fprintf(SignalLog->File, "Parameter(s) : ");
    for (xIdNodeSigPar = XSIGNAL_IDNODE(Signal)->First;
         xIdNodeSigPar != (xIdNode)0;
         xIdNodeSigPar = xIdNodeSigPar->Suc) {
      if (xIdNodeSigPar != XSIGNAL_IDNODE(Signal)->First)
        fprintf(SignalLog->File, ", ");
      WriteBuf_Clear(Buf);
      xGenericWriteSort(
	Buf,
	(void *)((xptrint)XSIGNAL_DATA(Signal)+((xVarIdNode)xIdNodeSigPar)->Offset),
	((xVarIdNode)xIdNodeSigPar)->TypeNode);
      WriteBuf_Terminate(Buf);
      fprintf(SignalLog->File, "%s", WriteBuf_Data(Buf));
    }
    fprintf(SignalLog->File, "\n");
    WriteBuf_Del(&Buf);
  }
/*  No path info
  if ( Path != (xIdNode *)0 )
    for ( i=1; i<PathIndex; i++ )
      fprintf(SignalLog->File, "over %s\n", Path[i]->Name);
*/
}


/*---+---------------------------------------------------------------
     xMonitorSignalLog
-------------------------------------------------------------------*/
void xMonitorSignalLog(
  xSignalNode  Signal,
  int          NrOfReceivers,
  xIdNode     *Path,
  int          PathIndex)
{
  xSignalLogNode SignalLog;

  if (xSysD.SignalLogList == (xSignalLogNode)0)
    return;
  if ( xEq_SDL_PId_NULL(XSIGNAL_SENDER(Signal)) )
    return;
  if ( xEq_SDL_PId_NULL(XSIGNAL_RECEIVER(Signal)) )
    return;
  for (SignalLog = xSysD.SignalLogList;
       SignalLog != (xSignalLogNode)0;
       SignalLog = SignalLog->Next)
    xMonitorOneSignalLog(Signal, NrOfReceivers, Path, PathIndex, SignalLog);
}

#endif
/************************* END XMONITOR ****************************/
