QtTest: data for code generation updated

Modified:
codegen/QtTest/QTestEventList.prg

$header

#include "hbclass.ch"

CLASS QTestEventList

   DATA pointer
   DATA self_destruction INIT .F.

   METHOD new1
   METHOD new2
   METHOD new
   METHOD delete
   METHOD addDelay
   METHOD addKeyClick1
   METHOD addKeyClick2
   METHOD addKeyClick
   METHOD addKeyClicks
   METHOD addKeyPress1
   METHOD addKeyPress2
   METHOD addKeyPress
   METHOD addKeyRelease1
   METHOD addKeyRelease2
   METHOD addKeyRelease
   METHOD addMouseClick
   METHOD addMouseDClick
   METHOD addMouseMove
   METHOD addMousePress
   METHOD addMouseRelease
   METHOD clear
   METHOD simulate
   METHOD newFrom
   METHOD newFromObject
   METHOD newFromPointer
   METHOD selfDestruction
   METHOD setSelfDestruction
   DESTRUCTOR destroyObject

END CLASS

$destructor

#pragma BEGINDUMP

#include <QTestEventList>

#include "qt4xhb_common.h"
#include "qt4xhb_macros.h"
#include "qt4xhb_utils.h"

/*
QTestEventList ()
*/
HB_FUNC_STATIC( QTESTEVENTLIST_NEW1 )
{
  QTestEventList * o = new QTestEventList ();
  _qt4xhb_storePointerAndFlag ( o, false );
}

/*
QTestEventList ( const QTestEventList & other )
*/
HB_FUNC_STATIC( QTESTEVENTLIST_NEW2 )
{
  QTestEventList * o = new QTestEventList ( *PQTESTEVENTLIST(1) );
  _qt4xhb_storePointerAndFlag ( o, false );
}

//[1]QTestEventList ()
//[2]QTestEventList ( const QTestEventList & other )

HB_FUNC_STATIC( QTESTEVENTLIST_NEW )
{
  if( ISNUMPAR(0) )
  {
    HB_FUNC_EXEC( QTESTEVENTLIST_NEW1 );
  }
  else if( ISNUMPAR(1) && ISQTESTEVENTLIST(1) )
  {
    HB_FUNC_EXEC( QTESTEVENTLIST_NEW2 );
  }
  else
  {
    hb_errRT_BASE( EG_ARG, 3012, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
  }
}

HB_FUNC_STATIC( QTESTEVENTLIST_DELETE )
{
  QTestEventList * obj = (QTestEventList *) hb_itemGetPtr( hb_objSendMsg( hb_stackSelfItem(), "POINTER", 0 ) );
  if( obj )
  {
    delete obj;
    obj = NULL;
    PHB_ITEM self = hb_stackSelfItem();
    PHB_ITEM ptr = hb_itemPutPtr( NULL, NULL );
    hb_objSendMsg( self, "_pointer", 1, ptr );
    hb_itemRelease( ptr );
  }
  hb_itemReturn( hb_stackSelfItem() );
}

/*
void addDelay ( int msecs )
*/
HB_FUNC_STATIC( QTESTEVENTLIST_ADDDELAY )
{
  QTestEventList * obj = (QTestEventList *) hb_itemGetPtr( hb_objSendMsg( hb_stackSelfItem(), "POINTER", 0 ) );
  if( obj )
  {
    obj->addDelay ( PINT(1) );
  }
  hb_itemReturn( hb_stackSelfItem() );
}

/*
void addKeyClick ( Qt::Key qtKey, Qt::KeyboardModifiers modifiers = Qt::NoModifier, int msecs = -1 )
*/
HB_FUNC_STATIC( QTESTEVENTLIST_ADDKEYCLICK1 )
{
  QTestEventList * obj = (QTestEventList *) hb_itemGetPtr( hb_objSendMsg( hb_stackSelfItem(), "POINTER", 0 ) );
  if( obj )
  {
    obj->addKeyClick ( (Qt::Key) hb_parni(1), ISNIL(2)? Qt::NoModifier : (Qt::KeyboardModifiers) hb_parni(2), OPINT(3,-1) );
  }
  hb_itemReturn( hb_stackSelfItem() );
}

/*
void addKeyClick ( char ascii, Qt::KeyboardModifiers modifiers = Qt::NoModifier, int msecs = -1 )
*/
HB_FUNC_STATIC( QTESTEVENTLIST_ADDKEYCLICK2 )
{
  QTestEventList * obj = (QTestEventList *) hb_itemGetPtr( hb_objSendMsg( hb_stackSelfItem(), "POINTER", 0 ) );
  if( obj )
  {
    char par1 = ISCHAR(1)? (char) hb_parc(1)[0] : (ISNUM(1)? hb_parni(1) : 0);
    obj->addKeyClick ( par1, ISNIL(2)? Qt::NoModifier : (Qt::KeyboardModifiers) hb_parni(2), OPINT(3,-1) );
  }
  hb_itemReturn( hb_stackSelfItem() );
}

//[1]void addKeyClick ( Qt::Key qtKey, Qt::KeyboardModifiers modifiers = Qt::NoModifier, int msecs = -1 )
//[2]void addKeyClick ( char ascii, Qt::KeyboardModifiers modifiers = Qt::NoModifier, int msecs = -1 )

HB_FUNC_STATIC( QTESTEVENTLIST_ADDKEYCLICK )
{
  if( ISBETWEEN(1,3) && ISNUM(1) && (ISNUM(2)||ISNIL(2)) && (ISNUM(3)||ISNIL(3)) )
  {
    HB_FUNC_EXEC( QTESTEVENTLIST_ADDKEYCLICK1 );
  }
  else if( ISBETWEEN(1,3) && ISCHAR(1) && (ISNUM(2)||ISNIL(2)) && (ISNUM(3)||ISNIL(3)) )
  {
    HB_FUNC_EXEC( QTESTEVENTLIST_ADDKEYCLICK2 );
  }
}

/*
void addKeyClicks ( const QString & keys, Qt::KeyboardModifiers modifiers = Qt::NoModifier, int msecs = -1 )
*/
HB_FUNC_STATIC( QTESTEVENTLIST_ADDKEYCLICKS )
{
  QTestEventList * obj = (QTestEventList *) hb_itemGetPtr( hb_objSendMsg( hb_stackSelfItem(), "POINTER", 0 ) );
  if( obj )
  {
    obj->addKeyClicks ( PQSTRING(1), ISNIL(2)? Qt::NoModifier : (Qt::KeyboardModifiers) hb_parni(2), OPINT(3,-1) );
  }
  hb_itemReturn( hb_stackSelfItem() );
}

/*
void addKeyPress ( Qt::Key qtKey, Qt::KeyboardModifiers modifiers = Qt::NoModifier, int msecs = -1 )
*/
HB_FUNC_STATIC( QTESTEVENTLIST_ADDKEYPRESS1 )
{
  QTestEventList * obj = (QTestEventList *) hb_itemGetPtr( hb_objSendMsg( hb_stackSelfItem(), "POINTER", 0 ) );
  if( obj )
  {
    obj->addKeyPress ( (Qt::Key) hb_parni(1), ISNIL(2)? Qt::NoModifier : (Qt::KeyboardModifiers) hb_parni(2), OPINT(3,-1) );
  }
  hb_itemReturn( hb_stackSelfItem() );
}

/*
void addKeyPress ( char ascii, Qt::KeyboardModifiers modifiers = Qt::NoModifier, int msecs = -1 )
*/
HB_FUNC_STATIC( QTESTEVENTLIST_ADDKEYPRESS2 )
{
  QTestEventList * obj = (QTestEventList *) hb_itemGetPtr( hb_objSendMsg( hb_stackSelfItem(), "POINTER", 0 ) );
  if( obj )
  {
    char par1 = ISCHAR(1)? (char) hb_parc(1)[0] : (ISNUM(1)? hb_parni(1) : 0);
    obj->addKeyPress ( par1, ISNIL(2)? Qt::NoModifier : (Qt::KeyboardModifiers) hb_parni(2), OPINT(3,-1) );
  }
  hb_itemReturn( hb_stackSelfItem() );
}

//[1]void addKeyPress ( Qt::Key qtKey, Qt::KeyboardModifiers modifiers = Qt::NoModifier, int msecs = -1 )
//[2]void addKeyPress ( char ascii, Qt::KeyboardModifiers modifiers = Qt::NoModifier, int msecs = -1 )

HB_FUNC_STATIC( QTESTEVENTLIST_ADDKEYPRESS )
{
  if( ISBETWEEN(1,3) && ISNUM(1) && (ISNUM(2)||ISNIL(2)) && (ISNUM(3)||ISNIL(3)) )
  {
    HB_FUNC_EXEC( QTESTEVENTLIST_ADDKEYPRESS1 );
  }
  else if( ISBETWEEN(1,3) && ISCHAR(1) && (ISNUM(2)||ISNIL(2)) && (ISNUM(3)||ISNIL(3)) )
  {
    HB_FUNC_EXEC( QTESTEVENTLIST_ADDKEYPRESS2 );
  }
}

/*
void addKeyRelease ( Qt::Key qtKey, Qt::KeyboardModifiers modifiers = Qt::NoModifier, int msecs = -1 )
*/
HB_FUNC_STATIC( QTESTEVENTLIST_ADDKEYRELEASE1 )
{
  QTestEventList * obj = (QTestEventList *) hb_itemGetPtr( hb_objSendMsg( hb_stackSelfItem(), "POINTER", 0 ) );
  if( obj )
  {
    obj->addKeyRelease ( (Qt::Key) hb_parni(1), ISNIL(2)? Qt::NoModifier : (Qt::KeyboardModifiers) hb_parni(2), OPINT(3,-1) );
  }
  hb_itemReturn( hb_stackSelfItem() );
}

/*
void addKeyRelease ( char ascii, Qt::KeyboardModifiers modifiers = Qt::NoModifier, int msecs = -1 )
*/
HB_FUNC_STATIC( QTESTEVENTLIST_ADDKEYRELEASE2 )
{
  QTestEventList * obj = (QTestEventList *) hb_itemGetPtr( hb_objSendMsg( hb_stackSelfItem(), "POINTER", 0 ) );
  if( obj )
  {
    char par1 = ISCHAR(1)? (char) hb_parc(1)[0] : (ISNUM(1)? hb_parni(1) : 0);
    obj->addKeyRelease ( par1, ISNIL(2)? Qt::NoModifier : (Qt::KeyboardModifiers) hb_parni(2), OPINT(3,-1) );
  }
  hb_itemReturn( hb_stackSelfItem() );
}

//[1]void addKeyRelease ( Qt::Key qtKey, Qt::KeyboardModifiers modifiers = Qt::NoModifier, int msecs = -1 )
//[2]void addKeyRelease ( char ascii, Qt::KeyboardModifiers modifiers = Qt::NoModifier, int msecs = -1 )

HB_FUNC_STATIC( QTESTEVENTLIST_ADDKEYRELEASE )
{
  if( ISBETWEEN(1,3) && ISNUM(1) && (ISNUM(2)||ISNIL(2)) && (ISNUM(3)||ISNIL(3)) )
  {
    HB_FUNC_EXEC( QTESTEVENTLIST_ADDKEYRELEASE1 );
  }
  else if( ISBETWEEN(1,3) && ISCHAR(1) && (ISNUM(2)||ISNIL(2)) && (ISNUM(3)||ISNIL(3)) )
  {
    HB_FUNC_EXEC( QTESTEVENTLIST_ADDKEYRELEASE2 );
  }
}

/*
void addMouseClick ( Qt::MouseButton button, Qt::KeyboardModifiers modifiers = 0, QPoint pos = QPoint(), int delay = -1 )
*/
HB_FUNC_STATIC( QTESTEVENTLIST_ADDMOUSECLICK )
{
  QTestEventList * obj = (QTestEventList *) hb_itemGetPtr( hb_objSendMsg( hb_stackSelfItem(), "POINTER", 0 ) );
  int par2 = ISNIL(2)? 0 :  hb_parni(2);
  if( obj )
  {
    QPoint par3 = ISNIL(3)? QPoint() : *(QPoint *) hb_itemGetPtr( hb_objSendMsg( hb_param(3, HB_IT_OBJECT ), "POINTER", 0 ) );
    obj->addMouseClick ( (Qt::MouseButton) hb_parni(1), (Qt::KeyboardModifiers) par2, par3, OPINT(4,-1) );
  }
  hb_itemReturn( hb_stackSelfItem() );
}

/*
void addMouseDClick ( Qt::MouseButton button, Qt::KeyboardModifiers modifiers = 0, QPoint pos = QPoint(), int delay = -1 )
*/
HB_FUNC_STATIC( QTESTEVENTLIST_ADDMOUSEDCLICK )
{
  QTestEventList * obj = (QTestEventList *) hb_itemGetPtr( hb_objSendMsg( hb_stackSelfItem(), "POINTER", 0 ) );
  int par2 = ISNIL(2)? 0 :  hb_parni(2);
  if( obj )
  {
    QPoint par3 = ISNIL(3)? QPoint() : *(QPoint *) hb_itemGetPtr( hb_objSendMsg( hb_param(3, HB_IT_OBJECT ), "POINTER", 0 ) );
    obj->addMouseDClick ( (Qt::MouseButton) hb_parni(1), (Qt::KeyboardModifiers) par2, par3, OPINT(4,-1) );
  }
  hb_itemReturn( hb_stackSelfItem() );
}

/*
void addMouseMove ( QPoint pos = QPoint(), int delay = -1 )
*/
HB_FUNC_STATIC( QTESTEVENTLIST_ADDMOUSEMOVE )
{
  QTestEventList * obj = (QTestEventList *) hb_itemGetPtr( hb_objSendMsg( hb_stackSelfItem(), "POINTER", 0 ) );
  if( obj )
  {
    QPoint par1 = ISNIL(1)? QPoint() : *(QPoint *) hb_itemGetPtr( hb_objSendMsg( hb_param(1, HB_IT_OBJECT ), "POINTER", 0 ) );
    obj->addMouseMove ( par1, OPINT(2,-1) );
  }
  hb_itemReturn( hb_stackSelfItem() );
}

/*
void addMousePress ( Qt::MouseButton button, Qt::KeyboardModifiers modifiers = 0, QPoint pos = QPoint(), int delay = -1 )
*/
HB_FUNC_STATIC( QTESTEVENTLIST_ADDMOUSEPRESS )
{
  QTestEventList * obj = (QTestEventList *) hb_itemGetPtr( hb_objSendMsg( hb_stackSelfItem(), "POINTER", 0 ) );
  int par2 = ISNIL(2)? 0 :  hb_parni(2);
  if( obj )
  {
    QPoint par3 = ISNIL(3)? QPoint() : *(QPoint *) hb_itemGetPtr( hb_objSendMsg( hb_param(3, HB_IT_OBJECT ), "POINTER", 0 ) );
    obj->addMousePress ( (Qt::MouseButton) hb_parni(1), (Qt::KeyboardModifiers) par2, par3, OPINT(4,-1) );
  }
  hb_itemReturn( hb_stackSelfItem() );
}

/*
void addMouseRelease ( Qt::MouseButton button, Qt::KeyboardModifiers modifiers = 0, QPoint pos = QPoint(), int delay = -1 )
*/
HB_FUNC_STATIC( QTESTEVENTLIST_ADDMOUSERELEASE )
{
  QTestEventList * obj = (QTestEventList *) hb_itemGetPtr( hb_objSendMsg( hb_stackSelfItem(), "POINTER", 0 ) );
  int par2 = ISNIL(2)? 0 :  hb_parni(2);
  if( obj )
  {
    QPoint par3 = ISNIL(3)? QPoint() : *(QPoint *) hb_itemGetPtr( hb_objSendMsg( hb_param(3, HB_IT_OBJECT ), "POINTER", 0 ) );
    obj->addMouseRelease ( (Qt::MouseButton) hb_parni(1), (Qt::KeyboardModifiers) par2, par3, OPINT(4,-1) );
  }
  hb_itemReturn( hb_stackSelfItem() );
}

/*
void clear ()
*/
HB_FUNC_STATIC( QTESTEVENTLIST_CLEAR )
{
  QTestEventList * obj = (QTestEventList *) hb_itemGetPtr( hb_objSendMsg( hb_stackSelfItem(), "POINTER", 0 ) );
  if( obj )
  {
    obj->clear ();
  }
  hb_itemReturn( hb_stackSelfItem() );
}

/*
void simulate ( QWidget * w )
*/
HB_FUNC_STATIC( QTESTEVENTLIST_SIMULATE )
{
  QTestEventList * obj = (QTestEventList *) hb_itemGetPtr( hb_objSendMsg( hb_stackSelfItem(), "POINTER", 0 ) );
  if( obj )
  {
    obj->simulate ( PQWIDGET(1) );
  }
  hb_itemReturn( hb_stackSelfItem() );
}

$extraMethods

#pragma ENDDUMP

$header

#include "hbclass.ch"

CLASS QTestEventList

   DATA pointer
   DATA self_destruction INIT .F.

   METHOD new1
   METHOD new2
   METHOD new
   METHOD delete
   METHOD addDelay
   METHOD addKeyClick1
   METHOD addKeyClick2
   METHOD addKeyClick
   METHOD addKeyClicks
   METHOD addKeyPress1
   METHOD addKeyPress2
   METHOD addKeyPress
   METHOD addKeyRelease1
   METHOD addKeyRelease2
   METHOD addKeyRelease
   METHOD addMouseClick
   METHOD addMouseDClick
   METHOD addMouseMove
   METHOD addMousePress
   METHOD addMouseRelease
   METHOD clear
   METHOD simulate
   METHOD newFrom
   METHOD newFromObject
   METHOD newFromPointer
   METHOD selfDestruction
   METHOD setSelfDestruction
   DESTRUCTOR destroyObject

END CLASS

PROCEDURE destroyObject () CLASS QTestEventList
   IF ::self_destruction
      ::delete()
   ENDIF
RETURN

#pragma BEGINDUMP

#include <QTestEventList>

#include "qt4xhb_common.h"
#include "qt4xhb_macros.h"
#include "qt4xhb_utils.h"

/*
QTestEventList ()
*/
HB_FUNC_STATIC( QTESTEVENTLIST_NEW1 )
{
  QTestEventList * o = new QTestEventList ();
  _qt4xhb_storePointerAndFlag ( o, false );
}

/*
QTestEventList ( const QTestEventList & other )
*/
HB_FUNC_STATIC( QTESTEVENTLIST_NEW2 )
{
  QTestEventList * o = new QTestEventList ( *PQTESTEVENTLIST(1) );
  _qt4xhb_storePointerAndFlag ( o, false );
}

//[1]QTestEventList ()
//[2]QTestEventList ( const QTestEventList & other )

HB_FUNC_STATIC( QTESTEVENTLIST_NEW )
{
  if( ISNUMPAR(0) )
  {
    HB_FUNC_EXEC( QTESTEVENTLIST_NEW1 );
  }
  else if( ISNUMPAR(1) && ISQTESTEVENTLIST(1) )
  {
    HB_FUNC_EXEC( QTESTEVENTLIST_NEW2 );
  }
  else
  {
    hb_errRT_BASE( EG_ARG, 3012, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
  }
}

HB_FUNC_STATIC( QTESTEVENTLIST_DELETE )
{
  QTestEventList * obj = (QTestEventList *) hb_itemGetPtr( hb_objSendMsg( hb_stackSelfItem(), "POINTER", 0 ) );
  if( obj )
  {
    delete obj;
    obj = NULL;
    PHB_ITEM self = hb_stackSelfItem();
    PHB_ITEM ptr = hb_itemPutPtr( NULL, NULL );
    hb_objSendMsg( self, "_pointer", 1, ptr );
    hb_itemRelease( ptr );
  }
  hb_itemReturn( hb_stackSelfItem() );
}

/*
void addDelay ( int msecs )
*/
HB_FUNC_STATIC( QTESTEVENTLIST_ADDDELAY )
{
  QTestEventList * obj = (QTestEventList *) hb_itemGetPtr( hb_objSendMsg( hb_stackSelfItem(), "POINTER", 0 ) );
  if( obj )
  {
    obj->addDelay ( PINT(1) );
  }
  hb_itemReturn( hb_stackSelfItem() );
}

/*
void addKeyClick ( Qt::Key qtKey, Qt::KeyboardModifiers modifiers = Qt::NoModifier, int msecs = -1 )
*/
HB_FUNC_STATIC( QTESTEVENTLIST_ADDKEYCLICK1 )
{
  QTestEventList * obj = (QTestEventList *) hb_itemGetPtr( hb_objSendMsg( hb_stackSelfItem(), "POINTER", 0 ) );
  if( obj )
  {
    obj->addKeyClick ( (Qt::Key) hb_parni(1), ISNIL(2)? Qt::NoModifier : (Qt::KeyboardModifiers) hb_parni(2), OPINT(3,-1) );
  }
  hb_itemReturn( hb_stackSelfItem() );
}

/*
void addKeyClick ( char ascii, Qt::KeyboardModifiers modifiers = Qt::NoModifier, int msecs = -1 )
*/
HB_FUNC_STATIC( QTESTEVENTLIST_ADDKEYCLICK2 )
{
  QTestEventList * obj = (QTestEventList *) hb_itemGetPtr( hb_objSendMsg( hb_stackSelfItem(), "POINTER", 0 ) );
  if( obj )
  {
    char par1 = ISCHAR(1)? (char) hb_parc(1)[0] : (ISNUM(1)? hb_parni(1) : 0);
    obj->addKeyClick ( par1, ISNIL(2)? Qt::NoModifier : (Qt::KeyboardModifiers) hb_parni(2), OPINT(3,-1) );
  }
  hb_itemReturn( hb_stackSelfItem() );
}

//[1]void addKeyClick ( Qt::Key qtKey, Qt::KeyboardModifiers modifiers = Qt::NoModifier, int msecs = -1 )
//[2]void addKeyClick ( char ascii, Qt::KeyboardModifiers modifiers = Qt::NoModifier, int msecs = -1 )

HB_FUNC_STATIC( QTESTEVENTLIST_ADDKEYCLICK )
{
  if( ISBETWEEN(1,3) && ISNUM(1) && (ISNUM(2)||ISNIL(2)) && (ISNUM(3)||ISNIL(3)) )
  {
    HB_FUNC_EXEC( QTESTEVENTLIST_ADDKEYCLICK1 );
  }
  else if( ISBETWEEN(1,3) && ISCHAR(1) && (ISNUM(2)||ISNIL(2)) && (ISNUM(3)||ISNIL(3)) )
  {
    HB_FUNC_EXEC( QTESTEVENTLIST_ADDKEYCLICK2 );
  }
}

/*
void addKeyClicks ( const QString & keys, Qt::KeyboardModifiers modifiers = Qt::NoModifier, int msecs = -1 )
*/
HB_FUNC_STATIC( QTESTEVENTLIST_ADDKEYCLICKS )
{
  QTestEventList * obj = (QTestEventList *) hb_itemGetPtr( hb_objSendMsg( hb_stackSelfItem(), "POINTER", 0 ) );
  if( obj )
  {
    obj->addKeyClicks ( PQSTRING(1), ISNIL(2)? Qt::NoModifier : (Qt::KeyboardModifiers) hb_parni(2), OPINT(3,-1) );
  }
  hb_itemReturn( hb_stackSelfItem() );
}

/*
void addKeyPress ( Qt::Key qtKey, Qt::KeyboardModifiers modifiers = Qt::NoModifier, int msecs = -1 )
*/
HB_FUNC_STATIC( QTESTEVENTLIST_ADDKEYPRESS1 )
{
  QTestEventList * obj = (QTestEventList *) hb_itemGetPtr( hb_objSendMsg( hb_stackSelfItem(), "POINTER", 0 ) );
  if( obj )
  {
    obj->addKeyPress ( (Qt::Key) hb_parni(1), ISNIL(2)? Qt::NoModifier : (Qt::KeyboardModifiers) hb_parni(2), OPINT(3,-1) );
  }
  hb_itemReturn( hb_stackSelfItem() );
}

/*
void addKeyPress ( char ascii, Qt::KeyboardModifiers modifiers = Qt::NoModifier, int msecs = -1 )
*/
HB_FUNC_STATIC( QTESTEVENTLIST_ADDKEYPRESS2 )
{
  QTestEventList * obj = (QTestEventList *) hb_itemGetPtr( hb_objSendMsg( hb_stackSelfItem(), "POINTER", 0 ) );
  if( obj )
  {
    char par1 = ISCHAR(1)? (char) hb_parc(1)[0] : (ISNUM(1)? hb_parni(1) : 0);
    obj->addKeyPress ( par1, ISNIL(2)? Qt::NoModifier : (Qt::KeyboardModifiers) hb_parni(2), OPINT(3,-1) );
  }
  hb_itemReturn( hb_stackSelfItem() );
}

//[1]void addKeyPress ( Qt::Key qtKey, Qt::KeyboardModifiers modifiers = Qt::NoModifier, int msecs = -1 )
//[2]void addKeyPress ( char ascii, Qt::KeyboardModifiers modifiers = Qt::NoModifier, int msecs = -1 )

HB_FUNC_STATIC( QTESTEVENTLIST_ADDKEYPRESS )
{
  if( ISBETWEEN(1,3) && ISNUM(1) && (ISNUM(2)||ISNIL(2)) && (ISNUM(3)||ISNIL(3)) )
  {
    HB_FUNC_EXEC( QTESTEVENTLIST_ADDKEYPRESS1 );
  }
  else if( ISBETWEEN(1,3) && ISCHAR(1) && (ISNUM(2)||ISNIL(2)) && (ISNUM(3)||ISNIL(3)) )
  {
    HB_FUNC_EXEC( QTESTEVENTLIST_ADDKEYPRESS2 );
  }
}

/*
void addKeyRelease ( Qt::Key qtKey, Qt::KeyboardModifiers modifiers = Qt::NoModifier, int msecs = -1 )
*/
HB_FUNC_STATIC( QTESTEVENTLIST_ADDKEYRELEASE1 )
{
  QTestEventList * obj = (QTestEventList *) hb_itemGetPtr( hb_objSendMsg( hb_stackSelfItem(), "POINTER", 0 ) );
  if( obj )
  {
    obj->addKeyRelease ( (Qt::Key) hb_parni(1), ISNIL(2)? Qt::NoModifier : (Qt::KeyboardModifiers) hb_parni(2), OPINT(3,-1) );
  }
  hb_itemReturn( hb_stackSelfItem() );
}

/*
void addKeyRelease ( char ascii, Qt::KeyboardModifiers modifiers = Qt::NoModifier, int msecs = -1 )
*/
HB_FUNC_STATIC( QTESTEVENTLIST_ADDKEYRELEASE2 )
{
  QTestEventList * obj = (QTestEventList *) hb_itemGetPtr( hb_objSendMsg( hb_stackSelfItem(), "POINTER", 0 ) );
  if( obj )
  {
    char par1 = ISCHAR(1)? (char) hb_parc(1)[0] : (ISNUM(1)? hb_parni(1) : 0);
    obj->addKeyRelease ( par1, ISNIL(2)? Qt::NoModifier : (Qt::KeyboardModifiers) hb_parni(2), OPINT(3,-1) );
  }
  hb_itemReturn( hb_stackSelfItem() );
}

//[1]void addKeyRelease ( Qt::Key qtKey, Qt::KeyboardModifiers modifiers = Qt::NoModifier, int msecs = -1 )
//[2]void addKeyRelease ( char ascii, Qt::KeyboardModifiers modifiers = Qt::NoModifier, int msecs = -1 )

HB_FUNC_STATIC( QTESTEVENTLIST_ADDKEYRELEASE )
{
  if( ISBETWEEN(1,3) && ISNUM(1) && (ISNUM(2)||ISNIL(2)) && (ISNUM(3)||ISNIL(3)) )
  {
    HB_FUNC_EXEC( QTESTEVENTLIST_ADDKEYRELEASE1 );
  }
  else if( ISBETWEEN(1,3) && ISCHAR(1) && (ISNUM(2)||ISNIL(2)) && (ISNUM(3)||ISNIL(3)) )
  {
    HB_FUNC_EXEC( QTESTEVENTLIST_ADDKEYRELEASE2 );
  }
}

/*
void addMouseClick ( Qt::MouseButton button, Qt::KeyboardModifiers modifiers = 0, QPoint pos = QPoint(), int delay = -1 )
*/
HB_FUNC_STATIC( QTESTEVENTLIST_ADDMOUSECLICK )
{
  QTestEventList * obj = (QTestEventList *) hb_itemGetPtr( hb_objSendMsg( hb_stackSelfItem(), "POINTER", 0 ) );
  int par2 = ISNIL(2)? 0 :  hb_parni(2);
  if( obj )
  {
    QPoint par3 = ISNIL(3)? QPoint() : *(QPoint *) hb_itemGetPtr( hb_objSendMsg( hb_param(3, HB_IT_OBJECT ), "POINTER", 0 ) );
    obj->addMouseClick ( (Qt::MouseButton) hb_parni(1), (Qt::KeyboardModifiers) par2, par3, OPINT(4,-1) );
  }
  hb_itemReturn( hb_stackSelfItem() );
}

/*
void addMouseDClick ( Qt::MouseButton button, Qt::KeyboardModifiers modifiers = 0, QPoint pos = QPoint(), int delay = -1 )
*/
HB_FUNC_STATIC( QTESTEVENTLIST_ADDMOUSEDCLICK )
{
  QTestEventList * obj = (QTestEventList *) hb_itemGetPtr( hb_objSendMsg( hb_stackSelfItem(), "POINTER", 0 ) );
  int par2 = ISNIL(2)? 0 :  hb_parni(2);
  if( obj )
  {
    QPoint par3 = ISNIL(3)? QPoint() : *(QPoint *) hb_itemGetPtr( hb_objSendMsg( hb_param(3, HB_IT_OBJECT ), "POINTER", 0 ) );
    obj->addMouseDClick ( (Qt::MouseButton) hb_parni(1), (Qt::KeyboardModifiers) par2, par3, OPINT(4,-1) );
  }
  hb_itemReturn( hb_stackSelfItem() );
}

/*
void addMouseMove ( QPoint pos = QPoint(), int delay = -1 )
*/
HB_FUNC_STATIC( QTESTEVENTLIST_ADDMOUSEMOVE )
{
  QTestEventList * obj = (QTestEventList *) hb_itemGetPtr( hb_objSendMsg( hb_stackSelfItem(), "POINTER", 0 ) );
  if( obj )
  {
    QPoint par1 = ISNIL(1)? QPoint() : *(QPoint *) hb_itemGetPtr( hb_objSendMsg( hb_param(1, HB_IT_OBJECT ), "POINTER", 0 ) );
    obj->addMouseMove ( par1, OPINT(2,-1) );
  }
  hb_itemReturn( hb_stackSelfItem() );
}

/*
void addMousePress ( Qt::MouseButton button, Qt::KeyboardModifiers modifiers = 0, QPoint pos = QPoint(), int delay = -1 )
*/
HB_FUNC_STATIC( QTESTEVENTLIST_ADDMOUSEPRESS )
{
  QTestEventList * obj = (QTestEventList *) hb_itemGetPtr( hb_objSendMsg( hb_stackSelfItem(), "POINTER", 0 ) );
  int par2 = ISNIL(2)? 0 :  hb_parni(2);
  if( obj )
  {
    QPoint par3 = ISNIL(3)? QPoint() : *(QPoint *) hb_itemGetPtr( hb_objSendMsg( hb_param(3, HB_IT_OBJECT ), "POINTER", 0 ) );
    obj->addMousePress ( (Qt::MouseButton) hb_parni(1), (Qt::KeyboardModifiers) par2, par3, OPINT(4,-1) );
  }
  hb_itemReturn( hb_stackSelfItem() );
}

/*
void addMouseRelease ( Qt::MouseButton button, Qt::KeyboardModifiers modifiers = 0, QPoint pos = QPoint(), int delay = -1 )
*/
HB_FUNC_STATIC( QTESTEVENTLIST_ADDMOUSERELEASE )
{
  QTestEventList * obj = (QTestEventList *) hb_itemGetPtr( hb_objSendMsg( hb_stackSelfItem(), "POINTER", 0 ) );
  int par2 = ISNIL(2)? 0 :  hb_parni(2);
  if( obj )
  {
    QPoint par3 = ISNIL(3)? QPoint() : *(QPoint *) hb_itemGetPtr( hb_objSendMsg( hb_param(3, HB_IT_OBJECT ), "POINTER", 0 ) );
    obj->addMouseRelease ( (Qt::MouseButton) hb_parni(1), (Qt::KeyboardModifiers) par2, par3, OPINT(4,-1) );
  }
  hb_itemReturn( hb_stackSelfItem() );
}

/*
void clear ()
*/
HB_FUNC_STATIC( QTESTEVENTLIST_CLEAR )
{
  QTestEventList * obj = (QTestEventList *) hb_itemGetPtr( hb_objSendMsg( hb_stackSelfItem(), "POINTER", 0 ) );
  if( obj )
  {
    obj->clear ();
  }
  hb_itemReturn( hb_stackSelfItem() );
}

/*
void simulate ( QWidget * w )
*/
HB_FUNC_STATIC( QTESTEVENTLIST_SIMULATE )
{
  QTestEventList * obj = (QTestEventList *) hb_itemGetPtr( hb_objSendMsg( hb_stackSelfItem(), "POINTER", 0 ) );
  if( obj )
  {
    obj->simulate ( PQWIDGET(1) );
  }
  hb_itemReturn( hb_stackSelfItem() );
}

$extraMethods

#pragma ENDDUMP


FIX Threading issue for MemVar

FIX Threading issue for MemVar

//
// Copyright (c) XSharp B.V.  All Rights Reserved.
// Licensed under the Apache License, Version 2.0.
// See License.txt in the project root for license information.
//

USING System.Collections.Generic
USING System.Linq
USING System.Diagnostics
USING System.Text
USING System.Threading

// Class that holds the memvars for a certain level on the callstack
[DebuggerDisplay("Level:{Depth}")];
INTERNAL CLASS XSharp.MemVarLevel
	PROPERTY Variables AS Dictionary<STRING, MemVar> AUTO
	PROPERTY Depth AS INT AUTO GET PRIVATE SET
	CONSTRUCTOR (nDepth AS INT)
		Variables   := Dictionary<STRING, MemVar>{StringComparer.OrdinalIgnoreCase}
		Depth       := nDepth
		RETURN

	METHOD Add(variable AS MemVar) AS VOID
#ifdef DEBUG
		variable:Level := SELF
#endif
		Variables:Add(variable:Name, variable)
		RETURN

	METHOD ContainsKey(cName AS STRING) AS LOGIC
		RETURN Variables:ContainsKey(cName)

	METHOD TryGetValue(cName AS STRING, VALUE OUT MemVar) AS LOGIC
		RETURN Variables:TryGetValue(cName, OUT VALUE)

	PROPERTY SELF[Name AS STRING] AS MemVar
		GET
			LOCAL memvar AS MemVar
			IF Variables:TryGetValue(name, OUT memvar)
				RETURN memvar
			ENDIF
			RETURN NULL
		END GET
	END PROPERTY

	PROPERTY Keys AS IEnumerable<STRING> GET Variables:Keys

	METHOD Clear() AS VOID STRICT
		Variables:Clear()

	PROPERTY Count AS INT GET Variables:Count

END CLASS

[DebuggerDisplay("Memvar: {Name}")];
PUBLIC CLASS XSharp.MemVar

    INTERNAL CLASS MemVarThreadInfo
        INTERNAL Levels as Stack <MemVarLevel>
        INTERNAL Depth  as INT
        CONSTRUCTOR()
            Levels := Stack <MemVarLevel>{32}
            Depth  := 0
            RETURN

    END CLASS

	// Static fields that monitor all memvars
	PRIVATE STATIC Publics  AS MemVarLevel

    // Stack local privates with initializer and property to access the current stacks privates
    PRIVATE STATIC ThreadList := ThreadLocal< MemVarThreadInfo >{ {=> MemVarThreadInfo{} }}  AS ThreadLocal< MemVarThreadInfo >
    PRIVATE STATIC PROPERTY Info       as MemVarThreadInfo          GET ThreadList:Value
	PRIVATE STATIC PROPERTY Privates   AS Stack <MemVarLevel>       GET Info:Levels
    PRIVATE STATIC PROPERTY Depth      AS INT GET Info:Depth        SET Info:Depth := Value
	PRIVATE STATIC PROPERTY Current    AS MemVarLevel GET IIF (Privates:Count > 0, Privates:Peek(), NULL)

    // for the enumeration.
	PRIVATE STATIC _PrivatesEnum AS IEnumerator<STRING>
	PRIVATE STATIC _PublicsEnum  AS IEnumerator<STRING>

	STATIC CONSTRUCTOR
		Publics  		:= MemVarLevel{-1}
		_PrivatesEnum 	:= NULL
		_PublicsEnum  	:= NULL
		Depth           := 0

    // Instance fields
  	PUBLIC Name 	AS STRING
  	PUBLIC @@Value 	AS USUAL
#ifdef DEBUG
  	INTERNAL Level	AS MemVarLevel
#endif
	CONSTRUCTOR (cName AS STRING, uValue AS USUAL)
	  		Name := cName:ToUpper()
	  		SELF:Value := uValue
	  		RETURN
#region Privates
	STATIC METHOD InitPrivates() AS INT
		// Initialize privates for a new function/method
		// returns # of levels available after initialization
		Depth 	+= 1
		RETURN Depth

	STATIC METHOD CheckCurrent() AS VOID
		IF Privates:Count() == 0 .OR. Privates:Peek():Depth < Depth
			Privates:Push( MemVarLevel{ Depth })
		ENDIF

	STATIC METHOD ReleasePrivates(nLevel AS INT) AS LOGIC
		DO WHILE Privates:Count > 0 .AND. Privates:Peek():Depth >= nLevel
			Privates:Pop()
		ENDDO
		Depth --
		RETURN TRUE

	STATIC METHOD GetHigherLevelPrivate(name AS STRING) AS XSharp.MemVar
		FOREACH VAR previous IN privates
			LOCAL memvar AS MemVar
			IF previous!= current .AND. previous:TryGetValue(name, OUT memvar)
				RETURN memvar
			ENDIF
		NEXT
		RETURN NULL

	STATIC METHOD PrivatePut(name AS STRING, VALUE AS USUAL) AS LOGIC
		CheckCurrent()
		LOCAL memvar AS MemVar
		IF current:TryGetValue(name, OUT memvar)
			MEMVAR:Value := VALUE
			RETURN TRUE
		ENDIF
        MEMVAR := GetHigherLevelPrivate(name)
        IF memvar != NULL
        	MEMVAR:Value := VALUE
        	RETURN TRUE
        ENDIF
		RETURN FALSE

	STATIC METHOD PrivateFind(name AS STRING) AS MemVar
		LOCAL memvar AS MemVar
		IF current != NULL .AND. current:TryGetValue(name, OUT memvar)
			RETURN memvar
		ENDIF
        RETURN GetHigherLevelPrivate(name)

	STATIC METHOD Release(name AS STRING) AS VOID
		// assign nil to visible private. Does not really release the variable.
		VAR Memvar := PrivateFind(name)
		IF memvar == NULL
			MEMVAR := PublicFind(name)
		ENDIF
		IF memvar != NULL
			MEMVAR:Value := NIL
		ELSE
			THROW Exception{"Variable "+name:ToString()+" does not exist"}
		ENDIF
		RETURN

	STATIC PRIVATE METHOD _GetUniquePrivates(lCurrentOnly := FALSE AS LOGIC) AS List<STRING>
		VAR _TempPrivates := List<STRING>{}
		IF lCurrentOnly
			IF Current != NULL
				_TempPrivates:AddRange(current:Keys)
			ENDIF
		ELSE
			FOREACH VAR previous IN privates
				IF _TempPrivates:Count == 0
					_TempPrivates:AddRange(previous:Keys)
				ELSE
					FOREACH VAR key IN previous:Keys
						IF !_tempPrivates:Contains(key)
							_tempPrivates:Add(key)
						ENDIF
					NEXT
				ENDIF
			NEXT
		ENDIF
	    RETURN _TempPrivates

	STATIC METHOD PrivatesEnum(lCurrentOnly := FALSE AS LOGIC) AS IEnumerator<STRING>
		RETURN _GetUniquePrivates(lCurrentOnly):GetEnumerator()

 	STATIC METHOD PrivatesFirst(lCurrentOnly := FALSE AS LOGIC) AS STRING
		_PrivatesEnum := PrivatesEnum(lCurrentOnly)
		_PrivatesEnum:Reset()
		RETURN PrivatesNext()

	STATIC METHOD PrivatesNext() AS STRING
		IF _PrivatesEnum != NULL
			IF _PrivatesEnum:MoveNext()
				RETURN _PrivatesEnum:Current
			ENDIF
			_PrivatesEnum  := NULL
		ENDIF
		RETURN NULL_STRING

	STATIC METHOD PrivatesCount(lCurrentOnly := FALSE AS LOGIC) AS INT
		RETURN _GetUniquePrivates(lCurrentOnly):Count

	STATIC METHOD ReleaseAll() AS VOID
		// Assign NIL to all currenly visible private variables
		// Hidden privates are not affected
		FOREACH VAR sym IN _GetUniquePrivates(FALSE)
			PrivatePut(sym, NIL)
		NEXT
		RETURN

#endregion

#region Generic - Public and Private

	STATIC METHOD Add(name AS STRING, _priv AS LOGIC) AS VOID
		IF _priv
			CheckCurrent()
			IF !Current:ContainsKey(name)
				Current:Add(MemVar{name,NIL})
			ENDIF
		ELSE
            BEGIN LOCK Publics
			    IF !Publics:ContainsKey(name)
				    VAR memvar := MemVar{name,NIL}
				    Publics:Add(memvar )
			    ENDIF
            END LOCK
		ENDIF

	STATIC METHOD Get(name AS STRING) AS USUAL
		LOCAL oMemVar AS MemVar
		// privates take precedence over publics ?
		oMemVar := PrivateFind(name)
		IF oMemVar == NULL
			oMemVar := PublicFind(name)
		ENDIF
		IF oMemVar != NULL
			RETURN oMemVar:Value
		ENDIF
		THROW Error{"Undeclared variable :"+name:ToString()}

	STATIC METHOD Put(name AS STRING, VALUE AS USUAL) AS USUAL
		LOCAL oMemVar AS MemVar
		// assign to existing memvar first
		// privates take precedence over publics ?
		oMemVar := PrivateFind(name)
		IF oMemVar == NULL
			oMemVar := PublicFind(name)
		ENDIF
		IF oMemVar != NULL
            BEGIN LOCK oMemVar
			    oMemVar:Value := VALUE
            END LOCK
		ELSE
			// memvar does not exist, then add it at the current level
			CheckCurrent()
			Current:Add(MemVar{name,VALUE})
		ENDIF
		RETURN VALUE

	STATIC METHOD ClearAll() AS VOID
		// Remove all public and private variables
		// Does not clear the privates stack levels
        BEGIN LOCK Publics
		    Publics:Clear()
        END LOCK
		FOREACH VAR level IN Privates
			level:Clear()
		NEXT

#endregion

#region Publics

	STATIC METHOD PublicFind(name AS STRING) AS MemVar
		LOCAL oMemVar AS MemVar
        BEGIN LOCK Publics
		    IF Publics:TryGetValue(name, OUT oMemVar)
			    RETURN oMemVar
		    ENDIF
        END LOCK
		RETURN NULL

	STATIC METHOD PublicPut(name AS STRING, VALUE AS USUAL) AS LOGIC
		VAR oMemVar := PublicFind(name)
		IF oMemVar != NULL
            BEGIN LOCK oMemVar
			    oMemVar:Value := VALUE
            END LOCK
			RETURN TRUE
		ENDIF
		RETURN FALSE

	STATIC METHOD PublicsEnum() AS IEnumerator<STRING>
        BEGIN LOCK Publics
		    RETURN Publics:Keys:GetEnumerator()
        END LOCK

	STATIC METHOD PublicsFirst() AS STRING
		_PublicsEnum := PublicsEnum()
		_PublicsEnum:Reset()
		RETURN PublicsNext()

	STATIC METHOD PublicsNext() AS STRING
		IF _PublicsEnum != NULL
			IF _PublicsEnum:MoveNext()
				RETURN _PublicsEnum:Current
			ENDIF
			_PublicsEnum := NULL
		ENDIF
		RETURN NULL_STRING

	STATIC METHOD PublicsCount() AS INT
        BEGIN LOCK Publics
		    RETURN Publics:Count
        END LOCK

#endregion
END CLASS

//
// Copyright (c) XSharp B.V.  All Rights Reserved.
// Licensed under the Apache License, Version 2.0.
// See License.txt in the project root for license information.
//

USING System.Collections.Generic
USING System.Linq
USING System.Diagnostics
USING System.Text
USING System.Threading

// Class that holds the memvars for a certain level on the callstack
[DebuggerDisplay("Level:{Depth}")];
INTERNAL CLASS XSharp.MemVarLevel
	PROPERTY Variables AS Dictionary<STRING, MemVar> AUTO
	PROPERTY Depth AS INT AUTO GET PRIVATE SET
	CONSTRUCTOR (nDepth AS INT)
		Variables   := Dictionary<STRING, MemVar>{StringComparer.OrdinalIgnoreCase}
		Depth       := nDepth
		RETURN

	METHOD Add(variable AS MemVar) AS VOID
#ifdef DEBUG
		variable:Level := SELF
#endif
		Variables:Add(variable:Name, variable)
		RETURN

	METHOD ContainsKey(cName AS STRING) AS LOGIC
		RETURN Variables:ContainsKey(cName)

	METHOD TryGetValue(cName AS STRING, VALUE OUT MemVar) AS LOGIC
		RETURN Variables:TryGetValue(cName, OUT VALUE)

	PROPERTY SELF[Name AS STRING] AS MemVar
		GET
			LOCAL memvar AS MemVar
			IF Variables:TryGetValue(name, OUT memvar)
				RETURN memvar
			ENDIF
			RETURN NULL
		END GET
	END PROPERTY

	PROPERTY Keys AS IEnumerable<STRING> GET Variables:Keys

	METHOD Clear() AS VOID STRICT
		Variables:Clear()

	PROPERTY Count AS INT GET Variables:Count

END CLASS

[DebuggerDisplay("Memvar: {Name}")];
PUBLIC CLASS XSharp.MemVar

    INTERNAL CLASS MemVarThreadInfo
        INTERNAL Levels as Stack <MemVarLevel>
        INTERNAL Depth  as INT
        CONSTRUCTOR()
            Levels := Stack <MemVarLevel>{32}
            Depth  := 0
            RETURN

    END CLASS

	// Static fields that monitor all memvars
	PRIVATE STATIC Publics  AS MemVarLevel

    // Stack local privates with initializer and property to access the current stacks privates
    PRIVATE STATIC ThreadList := ThreadLocal< MemVarThreadInfo >{ {=> MemVarThreadInfo{} }}  AS ThreadLocal< MemVarThreadInfo >
    PRIVATE STATIC PROPERTY Info       as MemVarThreadInfo          GET ThreadList:Value
	PRIVATE STATIC PROPERTY Privates   AS Stack <MemVarLevel>       GET Info:Levels
    PRIVATE STATIC PROPERTY Depth      AS INT GET Info:Depth        SET Info:Depth := Value
	PRIVATE STATIC PROPERTY Current    AS MemVarLevel GET Privates:Peek()

    // for the enumeration.
	PRIVATE STATIC _PrivatesEnum AS IEnumerator<STRING>
	PRIVATE STATIC _PublicsEnum  AS IEnumerator<STRING>

	STATIC CONSTRUCTOR
		Publics  		:= MemVarLevel{-1}
		_PrivatesEnum 	:= NULL
		_PublicsEnum  	:= NULL
		Depth           := 0

    // Instance fields
  	PUBLIC Name 	AS STRING
  	PUBLIC @@Value 	AS USUAL
#ifdef DEBUG
  	INTERNAL Level	AS MemVarLevel
#endif
	CONSTRUCTOR (cName AS STRING, uValue AS USUAL)
	  		Name := cName:ToUpper()
	  		SELF:Value := uValue
	  		RETURN
#region Privates
	STATIC METHOD InitPrivates() AS INT
		// Initialize privates for a new function/method
		// returns # of levels available after initialization
		Depth 	+= 1
		RETURN Depth

	STATIC METHOD CheckCurrent() AS VOID
		IF Privates:Count() == 0 .OR. Privates:Peek():Depth < Depth
			Privates:Push( MemVarLevel{ Depth })
		ENDIF

	STATIC METHOD ReleasePrivates(nLevel AS INT) AS LOGIC
		DO WHILE Privates:Count > 0 .AND. Privates:Peek():Depth >= nLevel
			Privates:Pop()
		ENDDO
		Depth --
		RETURN TRUE

	STATIC METHOD GetHigherLevelPrivate(name AS STRING) AS XSharp.MemVar
		FOREACH VAR previous IN privates
			LOCAL memvar AS MemVar
			IF previous!= current .AND. previous:TryGetValue(name, OUT memvar)
				RETURN memvar
			ENDIF
		NEXT
		RETURN NULL

	STATIC METHOD PrivatePut(name AS STRING, VALUE AS USUAL) AS LOGIC
		CheckCurrent()
		LOCAL memvar AS MemVar
		IF current:TryGetValue(name, OUT memvar)
			MEMVAR:Value := VALUE
			RETURN TRUE
		ENDIF
        MEMVAR := GetHigherLevelPrivate(name)
        IF memvar != NULL
        	MEMVAR:Value := VALUE
        	RETURN TRUE
        ENDIF
		RETURN FALSE

	STATIC METHOD PrivateFind(name AS STRING) AS MemVar
		LOCAL memvar AS MemVar
		IF current != NULL .AND. current:TryGetValue(name, OUT memvar)
			RETURN memvar
		ENDIF
        RETURN GetHigherLevelPrivate(name)

	STATIC METHOD Release(name AS STRING) AS VOID
		// assign nil to visible private. Does not really release the variable.
		VAR Memvar := PrivateFind(name)
		IF memvar == NULL
			MEMVAR := PublicFind(name)
		ENDIF
		IF memvar != NULL
			MEMVAR:Value := NIL
		ELSE
			THROW Exception{"Variable "+name:ToString()+" does not exist"}
		ENDIF
		RETURN

	STATIC PRIVATE METHOD _GetUniquePrivates(lCurrentOnly := FALSE AS LOGIC) AS List<STRING>
		VAR _TempPrivates := List<STRING>{}
		IF lCurrentOnly
			IF Current != NULL
				_TempPrivates:AddRange(current:Keys)
			ENDIF
		ELSE
			FOREACH VAR previous IN privates
				IF _TempPrivates:Count == 0
					_TempPrivates:AddRange(previous:Keys)
				ELSE
					FOREACH VAR key IN previous:Keys
						IF !_tempPrivates:Contains(key)
							_tempPrivates:Add(key)
						ENDIF
					NEXT
				ENDIF
			NEXT
		ENDIF
	    RETURN _TempPrivates

	STATIC METHOD PrivatesEnum(lCurrentOnly := FALSE AS LOGIC) AS IEnumerator<STRING>
		RETURN _GetUniquePrivates(lCurrentOnly):GetEnumerator()

 	STATIC METHOD PrivatesFirst(lCurrentOnly := FALSE AS LOGIC) AS STRING
		_PrivatesEnum := PrivatesEnum(lCurrentOnly)
		_PrivatesEnum:Reset()
		RETURN PrivatesNext()

	STATIC METHOD PrivatesNext() AS STRING
		IF _PrivatesEnum != NULL
			IF _PrivatesEnum:MoveNext()
				RETURN _PrivatesEnum:Current
			ENDIF
			_PrivatesEnum  := NULL
		ENDIF
		RETURN NULL_STRING

	STATIC METHOD PrivatesCount(lCurrentOnly := FALSE AS LOGIC) AS INT
		RETURN _GetUniquePrivates(lCurrentOnly):Count

	STATIC METHOD ReleaseAll() AS VOID
		// Assign NIL to all currenly visible private variables
		// Hidden privates are not affected
		FOREACH VAR sym IN _GetUniquePrivates(FALSE)
			PrivatePut(sym, NIL)
		NEXT
		RETURN

#endregion

#region Generic - Public and Private

	STATIC METHOD Add(name AS STRING, _priv AS LOGIC) AS VOID
		IF _priv
			CheckCurrent()
			IF !Current:ContainsKey(name)
				Current:Add(MemVar{name,NIL})
			ENDIF
		ELSE
            BEGIN LOCK Publics
			    IF !Publics:ContainsKey(name)
				    VAR memvar := MemVar{name,NIL}
				    Publics:Add(memvar )
			    ENDIF
            END LOCK
		ENDIF

	STATIC METHOD Get(name AS STRING) AS USUAL
		LOCAL oMemVar AS MemVar
		// privates take precedence over publics ?
		oMemVar := PrivateFind(name)
		IF oMemVar == NULL
			oMemVar := PublicFind(name)
		ENDIF
		IF oMemVar != NULL
			RETURN oMemVar:Value
		ENDIF
		THROW Error{"Undeclared variable :"+name:ToString()}

	STATIC METHOD Put(name AS STRING, VALUE AS USUAL) AS USUAL
		LOCAL oMemVar AS MemVar
		// assign to existing memvar first
		// privates take precedence over publics ?
		oMemVar := PrivateFind(name)
		IF oMemVar == NULL
			oMemVar := PublicFind(name)
		ENDIF
		IF oMemVar != NULL
            BEGIN LOCK oMemVar
			    oMemVar:Value := VALUE
            END LOCK
		ELSE
			// memvar does not exist, then add it at the current level
			CheckCurrent()
			Current:Add(MemVar{name,VALUE})
		ENDIF
		RETURN VALUE

	STATIC METHOD ClearAll() AS VOID
		// Remove all public and private variables
		// Does not clear the privates stack levels
        BEGIN LOCK Publics
		    Publics:Clear()
        END LOCK
		FOREACH VAR level IN Privates
			level:Clear()
		NEXT

#endregion

#region Publics

	STATIC METHOD PublicFind(name AS STRING) AS MemVar
		LOCAL oMemVar AS MemVar
        BEGIN LOCK Publics
		    IF Publics:TryGetValue(name, OUT oMemVar)
			    RETURN oMemVar
		    ENDIF
        END LOCK
		RETURN NULL

	STATIC METHOD PublicPut(name AS STRING, VALUE AS USUAL) AS LOGIC
		VAR oMemVar := PublicFind(name)
		IF oMemVar != NULL
            BEGIN LOCK oMemVar
			    oMemVar:Value := VALUE
            END LOCK
			RETURN TRUE
		ENDIF
		RETURN FALSE

	STATIC METHOD PublicsEnum() AS IEnumerator<STRING>
        BEGIN LOCK Publics
		    RETURN Publics:Keys:GetEnumerator()
        END LOCK

	STATIC METHOD PublicsFirst() AS STRING
		_PublicsEnum := PublicsEnum()
		_PublicsEnum:Reset()
		RETURN PublicsNext()

	STATIC METHOD PublicsNext() AS STRING
		IF _PublicsEnum != NULL
			IF _PublicsEnum:MoveNext()
				RETURN _PublicsEnum:Current
			ENDIF
			_PublicsEnum := NULL
		ENDIF
		RETURN NULL_STRING

	STATIC METHOD PublicsCount() AS INT
        BEGIN LOCK Publics
		    RETURN Publics:Count
        END LOCK

#endregion
END CLASS