Click here to Skip to main content
15,886,783 members
Articles / Containers / Virtual Machine

TOOL

Rate me:
Please Sign up or sign in to vote.
4.98/5 (52 votes)
23 Oct 200676 min read 230.3K   5.4K   147  
TOOL (Tiny Object Oriented Language) is an easily-embedded, object-oriented, C++-like-language interpreter. The purpose of this article is to introduce the TOOL interpreter and language from the perspective of a person who has a desire to include a scripting solution as part of his project.
/*****************************************************************************/
/*                              SOURCE FILE                                  */
/*****************************************************************************/
/*
       $Archive: $

      $Revision: $
          $Date: $
        $Author: $

    Description: Implementation of the VirtualOpSys class for the InterPiler.
                 Class uses a mark-sweep algorithm for garbage collection.

                 Portions of this code is based on work by David Betz as published
                 in Dr. Dobb's Journal. However, the code has been significantly
                 reworked, reformatted, and enhanced so it may not resemble any of
                 the original files at all. Other specific portions of this derivation
                 are based on the work of Michael Swartzendruber.

                      TOOL And XML FORMS License
                      ==========================

                      Except where otherwise noted, all of the documentation 
                      and software included in the TOOL package is 
                      copyrighted by Michael Swartzendruber.

                      Copyright (C) 2005 Michael John Swartzendruber. 
                      All rights reserved.

                      Access to this code, whether intentional or accidental,
                      does NOT IMPLY any transfer of rights.

                      This software is provided "as-is," without any express 
                      or implied warranty. In no event shall the author be held
                      liable for any damages arising from the use of this software.

                      Permission is granted to anyone to use this software for 
                      any purpose, including commercial applications, and to 
                      alter and redistribute it, provided that the following 
                      conditions are met:

                      1. All redistributions of source code files must retain 
                         all copyright notices that are currently in place, 
                         and this list of conditions without modification.

                      2. The origin of this software must not be misrepresented;
                         you must not claim that you wrote the original software.

                      3. If you use this software in another product, an acknowledgment
                         in the product documentation would be appreciated but is
                         not required.

                      4. Modified versions in source or binary form must be plainly 
                         marked as such, and must not be misrepresented as being 
                         the original software.
*/
static char OBJECT_ID[] = "$Revision: $ : $Date: $";
/*****************************************************************************/

#define WINVER 0x0501 //2b|!2b==?

#include "VMCoreVirtualOpSysIncludes.h"

VMVirtualOpSys* gpoOpSys = NULL;

#ifdef TOOL_PUBLIC_BUILD
/*****************************************************************************/
/*

     FUNCTION NAME:  VMVariant::VMVariant

       DESCRIPTION:  copy ctor for variant object. provided so that if a 
                     value is assigned to another with a 'previous value' that
                     no heap allocatations will be leaked

             INPUT:  roOther - 
            OUTPUT:  none

           RETURNS:  none 
*/
VMVariant::VMVariant( VMVariant& roOther )
{
  bool bCopyValue        = true;
  bool bTypeLockViolated = false;
  if ( v_typelocked )
  {
    if ( v_type != roOther.v_type )
    {
      bTypeLockViolated = true;
    }
  }
  if ( NULL != v_poMonitor )
    delete v_poMonitor;

  if ( DT_STRING == v_type )
  {
    if ( v.v_string->str_runtime == true )
    {
      delete [] v.v_string->str_data;
      v.v_string->str_data = NULL;
    }
  }
  else
  if ( DT_STACK == v_type )
  {
    if ( roOther.v_type != DT_STACK )
    {
      delete v.v_stack;
      v.v_stack = NULL;
    }
    else
    {
      bCopyValue = false;

      v.v_stack->Clear();
      v.v_stack->DeepCopy( *roOther.v.v_stack );
     }
  }
  else
  if ( DT_QUEUE == v_type )
  {
    if ( roOther.v_type != DT_QUEUE )
    {
      delete v.v_queue;
      v.v_queue = NULL;
    }
    else
    {
      bCopyValue = false;

      v.v_queue->Clear();
      v.v_queue->DeepCopy( *roOther.v.v_queue );
    }
  }
  else
  if ( DT_HASHTABLE == v_type )
  {
    if ( roOther.v_type != DT_HASHTABLE )
    {
      delete v.v_hashtable;
      v.v_hashtable = NULL;
    }
    else
    {
      bCopyValue = false;

      v.v_hashtable->Erase();
      v.v_hashtable->DeepCopy( *roOther.v.v_hashtable );
    }
  }
  else
  if ( DT_CALCULATOR == v_type )
  {
    delete v.v_calculator;
    v.v_calculator = NULL;
  }
  else
  if ( DT_TOKENIZER == v_type )
  {
    delete v.v_tokenizer;
    v.v_tokenizer = NULL;
  }
  else
  if ( DT_BYTEARRAY == v_type )
  {
    if ( roOther.v_type != DT_BYTEARRAY )
    {
      delete v.v_bytearray;
      v.v_bytearray = NULL;
    }
    else
    {
      bCopyValue = false;

      v.v_bytearray->FreeAll();
      v.v_bytearray->Append( *roOther.v.v_bytearray );
    }
  }
  else
  if ( DT_USERVECTOR == v_type )
  {
    if ( roOther.v_type != DT_USERVECTOR )
    {
      delete v.v_uservector;
      v.v_uservector = NULL;
    }
    else
    {
      bCopyValue = false;

      v.v_uservector->Clear();
      v.v_uservector->DeepCopy( *roOther.v.v_uservector );
    }
  }
  else
  if ( DT_REPORTPAGE == v_type )
  {
    delete v.v_page;
    v.v_page = NULL;
  }
  else
  if ( DT_REPORTTABLE == v_type )
  {
    delete v.v_pagetable;
    v.v_pagetable = NULL;
  }
  else
  if ( DT_ODBC == v_type )
  {
    delete v.v_odbc;
    v.v_odbc = NULL;
  }
  else
  if ( DT_CALCULATOR == v_type )
  {
    delete v.v_calculator;
    v.v_calculator = NULL;
  }
  else
  if ( DT_REGEX == v_type )
  {
    delete v.v_regex;
    v.v_regex = NULL;
  }
  else
  if ( DT_HTMLPARSER == v_type )
  {
    delete v.v_htmlparser;
    v.v_htmlparser = NULL;
  }
  else
  if ( DT_SQLLITE_2_DB == v_type )
  {
    delete v.v_sqllite2db;
    v.v_sqllite2db = NULL;
  }
  else
  if ( DT_UNZIPPER == v_type )
  {
    delete v.v_unzipper;
    v.v_unzipper = NULL;
  }  
  else
  if ( DT_ZIPMAKER == v_type )
  {
    delete v.v_zipmaker;
    v.v_zipmaker = NULL;
  }  
  else
  if ( DT_HTTPCLIENT == v_type )
  {
    delete v.v_httpclient;
    v.v_httpclient = NULL;
  }  
  else
  if ( DT_FTPCLIENT == v_type )
  {
    delete v.v_ftpclient;
    v.v_ftpclient = NULL;
  }  
  else
  if ( DT_SQLLITE_2_ROWSET == v_type )
  {
    delete v.v_sqllite2rowset;
    v.v_sqllite2rowset = NULL;
  }  
  else
  if ( DT_FILE_BUILDER == v_type )
  {
    delete v.v_filebuilder;
    v.v_filebuilder = NULL;
  }  
  else
  if ( DT_DELIMITED_FILE == v_type )
  {
    delete v.v_delimitedfile;
    v.v_delimitedfile = NULL;
  }  
  else
  if ( DT_EXCEL_EXPORTER == v_type )
  {
    delete v.v_excelwriter;
    v.v_excelwriter = NULL;
  }  
  else
  if ( DT_SQLLITE_3_DB == v_type )
  {
    delete v.v_sqllite3db;
    v.v_sqllite3db = NULL;
  }
  else
  if ( DT_SQLLITE_3_ROWSET == v_type )
  {
    delete v.v_sqllite3rowset;
    v.v_sqllite3rowset = NULL;
  }

  if ( !bTypeLockViolated )
  {
     v_type         = roOther.v_type;

     if ( v_type == DT_STRING )
     {
       if ( gpoOpSys )
       {
         bCopyValue = false;
         vmstring* pchReturn = gpoOpSys->AllocateNewString( roOther.v.v_string->str_size, true );
         strcpy( pchReturn->str_data, roOther.v.v_string->str_data );       
         v.v_string = pchReturn;
       }
     } 
     v_constant     = roOther.v_constant;
     v_tempconst    = roOther.v_tempconst;
     v_monitored    = roOther.v_monitored;
     v_poMonitor    = roOther.v_poMonitor;

     if ( bCopyValue )
     {
       v = roOther.v;
     }
  }
}
/* End of function "VMVariant::VMVariant"
/*****************************************************************************/


/*****************************************************************************/
/*

     FUNCTION NAME:  CloneValue 

       DESCRIPTION:  "assignment operator"

             INPUT:  roOther - the RHS
            OUTPUT:  none

           RETURNS:  *this
*/
VMVariant& VMVariant::CloneValue( const VMVariant& roOther )
{
  if ( &roOther == this )
  {
    return( *this );
  }

  bool bCopyValue        = true;
  bool bTypeLockViolated = false;
  if ( v_typelocked )
  {
    if ( v_type != roOther.v_type )
    {
      bTypeLockViolated = true;
    }
  }
  if ( NULL != v_poMonitor )
    delete v_poMonitor;

  if ( DT_STRING == v_type )
  {
    if ( v.v_string->str_runtime == true )
    {
      delete [] v.v_string->str_data;
      v.v_string->str_data = NULL;
    }
  }
  else
  if ( DT_STACK == v_type )
  {
    if ( roOther.v_type != DT_STACK )
    {
      delete v.v_stack;
      v.v_stack = NULL;
    }
    else
    {
      bCopyValue = false;

      v.v_stack->Clear();
      v.v_stack->DeepCopy( *roOther.v.v_stack );
     }
  }
  else
  if ( DT_QUEUE == v_type )
  {
    if ( roOther.v_type != DT_QUEUE )
    {
      delete v.v_queue;
      v.v_queue = NULL;
    }
    else
    {
      bCopyValue = false;

      v.v_queue->Clear();
      v.v_queue->DeepCopy( *roOther.v.v_queue );
    }
  }
  else
  if ( DT_HASHTABLE == v_type )
  {
    if ( roOther.v_type != DT_HASHTABLE )
    {
      delete v.v_hashtable;
      v.v_hashtable = NULL;
    }
    else
    {
      bCopyValue = false;

      v.v_hashtable->Erase();
      v.v_hashtable->DeepCopy( *roOther.v.v_hashtable );
    }
  }
  else
  if ( DT_CALCULATOR == v_type )
  {
    delete v.v_calculator;
    v.v_calculator = NULL;
  }
  else
  if ( DT_TOKENIZER == v_type )
  {
    delete v.v_tokenizer;
    v.v_tokenizer = NULL;
  }
  else
  if ( DT_BYTEARRAY == v_type )
  {
    if ( roOther.v_type != DT_BYTEARRAY )
    {
      delete v.v_bytearray;
      v.v_bytearray = NULL;
    }
    else
    {
      bCopyValue = false;

      v.v_bytearray->FreeAll();
      v.v_bytearray->Append( *roOther.v.v_bytearray );
    }
  }
  else
  if ( DT_USERVECTOR == v_type )
  {
    if ( roOther.v_type != DT_USERVECTOR )
    {
      delete v.v_uservector;
      v.v_uservector = NULL;
    }
    else
    {
      bCopyValue = false;

      v.v_uservector->Clear();
      v.v_uservector->DeepCopy( *roOther.v.v_uservector );
    }
  }
  else
  if ( DT_REPORTPAGE == v_type )
  {
    delete v.v_page;
    v.v_page = NULL;
  }
  else
  if ( DT_REPORTTABLE == v_type )
  {
    delete v.v_pagetable;
    v.v_pagetable = NULL;
  }
  else
  if ( DT_ODBC == v_type )
  {
    delete v.v_odbc;
    v.v_odbc = NULL;
  }
  else
  if ( DT_CALCULATOR == v_type )
  {
    delete v.v_calculator;
    v.v_calculator = NULL;
  }
  else
  if ( DT_REGEX == v_type )
  {
    delete v.v_regex;
    v.v_regex = NULL;
  }
  else
  if ( DT_HTMLPARSER == v_type )
  {
    delete v.v_htmlparser;
    v.v_htmlparser = NULL;
  }
  else
  if ( DT_SQLLITE_2_DB == v_type )
  {
    delete v.v_sqllite2db;
    v.v_sqllite2db = NULL;
  }
  else
  if ( DT_UNZIPPER == v_type )
  {
    delete v.v_unzipper;
    v.v_unzipper = NULL;
  }  
  else
  if ( DT_ZIPMAKER == v_type )
  {
    delete v.v_zipmaker;
    v.v_zipmaker = NULL;
  }  
  else
  if ( DT_HTTPCLIENT == v_type )
  {
    delete v.v_httpclient;
    v.v_httpclient = NULL;
  }  
  else
  if ( DT_FTPCLIENT == v_type )
  {
    delete v.v_ftpclient;
    v.v_ftpclient = NULL;
  }
  else  
  if ( DT_SQLLITE_2_ROWSET == v_type )
  {
    delete v.v_sqllite2rowset;
    v.v_sqllite2rowset = NULL;
  }  
  else  
  if ( DT_FILE_BUILDER == v_type )
  {
    delete v.v_filebuilder;
    v.v_filebuilder = NULL;
  }  
  else
  if ( DT_DELIMITED_FILE == v_type )
  {
    delete v.v_delimitedfile;
    v.v_delimitedfile = NULL;
  }  
  else
  if ( DT_EXCEL_EXPORTER == v_type )
  {
    delete v.v_excelwriter;
    v.v_excelwriter = NULL;
  }  
  else
  if ( DT_SQLLITE_3_DB == v_type )
  {
    delete v.v_sqllite3db;
    v.v_sqllite3db = NULL;
  }
  else
  if ( DT_SQLLITE_3_ROWSET == v_type )
  {
    delete v.v_sqllite3rowset;
    v.v_sqllite3rowset = NULL;
  }

  if ( !bTypeLockViolated )
  {
     v_type         = roOther.v_type;

     if ( v_type == DT_STRING )
     {
       if ( gpoOpSys )
       {
         bCopyValue = false;
         vmstring* pchReturn = gpoOpSys->AllocateNewString( roOther.v.v_string->str_size, true );
         strcpy( pchReturn->str_data, roOther.v.v_string->str_data );       
         v.v_string = pchReturn;
       }
     } 
     v_constant     = roOther.v_constant;
     v_tempconst    = roOther.v_tempconst;
     v_monitored    = roOther.v_monitored;
     v_poMonitor    = roOther.v_poMonitor;

     if ( bCopyValue )
     {
       v = roOther.v;
     }
  }
  return( *this );
}
/* End of function "VMVariant::CloneValue"
/*****************************************************************************/


/*****************************************************************************/
/*

     FUNCTION NAME:  VMTrackedAllocs::Erase

       DESCRIPTION:  heap management function. This function will get called for
                     all heap based variants that the user creates and they don't
                     specifically free.

                     This fixup is required because we have cheated the memory
                     manager used in this interpreter. The orginal design expected
                     to have all allocations be directly tracked in the internal
                     dictionary system. That design did not mix well with c++
                     objects, which are heap based in this hybrid system. So, since
                     the internal memory manager does not deal with these heap based
                     variables at all, we track them separately from the main memory
                     manager in an 'allocation tracker'.....
 
                     Admittedly, its a bit of a kludge; but it is a cheap solution 
                     and allows us to not have to dig into the guts of this engine
                     by negating the need to replace the internal memory manager with
                     a much more sophisticated scheme.

             INPUT:  void  
            OUTPUT:  none

           RETURNS:  void  
*/
void VMTrackedAllocs::Erase( void )
{
  if ( DT_STACK == v_type )
  {
    if ( !IsBadWritePtr( v.v_stack, sizeof( *v.v_stack ) ) )
    {
      delete v.v_stack;
    }
    v.v_stack = NULL;
  }
  else
  if ( DT_QUEUE == v_type )
  {
    if ( !IsBadWritePtr( v.v_queue, sizeof( *v.v_queue ) ) )
    {
      delete v.v_queue;
    }
    v.v_queue = NULL;
  }
  else
  if ( DT_HASHTABLE == v_type )
  {
    if ( !IsBadWritePtr( v.v_hashtable, sizeof( *v.v_hashtable ) ) )
    {
      delete v.v_hashtable;
    }
    v.v_hashtable = NULL;
  }
  else
  if ( DT_CALCULATOR == v_type )
  {
    if ( !IsBadWritePtr( v.v_calculator, sizeof( *v.v_calculator ) ) )
    {
      delete v.v_calculator;
    }
    v.v_calculator = NULL;
  }
  else
  if ( DT_TOKENIZER == v_type )
  {
    if ( !IsBadWritePtr( v.v_tokenizer, sizeof( *v.v_tokenizer ) ) )
    {
      delete v.v_tokenizer;
    }
    v.v_tokenizer = NULL;
  }
  else
  if ( DT_BYTEARRAY == v_type )
  {
    if ( !IsBadWritePtr( v.v_bytearray, sizeof( *v.v_bytearray ) ) )
    {
      delete v.v_bytearray;
    }
    v.v_bytearray = NULL;
  }
  else
  if ( DT_USERVECTOR == v_type )
  {
    if ( !IsBadWritePtr( v.v_uservector, sizeof( *v.v_uservector ) ) )
    {
       delete v.v_uservector;
    }
    v.v_uservector = NULL;
  }
  else
  if ( DT_REPORTPAGE == v_type )
  {
    if ( !IsBadWritePtr( v.v_page, sizeof( *v.v_page ) ) )
    {
      delete v.v_page;
    }
    v.v_page = NULL;
  }
  else
  if ( DT_ODBC == v_type )
  {
    if ( !IsBadWritePtr( v.v_odbc, sizeof( *v.v_odbc ) ) )
    {
       delete v.v_odbc;
    }
    v.v_odbc = NULL;
  }
  else
  if ( DT_SQLLITE_2_DB == v_type )
  {
    if ( !IsBadWritePtr( v.v_sqllite2db, sizeof( *v.v_sqllite2db ) ) )
    {
       delete v.v_sqllite2db;
    }
    v.v_sqllite2db = NULL;
  }
  else
  if ( DT_UNZIPPER == v_type )
  {
    if ( !IsBadWritePtr( v.v_unzipper, sizeof( *v.v_unzipper ) ) )
    {
       delete v.v_unzipper;
    }
    v.v_unzipper = NULL;
  }  
  else
  if ( DT_ZIPMAKER == v_type )
  {
    if ( !IsBadWritePtr( v.v_zipmaker, sizeof( *v.v_zipmaker ) ) )
    {
       delete v.v_zipmaker;
    }
    v.v_zipmaker = NULL;
  }
  else  
  if ( DT_SQLLITE_2_ROWSET == v_type )
  {
    if ( !IsBadWritePtr( v.v_sqllite2rowset, sizeof( *v.v_sqllite2rowset ) ) )
    {
       delete v.v_sqllite2rowset;
    }
    v.v_sqllite2rowset = NULL;
  } 
  else  
  if ( DT_FILE_BUILDER == v_type )
  {
    if ( !IsBadWritePtr( v.v_filebuilder, sizeof( *v.v_filebuilder ) ) )
    {
       delete v.v_filebuilder;
    }
    v.v_filebuilder = NULL;
  }  
  else  
  if ( DT_DELIMITED_FILE == v_type )
  {
    if ( !IsBadWritePtr( v.v_delimitedfile, sizeof( *v.v_delimitedfile ) ) )
    {
       delete v.v_delimitedfile;
    }
    v.v_delimitedfile = NULL;
  }  
  else  
  if ( DT_EXCEL_EXPORTER == v_type )
  {
    if ( !IsBadWritePtr( v.v_excelwriter, sizeof( *v.v_excelwriter ) ) )
    {
       delete v.v_excelwriter;
    }
    v.v_excelwriter = NULL;
  }  
  else  
  if ( DT_SQLLITE_3_DB == v_type )
  {
    if ( !IsBadWritePtr( v.v_sqllite3db, sizeof( *v.v_sqllite3db ) ) )
    {
       delete v.v_sqllite3db;
    }
    v.v_sqllite3db = NULL;
  }  
  else  
  if ( DT_SQLLITE_3_ROWSET == v_type )
  {
    if ( !IsBadWritePtr( v.v_sqllite3rowset, sizeof( *v.v_sqllite3rowset ) ) )
    {
       delete v.v_sqllite3rowset;
    }
    v.v_sqllite3rowset = NULL;
  }  

  v_type = 0;
}
/* End of function "VMTrackedAllocs::Erase"
/*****************************************************************************/
#endif


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::InitVirtualMachine

       DESCRIPTION:  initialize the virtual machine

             INPUT:  smax - the size of the virtual machine's stack
                     cmax - the size of the virtual machine's code array
            OUTPUT:  

           RETURNS:  true if successful, false otherwise
*/
int VMVirtualOpSys::InitVirtualMachine( int smax, int cmax )
{
  gpoOpSys = this;

  VMVirtualMachine::InitVirtualMachine( smax, cmax );

  // application context integration functions
  //
  ConfigureBuiltInFunction( "GetAppEnvField",   HandlerGetField         );
  ConfigureBuiltInFunction( "SetAppEnvField",   HandlerSetField         );
  ConfigureBuiltInFunction( "GetProperty",      HandlerGetArgument      );
  ConfigureBuiltInFunction( "SendCommandToApp", HandlerSendCommandToApp );

  // quick escape hatch for scripts
  //
  ConfigureBuiltInFunction( "Throw",           HandlerThrowError       );

  // create data type functions
  //
  ConfigureBuiltInFunction( "Vector",          HandlerNewVector        );
  ConfigureBuiltInFunction( "String",          HandlerNewString        );
  ConfigureBuiltInFunction( "Queue",           HandlerNewQueue         );
  ConfigureBuiltInFunction( "Stack",           HandlerNewStack         );
  ConfigureBuiltInFunction( "Map",             HandlerNewHashTable     );
  ConfigureBuiltInFunction( "Tokenizer",       HandlerNewTokenizer     );
  ConfigureBuiltInFunction( "ByteArray",       HandlerNewByteArray     );
  ConfigureBuiltInFunction( "Long",            HandlerNewLong          );
  ConfigureBuiltInFunction( "Handle",          HandlerNewHandle        );
  ConfigureBuiltInFunction( "DateTime",        HandlerNewDateTime      );
  ConfigureBuiltInFunction( "DWORD",           HandlerNewDWord         );
  ConfigureBuiltInFunction( "Double",          HandlerNewDouble        );
  ConfigureBuiltInFunction( "Byte",            HandlerNewByte          );
  ConfigureBuiltInFunction( "Page",            HandlerNewPage          );
  ConfigureBuiltInFunction( "Table",           HandlerNewTable         );
  ConfigureBuiltInFunction( "Color",           HandlerNewColor         );
  ConfigureBuiltInFunction( "Database",        HandlerNewDBConnection  );
  ConfigureBuiltInFunction( "Calculator",      HandlerNewCalculator    );
  ConfigureBuiltInFunction( "NullValue",       HandlerNewNullValue     );
  ConfigureBuiltInFunction( "SqlLite2Database", HandlerNewSqlLite2Database );
  ConfigureBuiltInFunction( "UnZipper",         HandlerNewUnZipper         );
  ConfigureBuiltInFunction( "ZipMaker",         HandlerNewZipMaker         );
  ConfigureBuiltInFunction( "FileBuilder",      HandlerNewFileBuilder      );
  ConfigureBuiltInFunction( "DelimitedFile",    HandlerNewDelimitedFile    );
  ConfigureBuiltInFunction( "ExcelExporter",    HandlerNewExcelExporter    );
  ConfigureBuiltInFunction( "Int64",            HandlerNewInt64            );
  ConfigureBuiltInFunction( "SqlLite3Database", HandlerNewSqlLite3Database );

  // release heap-based, data-type functions
  //
  ConfigureBuiltInFunction( "FreeObject",      HandlerFreeObject       );

  // general purpose functions
  //
  ConfigureBuiltInFunction( "SizeOf",          HandlerSizeOf           );
  ConfigureBuiltInFunction( "Echo",            HandlerEcho             );
  ConfigureBuiltInFunction( "Sleep",           HandlerSleep            );

  // bit manipulation
  //
  ConfigureBuiltInFunction( "SetBit",          HandlerSetBit           );

  // vector methods
  //
  ConfigureBuiltInFunction( "VectorSetAtIndex",   HandlerVectorSetAtIndex     );
  ConfigureBuiltInFunction( "VectorGetAtIndex",   HandlerVectorGetAtIndex     );
  ConfigureBuiltInFunction( "VectorAddItem",      HandlerVectorAppendItem     );
  ConfigureBuiltInFunction( "VectorDelAtIndex",   HandlerVectorRemoveAtIndex  );
  ConfigureBuiltInFunction( "VectorClear",        HandlerCollectionClear      );

  // byte array methods
  //
  ConfigureBuiltInFunction( "ByteArrayGetAtIndex",    HandlerByteArrayGetAtIndex    );
  ConfigureBuiltInFunction( "ByteArraySetAtIndex",    HandlerByteArraySetAtIndex    );
  ConfigureBuiltInFunction( "ByteArrayAppend",        HandlerByteArrayAppend        );
  ConfigureBuiltInFunction( "ByteArrayInsertAtIndex", HandlerByteArrayInsertAtIndex );
  ConfigureBuiltInFunction( "ByteArrayDelAtIndex",    HandlerByteArrayRemoveAtIndex );
  ConfigureBuiltInFunction( "ByteArrayClear",         HandlerCollectionClear        );

  // stack operations
  //
  ConfigureBuiltInFunction( "StackPush",       HandlerStackPush        );
  ConfigureBuiltInFunction( "StackPop",        HandlerStackPop         );
  ConfigureBuiltInFunction( "StackPeek",       HandlerStackPeek        );
  ConfigureBuiltInFunction( "StackClear",      HandlerCollectionClear  );

  // queue operations
  //
  ConfigureBuiltInFunction( "EnQueue",         HandlerEnQueue          );
  ConfigureBuiltInFunction( "DeQueue",         HandlerDeQueue          );
  ConfigureBuiltInFunction( "QueueClear",      HandlerCollectionClear  );

  // map operations
  //
  ConfigureBuiltInFunction( "MapAddKey",       HandlerHashTablePut     );
  ConfigureBuiltInFunction( "MapRemoveKey",    HandlerHashTableRemove  );
  ConfigureBuiltInFunction( "MapFindByKey",    HandlerHashTableFind    );
  ConfigureBuiltInFunction( "MapHasKey",       HandlerHashTableHasKey  );
  ConfigureBuiltInFunction( "MapClear",        HandlerCollectionClear  );

  // extension dlls management
  //
  ConfigureBuiltInFunction( "RunExtension",    HandlerRunExtension     );

  // variable locking -- thread safe access
  //
  ConfigureBuiltInFunction( "ConstCast",        HandlerConstCast       );
  ConfigureBuiltInFunction( "Synchronize",      HandlerSynchronous     );
  ConfigureBuiltInFunction( "AcquireReadLock",  HandlerGetReadLock     );
  ConfigureBuiltInFunction( "ReleaseReadLock",  HandlerFreeReadLock    );
  ConfigureBuiltInFunction( "AcquireWriteLock", HandlerGetWriteLock    );
  ConfigureBuiltInFunction( "ReleaseWriteLock", HandlerFreeWriteLock   );

  // rtti operations
  //
  ConfigureBuiltInFunction( "IsNull",             HandlerIsNull             );
  ConfigureBuiltInFunction( "IsClass",            HandlerIsClass            );
  ConfigureBuiltInFunction( "IsVector",           HandlerIsVector           );
  ConfigureBuiltInFunction( "IsNumber",           HandlerIsNumber           );
  ConfigureBuiltInFunction( "IsString",           HandlerIsString           );
  ConfigureBuiltInFunction( "IsFile",             HandlerIsFile             );
  ConfigureBuiltInFunction( "IsKernelObject",     HandlerIsKernelObject     );
  ConfigureBuiltInFunction( "IsHandle",           HandlerIsHandle           );
  ConfigureBuiltInFunction( "IsDateTime",         HandlerIsDateTime         );
  ConfigureBuiltInFunction( "IsDWord",            HandlerIsDWord            );
  ConfigureBuiltInFunction( "IsNTHandle",         HandlerIsNTHandle         );
  ConfigureBuiltInFunction( "IsFindHandle",       HandlerIsFindHandle       );
  ConfigureBuiltInFunction( "IsQueue",            HandlerIsQueue            );
  ConfigureBuiltInFunction( "IsStack",            HandlerIsStack            );
  ConfigureBuiltInFunction( "IsHashTable",        HandlerIsHashTable        );
  ConfigureBuiltInFunction( "IsConstant",         HandlerIsConstant         );
  ConfigureBuiltInFunction( "IsConstCast",        HandlerIsConstCast        );
  ConfigureBuiltInFunction( "IsDouble",           HandlerIsDouble           );
  ConfigureBuiltInFunction( "IsByte",             HandlerIsByte             );
  ConfigureBuiltInFunction( "IsByteArray",        HandlerIsByteArray        );
  ConfigureBuiltInFunction( "IsReportPage",       HandlerIsReportPage       );
  ConfigureBuiltInFunction( "IsPageRegion",       HandlerIsPageRegion       );
  ConfigureBuiltInFunction( "IsPageTable",        HandlerIsPageTable        );
  ConfigureBuiltInFunction( "IsColor",            HandlerIsColor            );
  ConfigureBuiltInFunction( "IsDatabase",         HandlerIsDBConnection     );
  ConfigureBuiltInFunction( "IsRegExp",           HandlerIsRegExpression    );
  ConfigureBuiltInFunction( "IsSqlLite2Database", HandlerIsSqlLite2Database );
  ConfigureBuiltInFunction( "IsHtmlParser",       HandlerIsHtmlParser       );
  ConfigureBuiltInFunction( "IsUnZipper",         HandlerIsUnZipper         );
  ConfigureBuiltInFunction( "IsZipMaker",         HandlerIsZipMaker         );
  ConfigureBuiltInFunction( "IsHttpClient",       HandlerIsHttpClient       );
  ConfigureBuiltInFunction( "IsFtpClient",        HandlerIsFtpClient        );
  ConfigureBuiltInFunction( "IsSqlLite2RowSet",   HandlerIsSqlLite2Rowset   );
  ConfigureBuiltInFunction( "IsFileBuilder",      HandlerIsFileBuilder      );
  ConfigureBuiltInFunction( "IsDelimitedFile",    HandlerIsDelimitedFile    );
  ConfigureBuiltInFunction( "IsExcelExporter",    HandlerIsExcelExporter    );
  ConfigureBuiltInFunction( "IsThreadPool",       HandlerIsThreadPool       );
  ConfigureBuiltInFunction( "IsThread",           HandlerIsThread           );
  ConfigureBuiltInFunction( "IsSqlLite3Database", HandlerIsSqlLite3Database );
  ConfigureBuiltInFunction( "IsSqlLite3RowSet",   HandlerIsSqlLite3Rowset   );
  ConfigureBuiltInFunction( "IsInt64",            HandlerIsInt64            );

  // tokenizer functions
  //
  ConfigureBuiltInFunction( "HasMoreTokens",   HandlerHasMoreTokens    );
  ConfigureBuiltInFunction( "GetNextToken",    HandlerGetNextToken     );

  // Numerical functions
  //
  ConfigureBuiltInFunction( "Max",             HandlerMax              );
  ConfigureBuiltInFunction( "Min",             HandlerMin              );
  ConfigureBuiltInFunction( "Average",         HandlerAverage          );
  ConfigureBuiltInFunction( "RandomInt",       HandlerRandomInt        );

  // date-time related functions
  //
  ConfigureBuiltInFunction( "GetDate",         HandlerGetDate          );  
  ConfigureBuiltInFunction( "DateAdd",         HandlerDateAdd          );  
  ConfigureBuiltInFunction( "DateSub",         HandlerDateSub          );  
  ConfigureBuiltInFunction( "DatePart",        HandlerDatePart         );  
  ConfigureBuiltInFunction( "DateSetHourPart", HandlerDateSetHourPart  );  
  ConfigureBuiltInFunction( "DateSetMinsPart", HandlerDateSetMinsPart  );  
  ConfigureBuiltInFunction( "DateSetSecsPart", HandlerDateSetSecsPart  );  
  ConfigureBuiltInFunction( "DateSetHMS",      HandlerDateSetHMS       );  
  ConfigureBuiltInFunction( "DateToString",    HandlerDateToString     );  
  ConfigureBuiltInFunction( "StringToDate",    HandlerStringToDate     );  
  ConfigureBuiltInFunction( "DateCompare",     HandlerDateCompare      );  
  ConfigureBuiltInFunction( "DateDiff",        HandlerDateDiff         );  

  // kernel primitives related functions
  //
  ConfigureBuiltInFunction( "CreateSemaphore",  HandlerCreateSemaphore  );
  ConfigureBuiltInFunction( "OpenSemaphore",    HandlerOpenSemaphore    );
  ConfigureBuiltInFunction( "CloseSemaphore",   HandlerCloseSemaphore   );
  ConfigureBuiltInFunction( "DestroySemaphore", HandlerCloseHandle      );

  ConfigureBuiltInFunction( "CreateMutex",      HandlerCreateMutex      );
  ConfigureBuiltInFunction( "OpenMutex",        HandlerOpenMutex        );
  ConfigureBuiltInFunction( "AcquireMutex",     HandlerAcquireMutex     );
  ConfigureBuiltInFunction( "ReleaseMutex",     HandlerReleaseMutex     );
  ConfigureBuiltInFunction( "DestroyMutex",     HandlerCloseHandle      );

  ConfigureBuiltInFunction( "CreateEvent",      HandlerCreateEvent      );
  ConfigureBuiltInFunction( "OpenEvent",        HandlerOpenEvent        );
  ConfigureBuiltInFunction( "PulseEvent",       HandlerPulseEvent       );
  ConfigureBuiltInFunction( "SetEvent",         HandlerSetEvent         );
  ConfigureBuiltInFunction( "ResetEvent",       HandlerResetEvent       );
  ConfigureBuiltInFunction( "DestroyEvent",     HandlerCloseHandle      );

  ConfigureBuiltInFunction( "WaitForSingleObject",    HandlerWaitForSingleObject    );
  ConfigureBuiltInFunction( "WaitForMultipleObjects", HandlerWaitForMultipleObjects );

  // string conversion functions
  //
  // mjs: need ByteToString,StringToByte,
  //           DWORDToString,StringToDWORD
  //           StringToDate
  //
  ConfigureBuiltInFunction( "IntToString",          HandlerIntToString          );  
  ConfigureBuiltInFunction( "StringToInt",          HandlerStringToInt          );  
  ConfigureBuiltInFunction( "DoubleToString",       HandlerDoubleToString       );  
  ConfigureBuiltInFunction( "StringToDouble",       HandlerStringToDouble       );  

  // string functions
  //
  ConfigureBuiltInFunction( "StringCompare",          HandlerStringCompare        );  
  ConfigureBuiltInFunction( "FillString",             HandlerFillString           );  
  ConfigureBuiltInFunction( "IndexOf",                HandlerIndexOf              );  
  ConfigureBuiltInFunction( "TrimString",             HandlerTrimString           );  
  ConfigureBuiltInFunction( "StringLength",           HandlerStringLength         );  
  ConfigureBuiltInFunction( "ToLower",                HandlerToLower              );  
  ConfigureBuiltInFunction( "ToUpper",                HandlerToUpper              );  
  ConfigureBuiltInFunction( "SubString",              HandlerSubString            );  
  ConfigureBuiltInFunction( "StringGetAt",            HandlerStringGetAt          );  
  ConfigureBuiltInFunction( "StringConcat",           HandlerStringConcat         );  
  ConfigureBuiltInFunction( "StringReplace",          HandlerStringReplace        );  
  ConfigureBuiltInFunction( "StringFormat",           HandlerStringFormat         );  
  ConfigureBuiltInFunction( "StringBoundedBy",        HandlerStringBoundedBy      );  
  ConfigureBuiltInFunction( "BoundedStringReplace",   HandlerBoundedStringReplace );  
  ConfigureBuiltInFunction( "TrimQuotes",             HandlerTrimQuotes           );  
  ConfigureBuiltInFunction( "StringCopy",             HandlerCopyString           );  
  ConfigureBuiltInFunction( "PutQuote",               HandlerPutQuote             );  
  ConfigureBuiltInFunction( "PadLeft",                HandlerPadLeft              );  
  ConfigureBuiltInFunction( "PadRight",               HandlerPadRight             );  
  ConfigureBuiltInFunction( "IsStringNumeric",        HandlerIsStringNumeric      );  
  ConfigureBuiltInFunction( "StringSwapOutSubString",      HandlerReplaceSubString     );  
  ConfigureBuiltInFunction( "StringFindFirstDigitIndex",   HandlerStringFindFirstDigitIndex  );  

  // process start functions
  //
  ConfigureBuiltInFunction( "ProcStartNoWait",       HandlerStartProcessNoWait    );
  ConfigureBuiltInFunction( "ProcStartErrorCheck",   HandlerStartCheckedProcess   );
  ConfigureBuiltInFunction( "StartLoggedProcess",    HandlerStartLoggedProcess    );
  ConfigureBuiltInFunction( "StartProcessGetHandle", HandlerStartProcessGetHandle );
  ConfigureBuiltInFunction( "ReleaseHandle",         HandlerCloseHandle           );

  // network drive related functions
  //
  ConfigureBuiltInFunction( "ConnectNetDrive",      HandlerLogOnNetDrive        );
  ConfigureBuiltInFunction( "LogOffNetDrive",       HandlerLogOffNetDrive       );
  ConfigureBuiltInFunction( "EnumerateServers",     HandlerEnumerateServers     );

  // directory related functions
  //
  ConfigureBuiltInFunction( "SetDirectory",         HandlerSetDirectory         );
  ConfigureBuiltInFunction( "GetDirectory",         HandlerGetDirectory         );
  ConfigureBuiltInFunction( "PathExists",           HandlerPathExists           );
  ConfigureBuiltInFunction( "CompareDirs",          HandlerCompareDirs          );
  ConfigureBuiltInFunction( "CreateDirectory",      HandlerCreateDirectory      );
  ConfigureBuiltInFunction( "MoveTree",             HandlerMoveTree             );
  ConfigureBuiltInFunction( "RemoveDirectory",      HandlerRemoveDirectory      );
  ConfigureBuiltInFunction( "RemoveTree",           HandlerRemoveTree           );
  ConfigureBuiltInFunction( "RenameDirectory",      HandlerRenameFile           );
  ConfigureBuiltInFunction( "CopyTree",             HandlerCopyTree             );
  ConfigureBuiltInFunction( "CopyFile",             HandlerCopyFile             );

  // find first/next related functions
  //
  ConfigureBuiltInFunction( "FindOpen",             HandlerFindOpen      );
  ConfigureBuiltInFunction( "FindClose",            HandlerFindClose     );
  ConfigureBuiltInFunction( "FindFirstDir",         HandlerFindFirstDir  );
  ConfigureBuiltInFunction( "FindNextDir",          HandlerFindNextDir   );
  ConfigureBuiltInFunction( "FindFirstFile",        HandlerFindFirstFile );
  ConfigureBuiltInFunction( "FindNextFile",         HandlerFindNextFile  );

  // scripted output functions
  //
  ConfigureBuiltInFunction( "PageSetLandscapeMode",     HandlerPageSetLandscapeMode     );
  ConfigureBuiltInFunction( "PageSetPortraitMode",      HandlerPageSetPortraitMode      );
  ConfigureBuiltInFunction( "PageSetFont",              HandlerPageSetFont              );
  ConfigureBuiltInFunction( "PageSetFontSize",          HandlerPageSetFontSize          );
  ConfigureBuiltInFunction( "PageSetRightMargin",       HandlerPageSetRightMargin       );
  ConfigureBuiltInFunction( "PageSetBottomMargin",      HandlerPageSetBottomMargin      );
  ConfigureBuiltInFunction( "PagePrintTextColumn",      HandlerPagePrintTextColumn      );
  ConfigureBuiltInFunction( "PageSetColor",             HandlerPageSetColor             );
  ConfigureBuiltInFunction( "PageSetBackColor",         HandlerPageSetBackColor         );
  ConfigureBuiltInFunction( "PagePrintBitMap",          HandlerPagePrintBitMap          );
  ConfigureBuiltInFunction( "PageGetNextLogicalColumn", HandlerPageGetNextLogicalColumn );
  ConfigureBuiltInFunction( "PageDrawBox",              HandlerPageDrawBox              );
  ConfigureBuiltInFunction( "PageDrawCheckBox",         HandlerPageDrawCheckBox         );
  ConfigureBuiltInFunction( "PagePrintRotatedText",     HandlerPagePrintRotatedText     );
  ConfigureBuiltInFunction( "PageCreateRegion",         HandlerPageCreateRegion         );     
  ConfigureBuiltInFunction( "PageCreateSubRegion",      HandlerPageCreateSubRegion      );
  ConfigureBuiltInFunction( "PagePrintText",            HandlerPagePrintText            );
  ConfigureBuiltInFunction( "RegionDrawBorder",         HandlerRegionDrawBorder         );
  ConfigureBuiltInFunction( "RegionDrawTitle",          HandlerRegionDrawTitle          );
  ConfigureBuiltInFunction( "RegionDrawCheckBox",       HandlerRegionDrawCheckBox       );
  ConfigureBuiltInFunction( "PageSetLineSpacing",       HandlerPageSetLineSpacing       );
  ConfigureBuiltInFunction( "PagePrintToRegion",        HandlerPagePrintToRegion        );
  ConfigureBuiltInFunction( "PageDrawLine",             HandlerPageDrawLine             );
  ConfigureBuiltInFunction( "PageDrawLineInRegion",     HandlerPageDrawLineInRegion     );
  ConfigureBuiltInFunction( "TableSetPointSize",        HandlerTableSetPointSize        );
  ConfigureBuiltInFunction( "TableSetLineSize",         HandlerTableSetLineSize         );
  ConfigureBuiltInFunction( "TableSetUsesInches",       HandlerTableSetUsesInches       );
  ConfigureBuiltInFunction( "TableSetAutoSize",         HandlerTableSetAutoSize         );
  ConfigureBuiltInFunction( "TableSetHasBorder",        HandlerTableSetHasBorder        );
  ConfigureBuiltInFunction( "TableSetFillFlag",         HandlerTableSetFillFlag         );
  ConfigureBuiltInFunction( "TableSetColumnCount",      HandlerTableSetColumnCount      );
  ConfigureBuiltInFunction( "TableSetRowCount",         HandlerTableSetRowCount         );
  ConfigureBuiltInFunction( "TableSetOrigin",           HandlerTableSetOrigin           );
  ConfigureBuiltInFunction( "TableSetRightMargin",      HandlerTableSetRightMargin      );
  ConfigureBuiltInFunction( "TableAddColumn",           HandlerTableAddColumn           );
  ConfigureBuiltInFunction( "PageAddTable",             HandlerPageAddTable             );
  ConfigureBuiltInFunction( "TableGetBottom",           HandlerTableGetBottom           );
  ConfigureBuiltInFunction( "TablePrintIntoCell",       HandlerTablePrintIntoCell       );

  // Win32 Environment Variable functions
  //
  ConfigureBuiltInFunction( "GetEnvironmentVar",    HandlerGetEnvironmentVar    );
  ConfigureBuiltInFunction( "SetEnvironmentVar",    HandlerSetEnvironmentVar    );
  ConfigureBuiltInFunction( "DelEnvironmentVar",    HandlerDelEnvironmentVar    );
  ConfigureBuiltInFunction( "AppendEnvironmentVar", HandlerAddToEnvironmentVar  );

  // Win32 misc file functions
  //
  ConfigureBuiltInFunction( "SysGetTempDir",           HandlerGetTempDir             );
  ConfigureBuiltInFunction( "SysGetSystemDir",         HandlerGetSystemDir           );
  ConfigureBuiltInFunction( "SysGetTempFileName",      HandlerGetTempFileName        );
  ConfigureBuiltInFunction( "SplitPathForFileName",    HandlerSplitPathForFileName   );
  ConfigureBuiltInFunction( "SplitPathForPathPart",    HandlerSplitPathForPathPart   );
  ConfigureBuiltInFunction( "SplitPathForExtPart",     HandlerSplitPathForExtPart    );
  ConfigureBuiltInFunction( "SplitPathForDriveName",   HandlerSplitPathForDriveName  );
  ConfigureBuiltInFunction( "GetAsShortPath",          HandlerGetShortPath  );
  ConfigureBuiltInFunction( "GetAsLongPath",           HandlerGetLongPath   );

  // Win32 misc functions
  //
  ConfigureBuiltInFunction( "MessageBox",              HandlerMessageBox         );
  ConfigureBuiltInFunction( "TimeoutMessageBox",       HandlerTimeOutMessageBox  );
  ConfigureBuiltInFunction( "GetHostName",             HandlerGetHostName        );

  // Database Access functions
  //
  ConfigureBuiltInFunction( "DBOpen",               HandlerDBOpen               );
  ConfigureBuiltInFunction( "DBClose",              HandlerDBClose              );
  ConfigureBuiltInFunction( "DBIsOpen",             HandlerDBIsOpen             );
  ConfigureBuiltInFunction( "DBCanTransact",        HandlerDBCanTransact        );
  ConfigureBuiltInFunction( "DBSetLogonTimeOut",    HandlerDBSetLogonTimeOut    );
  ConfigureBuiltInFunction( "DBSetQueryTimeOut",    HandlerDBSetQueryTimeOut    );
  ConfigureBuiltInFunction( "DBBeginTran",          HandlerDBBeginTran          );
  ConfigureBuiltInFunction( "DBCommitTran",         HandlerDBCommitTran         );
  ConfigureBuiltInFunction( "DBRollbackTran",       HandlerDBRollbackTran       );
  ConfigureBuiltInFunction( "DBExecQuery",          HandlerDBExecQuery          );
  ConfigureBuiltInFunction( "DBIsEmptySet",         HandlerDBIsEmptySet         );
  ConfigureBuiltInFunction( "DBIsEOF",              HandlerDBIsEOF              );
  ConfigureBuiltInFunction( "DBIsBOF",              HandlerDBIsBOF              );
  ConfigureBuiltInFunction( "DBMoveNext",           HandlerDBMoveNext           );
  ConfigureBuiltInFunction( "DBMovePrev",           HandlerDBMovePrev           );
  ConfigureBuiltInFunction( "DBMoveToStart",        HandlerDBMoveToStart        );
  ConfigureBuiltInFunction( "DBMoveToEnd",          HandlerDBMoveToEnd          );
  ConfigureBuiltInFunction( "DBMoveAheadBy",        HandlerDBMoveAheadBy        );
  ConfigureBuiltInFunction( "DBMoveBackBy",         HandlerDBMoveBackBy         );
  ConfigureBuiltInFunction( "DBMoveFromStartBy",    HandlerDBMoveFromStartBy    );
  ConfigureBuiltInFunction( "DBMoveFromEndBy",      HandlerDBMoveFromEndBy      );
  ConfigureBuiltInFunction( "DBGetFieldByIndex",    HandlerDBGetFieldByIndex    );
  ConfigureBuiltInFunction( "DBGetFieldByName",     HandlerDBGetFieldByName     );
  ConfigureBuiltInFunction( "DBGetColumnCount",     HandlerDBGetColumnCount     );
  ConfigureBuiltInFunction( "DBFetchRow",           HandlerDBFetchRow           );
  ConfigureBuiltInFunction( "DBGetDatabaseName",    HandlerDBGetDatabaseName    );
  ConfigureBuiltInFunction( "DBGetServerName",      HandlerDBGetServerName      );
  ConfigureBuiltInFunction( "SysCreateOdbcDsn",     HandlerCreateOdbcDsn        );

  // ini-file related functions
  //
  ConfigureBuiltInFunction( "IniFileReadInt",     HandlerIniFileReadInt     );
  ConfigureBuiltInFunction( "IniFileWriteInt",    HandlerIniFileWriteInt    );
  ConfigureBuiltInFunction( "IniFileReadDouble",  HandlerIniFileReadDouble  );
  ConfigureBuiltInFunction( "IniFileWriteDouble", HandlerIniFileWriteDouble );
  ConfigureBuiltInFunction( "IniFileReadBool",    HandlerIniFileReadBool    );
  ConfigureBuiltInFunction( "IniFileWriteBool",   HandlerIniFileWriteBool   );
  ConfigureBuiltInFunction( "IniFileReadString",  HandlerIniFileReadString  );
  ConfigureBuiltInFunction( "IniFileWriteString", HandlerIniFileWriteString );
  ConfigureBuiltInFunction( "IniFileDeleteEntry", HandlerIniFileDeleteEntry );
  ConfigureBuiltInFunction( "IniGetSection",      HandlerIniGetSection      );

  // calculator related functions
  //
  ConfigureBuiltInFunction( "CalcAddVariable",      HandlerAddVariable         );
  ConfigureBuiltInFunction( "CalcAddExpression",    HandlerAddSubExpression    );
  ConfigureBuiltInFunction( "CalcSetEquation",      HandlerSetEquation         );
  ConfigureBuiltInFunction( "CalcSolve",            HandlerSolve               );

  // process probe (asks: is 'process x' running)
  //
  ConfigureBuiltInFunction( "IsProcessRunning",     HandlerIsProcessRunning     );

  // xml form data integration functions
  //
#ifndef NOT_USING_XML_FORMS
  ConfigureBuiltInFunction( "CreateForm",                HandlerCreateForm                );
  ConfigureBuiltInFunction( "RunForm",                   HandlerRunForm                   );
  ConfigureBuiltInFunction( "DestroyForm",               HandlerDestroyForm               );
  ConfigureBuiltInFunction( "FormGetCtrlValueAsString",  HandlerFormGetCtrlValueAsString  );
  ConfigureBuiltInFunction( "FormSetCtrlValueAsString",  HandlerFormSetCtrlValueAsString  );
  ConfigureBuiltInFunction( "FormGetCtrlValueAsInteger", HandlerFormGetCtrlValueAsInteger );
  ConfigureBuiltInFunction( "FormSetCtrlValueAsInteger", HandlerFormSetCtrlValueAsInteger );
  ConfigureBuiltInFunction( "FormGetCtrlValueAsDouble",  HandlerFormGetCtrlValueAsDouble  );
  ConfigureBuiltInFunction( "FormSetCtrlValueAsDouble",  HandlerFormSetCtrlValueAsDouble  );
  ConfigureBuiltInFunction( "FormCtrlValidateFail",      HandlerFormCtrlValidateFail      );
  ConfigureBuiltInFunction( "FormClearAllFields",        HandlerFormClearAllFields        );
  ConfigureBuiltInFunction( "FormClearFieldByName",      HandlerFormClearFieldByName      );
  ConfigureBuiltInFunction( "FormShowHideFormGroup",     HandlerShowHideFormGroup         );
  ConfigureBuiltInFunction( "FormEnableDisableFormGroup",   HandlerEnableDisableFormGroup   );
  ConfigureBuiltInFunction( "FormShowHideSubForm",          HandlerShowHideSubForm          );
  ConfigureBuiltInFunction( "FormShowHideControl",          HandlerShowHideControl          );
  ConfigureBuiltInFunction( "FormEnableDisableControl",     HandlerEnableDisableControl     );
  ConfigureBuiltInFunction( "FormIsFormGroupVisible",       HandlerIsFormGroupVisible       );
  ConfigureBuiltInFunction( "FormIsFormGroupEnabled",       HandlerIsFormGroupEnabled       );
  ConfigureBuiltInFunction( "FormIsSubFormVisible",         HandlerIsSubFormVisible         );
  ConfigureBuiltInFunction( "FormIsControlVisible",         HandlerIsControlVisible         );
  ConfigureBuiltInFunction( "FormIsControlEnabled",         HandlerIsControlEnabled         );
  ConfigureBuiltInFunction( "FormSetFocusToControl",        HandlerSetFocusToControl        );
  ConfigureBuiltInFunction( "FormIsFormButtonChecked",      HandlerIsFormButtonChecked      );
  ConfigureBuiltInFunction( "FormAddStringToComboBox",      HandlerAddStringToComboBox      );
  ConfigureBuiltInFunction( "FormRemoveStringFromComboBox", HandlerRemoveStringFromComboBox );
  ConfigureBuiltInFunction( "FormAddStringToListBox",       HandlerAddStringToListBox       );
  ConfigureBuiltInFunction( "FormRemoveStringFromListBox",  HandlerRemoveStringFromListBox  );
  ConfigureBuiltInFunction( "FormAddRecordToList",              HandlerAddRecordToList                );
  ConfigureBuiltInFunction( "FormRemoveRecordFromListByIndex",  HandlerRemoveRecordFromListByIndex    );
  ConfigureBuiltInFunction( "FormRemoveAllStringsFromComboBox", HandlerRemoveAllStringsFromComboBox   );
  ConfigureBuiltInFunction( "FormRemoveAllStringsFromListBox",  HandlerRemoveAllStringsFromListBox    );
  ConfigureBuiltInFunction( "FormCheckButton",                  HandlerFormCheckButton                );
  ConfigureBuiltInFunction( "FormSetListBoxStrings",            HandlerSetListBoxStrings              );
  ConfigureBuiltInFunction( "FormSetComboBoxStrings",           HandlerSetComboBoxStrings             );
  ConfigureBuiltInFunction( "FormSetFocus",                     HandlerFormSetFocus                   );
  ConfigureBuiltInFunction( "FormSetComboBoxCurSel",            HandlerSetComboBoxCurSel              );
  ConfigureBuiltInFunction( "FormSetListBoxCurSel",             HandlerSetListBoxCurSel               );
  ConfigureBuiltInFunction( "FormSetTabControlCurSel",          HandlerSetTabControlCurSel            );
#endif

  // template processor integration functions
  //
  ConfigureBuiltInFunction( "TemplateStringFormat",        HandlerTemplateStringFormat        );
  ConfigureBuiltInFunction( "TemplateSectionOutputDirect", HandlerTemplateSectionOutputDirect );
  ConfigureBuiltInFunction( "RunTemplateFile",             HandlerRunTemplateFile             );

  // file related functions
  //
  ConfigureBuiltInFunction( "FileExists",          HandlerFileExists       );
  ConfigureBuiltInFunction( "OpenCreateFile",      HandlerOpenFile         );
  ConfigureBuiltInFunction( "CloseFile",           HandlerCloseHandle      );
  ConfigureBuiltInFunction( "MeasureFile",         HandlerMeasureFile      );
  ConfigureBuiltInFunction( "CountLinesInFile",    HandlerCountLinesInFile );
  ConfigureBuiltInFunction( "WriteToFile",         HandlerWriteToFile      );
  ConfigureBuiltInFunction( "ReadFromFile",        HandlerReadFromFile     );
  ConfigureBuiltInFunction( "ReadLineFromFile",    HandlerReadLineFromFile );
  ConfigureBuiltInFunction( "LoadTextFile",        HandlerLoadTextFile     );
  ConfigureBuiltInFunction( "WriteLineToFile",     HandlerWriteLineToFile  );
  ConfigureBuiltInFunction( "SetFilePointer",      HandlerSetFilePointer   );
  ConfigureBuiltInFunction( "GetFileAttribute",    HandlerGetFileAttribute );
  ConfigureBuiltInFunction( "GetFileAttributes",   HandlerGetFileAttribute );
  ConfigureBuiltInFunction( "SetFileAttribute",    HandlerSetFileAttribute );
  ConfigureBuiltInFunction( "DeleteFile",          HandlerDeleteFile       );
  ConfigureBuiltInFunction( "MoveFile",            HandlerMoveFile         );
  ConfigureBuiltInFunction( "RenameFile",          HandlerRenameFile       );
  ConfigureBuiltInFunction( "CompareFiles",        HandlerCompareFiles     );
  ConfigureBuiltInFunction( "GetFileSize",         HandlerGetFileSize      );
  ConfigureBuiltInFunction( "GetFileTime",         HandlerGetFileTime      );
  ConfigureBuiltInFunction( "FileTimeToString",    HandlerDateToString     );
  ConfigureBuiltInFunction( "SetFileTime",         HandlerSetFileTime      );
  ConfigureBuiltInFunction( "WriteTextToFile",     HandlerWriteTextToFile  );

  // registry read/write functions
  //
  ConfigureBuiltInFunction( "RegWriteString", HandlerRegistryStringWrite );
  ConfigureBuiltInFunction( "RegReadString",  HandlerRegistryStringRead  );
  ConfigureBuiltInFunction( "RegWriteInt",    HandlerRegistryIntWrite    );
  ConfigureBuiltInFunction( "RegReadInt",     HandlerRegistryIntRead     );
  ConfigureBuiltInFunction( "RegVerifyPath",  HandlerRegistryVerifyPath  );
  ConfigureBuiltInFunction( "RegCreatePath",  HandlerRegistryCreatePath  );

  // zip file related functions
  //
  ConfigureBuiltInFunction( "ZipFileLoad",             HandlerOpenZipFile            );
  ConfigureBuiltInFunction( "ZipFileClose",            HandlerZipFileClose           );
  ConfigureBuiltInFunction( "UnZipExtractAll",         HandlerExtractAllFromZipFile  );
  ConfigureBuiltInFunction( "UnZipExtractFile",        HandlerExtractOneFromZipFile  );
  ConfigureBuiltInFunction( "UnZipDoesContain",        HandlerDoesZipContainFile     );
  ConfigureBuiltInFunction( "UnZipGetFileCount",       HandlerGetZipFileFileCount    );
  ConfigureBuiltInFunction( "UnZipGetFileToString",    HandlerUnzipFileToString      );
  ConfigureBuiltInFunction( "UnZipGetFileToByteArray", HandlerUnzipFileToByteArray   );
  ConfigureBuiltInFunction( "UnZipGetFileList",        HandlerGetFileListFromZipFile );
  ConfigureBuiltInFunction( "ZipMakerAddFile",         HandlerAddFileToZip           );
  ConfigureBuiltInFunction( "ZipMakerAddFolder",       HandlerAddFolderToZip         );
  ConfigureBuiltInFunction( "PutFileInZipAtPath",      HandlerPutFileInZipAtPath     );

  // sql lite related functions
  //
  ConfigureBuiltInFunction( "SqlLite2Open",                  HandlerSqlLite2Open            );
  ConfigureBuiltInFunction( "SqlLite2Close",                 HandlerSqlLite2Close           );
  ConfigureBuiltInFunction( "SqlLite2IsGood",                HandlerSqlLite2IsGood          );
  ConfigureBuiltInFunction( "SqlLite2ExecStatement",         HandlerSqlLite2ExecStatement   );
  ConfigureBuiltInFunction( "SqlLite2ExecQuery",             HandlerSqlLite2ExecQuery       );
  ConfigureBuiltInFunction( "SqlLite2RowSetIsEmptySet",      HandlerSqlLite2IsEmptySet      );
  ConfigureBuiltInFunction( "SqlLite2RowSetIsEOF",           HandlerSqlLite2IsEOF           );
  ConfigureBuiltInFunction( "SqlLite2RowSetIsBOF",           HandlerSqlLite2IsBOF           );
  ConfigureBuiltInFunction( "SqlLite2RowSetMoveNext",        HandlerSqlLite2MoveNext        );
  ConfigureBuiltInFunction( "SqlLite2RowSetMovePrev",        HandlerSqlLite2MovePrev        );
  ConfigureBuiltInFunction( "SqlLite2RowSetGetFieldByIndex", HandlerSqlLite2GetFieldByIndex );
  ConfigureBuiltInFunction( "SqlLite2RowSetGetFieldByName",  HandlerSqlLite2GetFieldByName  );
  ConfigureBuiltInFunction( "SqlLite2RowSetGetColumnCount",  HandlerSqlLite2GetColumnCount  );
  ConfigureBuiltInFunction( "SqlLite2RowSetGetRowCount",     HandlerSqlLite2GetRowCount     );
  ConfigureBuiltInFunction( "SqlLite2GetLastError",          HandlerSqlLite2GetLastError    );

  ConfigureBuiltInFunction( "SqlLite3Open",                  HandlerSqlLite3Open            );
  ConfigureBuiltInFunction( "SqlLite3Close",                 HandlerSqlLite3Close           );
  ConfigureBuiltInFunction( "SqlLite3ExecStatement",         HandlerSqlLite3ExecStatement   );
  ConfigureBuiltInFunction( "SqlLite3ExecQuery",             HandlerSqlLite3ExecQuery       );
  ConfigureBuiltInFunction( "SqlLite3RowSetIsEmptySet",      HandlerSqlLite3IsEmptySet      );
  ConfigureBuiltInFunction( "SqlLite3RowSetIsEOF",           HandlerSqlLite3IsEOF           );
  ConfigureBuiltInFunction( "SqlLite3RowSetIsBOF",           HandlerSqlLite3IsBOF           );
  ConfigureBuiltInFunction( "SqlLite3RowSetMoveNext",        HandlerSqlLite3MoveNext        );
  ConfigureBuiltInFunction( "SqlLite3RowSetMovePrev",        HandlerSqlLite3MovePrev        );
  ConfigureBuiltInFunction( "SqlLite3RowSetGetFieldByIndex", HandlerSqlLite3GetFieldByIndex );
  ConfigureBuiltInFunction( "SqlLite3RowSetGetFieldByName",  HandlerSqlLite3GetFieldByName  );
  ConfigureBuiltInFunction( "SqlLite3RowSetGetColumnCount",  HandlerSqlLite3GetColumnCount  );
  ConfigureBuiltInFunction( "SqlLite3RowSetGetRowCount",     HandlerSqlLite3GetRowCount     );
  ConfigureBuiltInFunction( "SqlLite3TableCopy",             HandlerSqlLite3TableCopy      );
  ConfigureBuiltInFunction( "SqlLite3QueryCopy",             HandlerSqlLite3QueryCopy      );

  // file builder related functions
  //
  ConfigureBuiltInFunction( "FileBuilderGetCount",   HandlerFileBuilderGetCount   );
  ConfigureBuiltInFunction( "FileBuilderAddTail",    HandlerFileBuilderAddTail    );
  ConfigureBuiltInFunction( "FileBuilderSetAtIndex", HandlerFileBuilderSetAtIndex );
  ConfigureBuiltInFunction( "FileBuilderDelAtIndex", HandlerFileBuilderDelAtIndex );
  ConfigureBuiltInFunction( "FileBuilderGetAtIndex", HandlerFileBuilderGetAtIndex );
  ConfigureBuiltInFunction( "FileBuilderRemoveAll",  HandlerFileBuilderRemoveAll  );
  ConfigureBuiltInFunction( "FileBuilderSendToFile", HandlerFileBuilderSendToFile );

  // delimited file related functions
  //
  ConfigureBuiltInFunction( "DelimFileSetValueAt",        HandlerDelimFileSetValueAt       );
  ConfigureBuiltInFunction( "DelimFileClearData",         HandlerDelimFileClearData        );
  ConfigureBuiltInFunction( "DelimFileCreateColumn",      HandlerDelimFileCreateVariable   );
  ConfigureBuiltInFunction( "DelimFileDeleteColumn",      HandlerDelimFileDeleteVariable   );
  ConfigureBuiltInFunction( "DelimFileGetValueAt",        HandlerDelimFileGetValueAt       );
  ConfigureBuiltInFunction( "DelimFileGetLastError",      HandlerDelimFileGetLastError     );
  ConfigureBuiltInFunction( "DelimFileGetRowCount",       HandlerDelimFileGetSampleCount   );
  ConfigureBuiltInFunction( "DelimFileGetColCount",       HandlerDelimFileGetVariableCount );
  ConfigureBuiltInFunction( "DelimFileGetColIndexByName", HandlerDelimFileGetVariableIndex );
  ConfigureBuiltInFunction( "DelimFileGetColNameByIndex", HandlerDelimFileGetVariableName  );
  ConfigureBuiltInFunction( "DelimFileLoad",              HandlerDelimFileLoadFile         );
  ConfigureBuiltInFunction( "DelimFileSetDelimiter",      HandlerDelimFileSetDelimiter     );
  ConfigureBuiltInFunction( "DelimFileSetFlags",          HandlerDelimFileSetReadFlags     );
  ConfigureBuiltInFunction( "DelimFileWriteToFile",       HandlerDelimFileWriteToFile      );
  ConfigureBuiltInFunction( "DelimFileSetReserveBuffer",  HandlerDelimFileSetReserveBuffer );

  // excel exporter related functions
  //
  ConfigureBuiltInFunction( "ExcelExporterSetValueAt",   HandlerExcelExportSetValueAt   );
  ConfigureBuiltInFunction( "ExcelExporterGetValueAt",   HandlerExcelExportGetValueAt   );
  ConfigureBuiltInFunction( "ExcelExporterWriteToFile",  HandlerExcelExportWriteFile    );
  ConfigureBuiltInFunction( "ExcelExporterSetCellStyle", HandlerExcelExportSetCellStyle );
  ConfigureBuiltInFunction( "ExcelExporterSetCellAlign", HandlerExcelExportSetCellAlign );

  // disk space functions
  //
  ConfigureBuiltInFunction( "DiskFreeBytes",     HandlerDiskFreeBytes     );
  ConfigureBuiltInFunction( "DiskTotalBytes",    HandlerDiskTotalBytes    );
  ConfigureBuiltInFunction( "DiskPercentFree",   HandlerDiskPercentFree   );
  ConfigureBuiltInFunction( "DiskPercentFull",   HandlerDiskPercentFull   );
  ConfigureBuiltInFunction( "DiskIsRemovable",   HandlerDiskIsRemovable   );
  ConfigureBuiltInFunction( "DiskIsFixedDrive",  HandlerDiskIsFixedDrive  );
  ConfigureBuiltInFunction( "DiskIsRemoteDrive", HandlerDiskIsRemoteDrive );
  ConfigureBuiltInFunction( "DiskIsCDROM",       HandlerDiskIsCdROM       );
  ConfigureBuiltInFunction( "DiskIsRAMDrive",    HandlerDiskIsRamDrive    );

  // windows functions
  //
  ConfigureBuiltInFunction( "RebootHost",           HandlerRebootHost     );
  ConfigureBuiltInFunction( "Beep",                 HandlerBeep           );
  ConfigureBuiltInFunction( "ExitWindows",          HandlerExitWindows    );
  ConfigureBuiltInFunction( "ShellExecute",         HandlerShellExecute   );

#ifndef TOOL_PUBLIC_BUILD
  PrivateFunctionsInit();
#endif

  return ( true );
}
/* End of function "VMVirtualOpSys::InitVirtualMachine"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::CanModify   / GetWriteLock 
                                     GetReadLock / UnlockData

       DESCRIPTION:  Does the work required to perform monitor safety on a variable

             INPUT:  poVariable - pointer to variable
            OUTPUT:  

           RETURNS:  void
*/
bool VMVirtualOpSys::CanModify( VMVariant* poVariable )
{
  return( !is_constant( poVariable ) );
}
void VMVirtualOpSys::GetReadLock( VMVariant* poVariable )
{
  if ( is_monitored( poVariable ) )
  {
    get_monitor( poVariable )->RequestReadLock();
  }
}
/*****************************************************************************/
bool VMVirtualOpSys::GetWriteLock( VMVariant* poVariable )
{
  if ( is_constant( poVariable ) )
  {
    return( false );
  }
  if ( is_monitored( poVariable ) )
  {
    get_monitor( poVariable )->RequestWriteLock();
  }
  return( true );
}
/*****************************************************************************/
void VMVirtualOpSys::UnlockData( VMVariant* poVariable, bool bLockType )
{
  if ( is_monitored( poVariable ) )
  {
    if ( bLockType == true )
    {
      get_monitor( poVariable )->ReleaseWriteLock();
    }
    else
    {
      get_monitor( poVariable )->ReleaseReadLock();
    }
  }
}
/* End of function "CanModify   / GetWriteLock"
                   "GetReadLock / UnlockData"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::SetValue

       DESCRIPTION:  Does the work required to set the value of a variable

             INPUT:  poVariable - pointer to variable
                     xxx        - the value to set
            OUTPUT:  

           RETURNS:  void
*/
void VMVirtualOpSys::SetValue( VMVariant* poVariable, int iValue )
{
  if ( !is_constant( poVariable ) )
  {
    if ( is_monitored( poVariable ) )
    {
      get_monitor( poVariable )->RequestWriteLock();
    }
    set_integer( poVariable, iValue );

    if ( is_monitored( poVariable ) )
    {
      get_monitor( poVariable )->ReleaseWriteLock();
    }
  }
  else
  {
    IllegalConstantAssignment();
  }
}
/*****************************************************************************/
void VMVirtualOpSys::SetValue( VMVariant* poVariable, long lValue )
{
  if ( !is_constant( poVariable ) )
  {
    if ( is_monitored( poVariable ) )
    {
      get_monitor( poVariable )->RequestWriteLock();
    }
    set_integer( poVariable, lValue );

    if ( is_monitored( poVariable ) )
    {
      get_monitor( poVariable )->ReleaseWriteLock();
    }
  }
  else
  {
    IllegalConstantAssignment();
  }
}
/*****************************************************************************/
void VMVirtualOpSys::SetValue( VMVariant* poVariable, vmstring* pxString )
{
  if ( !is_constant( poVariable ) )
  {
    if ( is_monitored( poVariable ) )
    {
      get_monitor( poVariable )->RequestWriteLock();
    }
    set_string( poVariable, pxString );

    if ( is_monitored( poVariable ) )
    {
      get_monitor( poVariable )->ReleaseWriteLock();
    }
  }
  else
  {
    IllegalConstantAssignment();
  }
}
/*****************************************************************************/
void VMVirtualOpSys::SetValue( VMVariant* poVariable, FILE* pFile )
{
  if ( !is_constant( poVariable ) )
  {
    if ( is_monitored( poVariable ) )
    {
      get_monitor( poVariable )->RequestWriteLock();
    }
    set_file( poVariable, pFile );

    if ( is_monitored( poVariable ) )
    {
      get_monitor( poVariable )->ReleaseWriteLock();
    }
  }
  else
  {
    IllegalConstantAssignment();
  }
}
/*****************************************************************************/
void VMVirtualOpSys::SetValue( VMVariant* poVariable, HANDLE hValue )
{
  if ( !is_constant( poVariable ) )
  {
    if ( is_monitored( poVariable ) )
    {
      get_monitor( poVariable )->RequestWriteLock();
    }
    switch( poVariable->v_type )
    {
       case DT_KERNELHANDLE:
       {
         set_kernelhandle( poVariable, hValue );
       }
       break;

       case DT_NTFILEHANDLE:
       {
         set_ntfilehandle( poVariable, hValue );
       }
       break;

       case DT_HANDLE:
       {
         set_handle( poVariable, hValue );
       }
       break;

       case DT_FILEFINDHANDLE:
       {
         set_filefindhandle( poVariable, hValue );
       }
       break;
    }

    if ( is_monitored( poVariable ) )
    {
      get_monitor( poVariable )->ReleaseWriteLock();
    }
  }
  else
  {
    IllegalConstantAssignment();
  }
}
/*****************************************************************************/
void VMVirtualOpSys::SetValue( VMVariant* poVariable, SYSTEMTIME xValue )
{
  if ( !is_constant( poVariable ) )
  {
    if ( is_monitored( poVariable ) )
    {
      get_monitor( poVariable )->RequestWriteLock();
    }
    set_datetime( poVariable, xValue );

    if ( is_monitored( poVariable ) )
    {
      get_monitor( poVariable )->ReleaseWriteLock();
    }
  }
  else
  {
    IllegalConstantAssignment();
  }
}
/*****************************************************************************/
void VMVirtualOpSys::SetValue( VMVariant* poVariable, DWORD dwValue  )
{
  if ( !is_constant( poVariable ) )
  {
    if ( is_monitored( poVariable ) )
    {
      get_monitor( poVariable )->RequestWriteLock();
    }
    set_dword( poVariable, dwValue );

    if ( is_monitored( poVariable ) )
    {
      get_monitor( poVariable )->ReleaseWriteLock();
    }
  }
  else
  {
    IllegalConstantAssignment();
  }
}
/*****************************************************************************/
void VMVirtualOpSys::SetValue( VMVariant* poVariable, double dblValue )
{
  if ( !is_constant( poVariable ) )
  {
    if ( is_monitored( poVariable ) )
    {
      get_monitor( poVariable )->RequestWriteLock();
    }
    set_double( poVariable, dblValue );

    if ( is_monitored( poVariable ) )
    {
      get_monitor( poVariable )->ReleaseWriteLock();
    }
  }
  else
  {
    IllegalConstantAssignment();
  }
}
/*****************************************************************************/
void VMVirtualOpSys::SetValue( VMVariant* poVariable, unsigned char chValue )
{
  if ( !is_constant( poVariable ) )
  {
    if ( is_monitored( poVariable ) )
    {
      get_monitor( poVariable )->RequestWriteLock();
    }
    set_byte( poVariable, chValue );

    if ( is_monitored( poVariable ) )
    {
      get_monitor( poVariable )->ReleaseWriteLock();
    }
  }
  else
  {
    IllegalConstantAssignment();
  }
}
/*****************************************************************************/
void VMVirtualOpSys::SetValue( VMVariant* poVariable, bool bValue )
{
  if ( !is_constant( poVariable ) )
  {
    if ( is_monitored( poVariable ) )
    {
      get_monitor( poVariable )->RequestWriteLock();
    }
    set_byte( poVariable, bValue );

    if ( is_monitored( poVariable ) )
    {
      get_monitor( poVariable )->ReleaseWriteLock();
    }
  }
  else
  {
    IllegalConstantAssignment();
  }
}
/* End of function "VMVirtualOpSys::SetValue"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerThrowError

       DESCRIPTION:  allows the script to throw if there is a condition under
                     which it should not continue

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  none

           RETURNS:  0
*/
int  VMVirtualOpSys::HandlerThrowError( int iArgc )
{
  VMException* pThrow;
  if ( iArgc == 1 )
  {
    VerifyElementType( 0, DT_STRING );

    // if the script is compiled with pragma to enable file/lines then include
    // that as part of the exception along with the user message string
    //
    VMException* pThrow = new VMException( m_poInterpreter->GetLastScriptFile(),
                                           m_poInterpreter->GetLastScriptLine(), 
                                           m_poVirtualChip->m_psStackPointer[ 0 ].v.v_string->str_data );
    throw pThrow;
  }
  else
  {
     pThrow = new VMException( m_poInterpreter->GetLastScriptFile(),
                               m_poInterpreter->GetLastScriptLine(), 
                               "User Script Threw Error. No Message Given" );
  }
  throw pThrow;
}
/* End of function "VMVirtualOpSys::HandlerThrowError"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerSetBit

       DESCRIPTION:  does the work required to set a document field's value in
                     the server context

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  none

           RETURNS:  0
*/
int VMVirtualOpSys::HandlerSetBit( int iArgc )
{
  m_poInterpreter->SetLastCall( "SetBit" );

  VerifyRunLineArguments( iArgc, 3 );
  VerifyElementType( 1, DT_INTEGER );
  VerifyElementType( 0, DT_BYTE );

  int iBit  = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_integer;
  bool bSet = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_byte;

  switch ( m_poVirtualChip->m_psStackPointer[ 2 ].v_type )
  {
    case DT_INTEGER:
    {
      long lMask    = 1 << iBit;
      long lOldVal  = m_poVirtualChip->m_psStackPointer[ 2 ].v.v_integer;
      long lNewVal;
      if ( !bSet )
      {
        lMask   = ~lMask;
        lNewVal = lOldVal & lMask;
      }
      else 
      {
        lNewVal = lOldVal | lMask;
      }
      SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], lNewVal );
    }
    break;

    case DT_DWORD:
    {
      DWORD dwMask    = 1 << iBit;
      DWORD dwOldVal  = m_poVirtualChip->m_psStackPointer[ 2 ].v.v_dword;
      DWORD dwNewVal;
      if ( !bSet )
      {
        dwMask   = ~dwMask;
        dwNewVal = dwOldVal & dwMask;
      }
      else 
      {
        dwNewVal = dwOldVal | dwMask;
      }
      SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], dwNewVal );
    }
    break;

    case DT_BYTE:
    {
      unsigned char chMask    = 1 << iBit;
      unsigned char chOldVal  = m_poVirtualChip->m_psStackPointer[ 2 ].v.v_byte;
      unsigned char chNewVal;
      if ( !bSet )
      {
        chMask   = ~chMask;
        chNewVal = chOldVal & chMask;
      }
      else 
      {
        chNewVal = chOldVal | chMask;
      }
      SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], chNewVal );
    }
    break;
  }

  m_poVirtualChip->m_psStackPointer += iArgc;
  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerSetBit"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerGetField

       DESCRIPTION:  does the work required to get a document field from the
                     server context

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  none

           RETURNS:  0
*/
int VMVirtualOpSys::HandlerGetField( int iArgc )
{
  m_poInterpreter->SetLastCall( "GetAppEnvField" );

  char* pchFieldName = NULL;

  VerifyRunLineArguments( iArgc, 1 );
  VerifyElementType( 0, DT_STRING );

  const CAppContextVariant* poFieldValue;
  poFieldValue = m_poServerContext->GetFieldByName( m_poVirtualChip->m_psStackPointer[0].v.v_string->str_data );

  if ( poFieldValue )
  {
    m_poVirtualChip->m_psStackPointer[ iArgc ].ResetValue( false );

    switch( poFieldValue->GetValueType() )
    {
      case CAppContextVariant::eString:
      {
        char* pchValue = NULL;
        int   iLength  = poFieldValue->AsString( NULL );
         
        vmstring* pchReturn = AllocateNewString( iLength + 2, true );
        poFieldValue->AsString( pchReturn->str_data ); 
        SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], pchReturn );
      }
      break;

      case CAppContextVariant::eLong:
      {
        long lValue;
        poFieldValue->GetValue( lValue );
        SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], lValue );
      }
      break;

      case CAppContextVariant::eBool:
      {
        bool bValue;
        poFieldValue->GetValue( bValue );
        SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], bValue );
      }
      break;

      case CAppContextVariant::eDouble:
      {
        bool dblValue;
        poFieldValue->GetValue( dblValue );
        SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], dblValue );
      }
      break;

      case CAppContextVariant::eDWORD:
      {
        DWORD dwValue;
        poFieldValue->GetValue( dwValue );
        SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], dwValue );
      }
      break;

      case CAppContextVariant::eDateTime:
      {
        SYSTEMTIME xValue;
        poFieldValue->GetValue( xValue );
        SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], xValue );
      }
      break;

      case CAppContextVariant::eBytes:
      {
        VMByteArray* poBytes = new VMByteArray;
        poFieldValue->GetValue( *poBytes );
        m_poVirtualChip->m_psStackPointer[ iArgc ].v_type = DT_BYTEARRAY;
        m_poVirtualChip->m_psStackPointer[ iArgc ].v.v_bytearray = poBytes;
      }
      break;
    }
  }
  else
  {
    set_nil( &m_poVirtualChip->m_psStackPointer[ iArgc ] );
  }
   
  m_poVirtualChip->m_psStackPointer += iArgc;
  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerGetField"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerSetField

       DESCRIPTION:  does the work required to set a document field's value in
                     the server context

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  none

           RETURNS:  0
*/
int VMVirtualOpSys::HandlerSetField( int iArgc )
{
  m_poInterpreter->SetLastCall( "SetAppEnvField" );

  char* pchFieldName = NULL;
  char* pchFieldText = NULL;

  VerifyRunLineArguments( iArgc, 2 );
  VerifyElementType( 1, DT_STRING );

  pchFieldName = m_poVirtualChip->m_psStackPointer[1].v.v_string->str_data;

  switch ( m_poVirtualChip->m_psStackPointer[ 0 ].v_type )
  {
   case DT_STRING:
   {
     pchFieldText = m_poVirtualChip->m_psStackPointer[0].v.v_string->str_data;
     CAppContextVariant* poValue = new CAppContextVariant( pchFieldText );
     m_poServerContext->SetFieldByName( pchFieldName, poValue );
   }
   break;

   case DT_BYTE:
   {
     CAppContextVariant* poValue;
     poValue = new CAppContextVariant( (bool)m_poVirtualChip->m_psStackPointer[0].v.v_byte );
     m_poServerContext->SetFieldByName( pchFieldName, poValue );
   }
   break;

   case DT_DOUBLE:
   {
     CAppContextVariant* poValue;
     poValue = new CAppContextVariant( m_poVirtualChip->m_psStackPointer[0].v.v_double );
     m_poServerContext->SetFieldByName( pchFieldName, poValue );
   }
   break;

   case DT_DWORD:
   {
     CAppContextVariant* poValue;
     poValue = new CAppContextVariant( m_poVirtualChip->m_psStackPointer[0].v.v_dword );
     m_poServerContext->SetFieldByName( pchFieldName, poValue );
   }
   break;

   case DT_DATETIME:
   {
     CAppContextVariant* poValue;
     poValue = new CAppContextVariant( m_poVirtualChip->m_psStackPointer[0].v.v_datetime );
     m_poServerContext->SetFieldByName( pchFieldName, poValue );
   }
   break;

   case DT_INTEGER:
   {
     CAppContextVariant* poValue;
     poValue = new CAppContextVariant( m_poVirtualChip->m_psStackPointer[0].v.v_integer );
     m_poServerContext->SetFieldByName( pchFieldName, poValue );
   }
   break;

   case DT_BYTEARRAY:
   {
     CAppContextVariant* poValue;
     poValue = new CAppContextVariant( *(m_poVirtualChip->m_psStackPointer[0].v.v_bytearray) );
     m_poServerContext->SetFieldByName( pchFieldName, poValue );
   }
   break;
  }

  m_poVirtualChip->m_psStackPointer += iArgc;
  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerSetField"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerSendCommandToApp

       DESCRIPTION:  sends a command to the hosting application environment

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  none

           RETURNS:  0
*/
int VMVirtualOpSys::HandlerSendCommandToApp( int iArgc )
{
  m_poInterpreter->SetLastCall( "SendCommandToApp" );

  VerifyRunLineArguments( iArgc, 3 );
  VerifyElementType( 2, DT_INTEGER );
  VerifyElementType( 1, DT_INTEGER );

  int iCommand    = m_poVirtualChip->m_psStackPointer[ 2 ].v.v_integer;
  int iSubCommand = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_integer;

  switch ( m_poVirtualChip->m_psStackPointer[ 0 ].v_type )
  {
   case DT_STRING:
   {
     ::SendMessage( m_hWndCommandTarget, 
                    iCommand, 
                    iSubCommand, 
                    (LPARAM)m_poVirtualChip->m_psStackPointer[0].v.v_string->str_data );
   }
   break;

   case DT_BYTE:
   {
     ::SendMessage( m_hWndCommandTarget, 
                    iCommand, 
                    iSubCommand, 
                    (LPARAM)m_poVirtualChip->m_psStackPointer[0].v.v_byte );
   }
   break;

   case DT_DOUBLE:
   {
     ::SendMessage( m_hWndCommandTarget, 
                    iCommand, 
                    iSubCommand, 
                    (LPARAM)m_poVirtualChip->m_psStackPointer[0].v.v_double );
   }
   break;

   case DT_DWORD:
   {
     ::SendMessage( m_hWndCommandTarget, 
                    iCommand, 
                    iSubCommand, 
                    (LPARAM)m_poVirtualChip->m_psStackPointer[0].v.v_dword );
   }
   break;

   case DT_INTEGER:
   {
     ::SendMessage( m_hWndCommandTarget, 
                    iCommand, 
                    iSubCommand, 
                    (LPARAM)m_poVirtualChip->m_psStackPointer[0].v.v_integer );
   }
   break;


   case DT_KERNELHANDLE:
   {
     ::SendMessage( m_hWndCommandTarget, 
                    iCommand, 
                    iSubCommand, 
                    (LPARAM)m_poVirtualChip->m_psStackPointer[0].v.v_kernelhandle );
   }
   break;

   case DT_NTFILEHANDLE:
   case DT_HANDLE:
   {
     ::SendMessage( m_hWndCommandTarget, 
                    iCommand, 
                    iSubCommand, 
                    (LPARAM)m_poVirtualChip->m_psStackPointer[0].v.v_handle );
   }
   break;
  }

  m_poVirtualChip->m_psStackPointer += iArgc;
  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerSendCommandToApp"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerTypeOf

       DESCRIPTION:  get the data type of a value

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerTypeOf( int iArgc )
{
  VerifyRunLineArguments( iArgc, 1 );

  SetValue( &m_poVirtualChip->m_psStackPointer[1], 
            m_poVirtualChip->m_psStackPointer->v_type );

  ++m_poVirtualChip->m_psStackPointer;
  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerTypeOf"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerIsXXXX

       DESCRIPTION:  Tests the type of the argument. Puts true on the stack
                     if the argument matches the type, false otherwise

             INPUT:  iArgc - must be 1
            OUTPUT:  none

           RETURNS:  0
*/
int VMVirtualOpSys::HandlerIsNull( int iArgc )
{
  VerifyRunLineArguments( iArgc, 1 );
  SetValue( &m_poVirtualChip->m_psStackPointer[1], 
            m_poVirtualChip->m_psStackPointer[ 0 ].v_type == DT_NIL );
  ++m_poVirtualChip->m_psStackPointer;
  return( 0 );
}
/*****************************************************************************/
int VMVirtualOpSys::HandlerIsClass( int iArgc )
{
  VerifyRunLineArguments( iArgc, 1 );
  SetValue( &m_poVirtualChip->m_psStackPointer[1], 
            m_poVirtualChip->m_psStackPointer[ 0 ].v_type == DT_CLASS );
  ++m_poVirtualChip->m_psStackPointer;
  return( 0 );
}
/*****************************************************************************/
int VMVirtualOpSys::HandlerIsVector( int iArgc )
{
  VerifyRunLineArguments( iArgc, 1 );
  SetValue( &m_poVirtualChip->m_psStackPointer[1], 
            m_poVirtualChip->m_psStackPointer[ 0 ].v_type == DT_USERVECTOR );
  ++m_poVirtualChip->m_psStackPointer;
  return( 0 );
}
/*****************************************************************************/
int VMVirtualOpSys::HandlerIsNumber( int iArgc )
{
  VerifyRunLineArguments( iArgc, 1 );
  SetValue( &m_poVirtualChip->m_psStackPointer[1], 
            m_poVirtualChip->m_psStackPointer[ 0 ].v_type == DT_INTEGER );
  ++m_poVirtualChip->m_psStackPointer;
  return( 0 );
}
/*****************************************************************************/
int VMVirtualOpSys::HandlerIsString( int iArgc )
{
  VerifyRunLineArguments( iArgc, 1 );
  SetValue( &m_poVirtualChip->m_psStackPointer[1], 
            m_poVirtualChip->m_psStackPointer[ 0 ].v_type == DT_STRING );
  ++m_poVirtualChip->m_psStackPointer;
  return( 0 );
}
/*****************************************************************************/
int VMVirtualOpSys::HandlerIsFile( int iArgc )
{
  VerifyRunLineArguments( iArgc, 1 );
  SetValue( &m_poVirtualChip->m_psStackPointer[1], 
            m_poVirtualChip->m_psStackPointer[ 0 ].v_type == DT_FILE );
  ++m_poVirtualChip->m_psStackPointer;
  return( 0 );
}
/*****************************************************************************/
int VMVirtualOpSys::HandlerIsKernelObject( int iArgc )
{
  VerifyRunLineArguments( iArgc, 1 );
  SetValue( &m_poVirtualChip->m_psStackPointer[1], 
            m_poVirtualChip->m_psStackPointer[ 0 ].v_type == DT_KERNELHANDLE );
  ++m_poVirtualChip->m_psStackPointer;
  return( 0 );
}
/*****************************************************************************/
int VMVirtualOpSys::HandlerIsHandle( int iArgc )
{
   VerifyRunLineArguments( iArgc, 1 );
   SetValue( &m_poVirtualChip->m_psStackPointer[1], 
             m_poVirtualChip->m_psStackPointer[ 0 ].v_type == DT_HANDLE );
   ++m_poVirtualChip->m_psStackPointer;
   return( 0 );
}
/*****************************************************************************/
int VMVirtualOpSys::HandlerIsDateTime( int iArgc )
{
  VerifyRunLineArguments( iArgc, 1 );
  SetValue( &m_poVirtualChip->m_psStackPointer[1], 
            m_poVirtualChip->m_psStackPointer[ 0 ].v_type == DT_DATETIME );
  ++m_poVirtualChip->m_psStackPointer;
  return( 0 );
}
/*****************************************************************************/
int VMVirtualOpSys::HandlerIsDWord( int iArgc )
{
  VerifyRunLineArguments( iArgc, 1 );
  SetValue( &m_poVirtualChip->m_psStackPointer[1], 
            m_poVirtualChip->m_psStackPointer[ 0 ].v_type == DT_DWORD );
  ++m_poVirtualChip->m_psStackPointer;
  return( 0 );
}
/*****************************************************************************/
int VMVirtualOpSys::HandlerIsNTHandle( int iArgc )
{
  VerifyRunLineArguments( iArgc, 1 );
  SetValue( &m_poVirtualChip->m_psStackPointer[1], 
            m_poVirtualChip->m_psStackPointer[ 0 ].v_type == DT_NTFILEHANDLE );
  ++m_poVirtualChip->m_psStackPointer;
  return( 0 );
}
/*****************************************************************************/
int VMVirtualOpSys::HandlerIsFindHandle( int iArgc )
{
  VerifyRunLineArguments( iArgc, 1 );
  SetValue( &m_poVirtualChip->m_psStackPointer[1], 
            m_poVirtualChip->m_psStackPointer[ 0 ].v_type == DT_FILEFINDHANDLE );
  ++m_poVirtualChip->m_psStackPointer;
  return( 0 );
}
/*****************************************************************************/
int VMVirtualOpSys::HandlerIsStream( int iArgc )
{
  VerifyRunLineArguments( iArgc, 1 );
  SetValue( &m_poVirtualChip->m_psStackPointer[1], 
            m_poVirtualChip->m_psStackPointer[ 0 ].v_type == DT_IOSTREAM );
  ++m_poVirtualChip->m_psStackPointer;
  return( 0 );
}
/*****************************************************************************/
int VMVirtualOpSys::HandlerIsQueue( int iArgc )
{
  VerifyRunLineArguments( iArgc, 1 );
  SetValue( &m_poVirtualChip->m_psStackPointer[1], 
            m_poVirtualChip->m_psStackPointer[ 0 ].v_type == DT_QUEUE );
  ++m_poVirtualChip->m_psStackPointer;
  return( 0 );
}
/*****************************************************************************/
int VMVirtualOpSys::HandlerIsStack( int iArgc )
{
  VerifyRunLineArguments( iArgc, 1 );
  SetValue( &m_poVirtualChip->m_psStackPointer[1], 
            m_poVirtualChip->m_psStackPointer[ 0 ].v_type == DT_STACK );
  ++m_poVirtualChip->m_psStackPointer;
  return( 0 );
}
/*****************************************************************************/
int VMVirtualOpSys::HandlerIsHashTable( int iArgc )
{
  VerifyRunLineArguments( iArgc, 1 );
  SetValue( &m_poVirtualChip->m_psStackPointer[1], 
            m_poVirtualChip->m_psStackPointer[ 0 ].v_type == DT_HASHTABLE );
  ++m_poVirtualChip->m_psStackPointer;
  return( 0 );
}
/*****************************************************************************/
int VMVirtualOpSys::HandlerIsCalculator( int iArgc )
{
  VerifyRunLineArguments( iArgc, 1 );
  SetValue( &m_poVirtualChip->m_psStackPointer[1], 
            m_poVirtualChip->m_psStackPointer[ 0 ].v_type == DT_CALCULATOR );
  ++m_poVirtualChip->m_psStackPointer;
  return( 0 );
}
/*****************************************************************************/
int VMVirtualOpSys::HandlerIsConstant( int iArgc )
{
  VerifyRunLineArguments( iArgc, 1 );
  SetValue( &m_poVirtualChip->m_psStackPointer[1], 
            m_poVirtualChip->m_psStackPointer[0].v_constant == true );
  ++m_poVirtualChip->m_psStackPointer;
  return( 0 );
}
/*****************************************************************************/
int VMVirtualOpSys::HandlerIsConstCast( int iArgc )
{
  VerifyRunLineArguments( iArgc, 1 );
  SetValue( &m_poVirtualChip->m_psStackPointer[1], 
            m_poVirtualChip->m_psStackPointer[0].v_tempconst == true );
  ++m_poVirtualChip->m_psStackPointer;
  return( 0 );
}
/*****************************************************************************/
int VMVirtualOpSys::HandlerIsDouble( int iArgc )
{
  VerifyRunLineArguments( iArgc, 1 );
  SetValue( &m_poVirtualChip->m_psStackPointer[1], 
            m_poVirtualChip->m_psStackPointer[ 0 ].v_type == DT_DOUBLE );
  ++m_poVirtualChip->m_psStackPointer;
  return( 0 );
}
/*****************************************************************************/
int VMVirtualOpSys::HandlerIsByte( int iArgc )
{
  VerifyRunLineArguments( iArgc, 1 );
  SetValue( &m_poVirtualChip->m_psStackPointer[1], 
            m_poVirtualChip->m_psStackPointer[ 0 ].v_type == DT_BYTE );
  ++m_poVirtualChip->m_psStackPointer;
  return( 0 );
}
/*****************************************************************************/
int VMVirtualOpSys::HandlerIsByteArray( int iArgc )
{
  VerifyRunLineArguments( iArgc, 1 );
  SetValue( &m_poVirtualChip->m_psStackPointer[1], 
            m_poVirtualChip->m_psStackPointer[ 0 ].v_type == DT_BYTEARRAY );
  ++m_poVirtualChip->m_psStackPointer;
  return( 0 );
}
/*****************************************************************************/
int VMVirtualOpSys::HandlerIsReportPage( int iArgc )
{
  VerifyRunLineArguments( iArgc, 1 );
  SetValue( &m_poVirtualChip->m_psStackPointer[1], 
            m_poVirtualChip->m_psStackPointer[ 0 ].v_type == DT_REPORTPAGE );
  ++m_poVirtualChip->m_psStackPointer;
  return( 0 );
}
/*****************************************************************************/
int VMVirtualOpSys::HandlerIsPageRegion( int iArgc )
{
  VerifyRunLineArguments( iArgc, 1 );
  SetValue( &m_poVirtualChip->m_psStackPointer[1], 
            m_poVirtualChip->m_psStackPointer[ 0 ].v_type == DT_REPORTPAGEREGION );
  ++m_poVirtualChip->m_psStackPointer;
  return( 0 );
}
/*****************************************************************************/
int VMVirtualOpSys::HandlerIsPageTable( int iArgc )
{
  VerifyRunLineArguments( iArgc, 1 );
  SetValue( &m_poVirtualChip->m_psStackPointer[1], 
            m_poVirtualChip->m_psStackPointer[ 0 ].v_type == DT_REPORTTABLE );
  ++m_poVirtualChip->m_psStackPointer;
  return( 0 );
}
/*****************************************************************************/
int VMVirtualOpSys::HandlerIsColor( int iArgc )
{
  VerifyRunLineArguments( iArgc, 1 );
  SetValue( &m_poVirtualChip->m_psStackPointer[1], 
            m_poVirtualChip->m_psStackPointer[ 0 ].v_type == DT_COLOR );
  ++m_poVirtualChip->m_psStackPointer;
  return( 0 );
}
/*****************************************************************************/
int VMVirtualOpSys::HandlerIsDBConnection( int iArgc )
{
  VerifyRunLineArguments( iArgc, 1 );
  SetValue( &m_poVirtualChip->m_psStackPointer[1], 
            m_poVirtualChip->m_psStackPointer[ 0 ].v_type == DT_ODBC );
  ++m_poVirtualChip->m_psStackPointer;
  return( 0 );
}
/*****************************************************************************/
int VMVirtualOpSys::HandlerIsRegExpression( int iArgc )
{
  VerifyRunLineArguments( iArgc, 1 );
  SetValue( &m_poVirtualChip->m_psStackPointer[1], 
            m_poVirtualChip->m_psStackPointer[ 0 ].v_type == DT_REGEX );
  ++m_poVirtualChip->m_psStackPointer;
  return( 0 );
}
/*****************************************************************************/
int VMVirtualOpSys::HandlerIsHtmlParser( int iArgc )
{
  VerifyRunLineArguments( iArgc, 1 );
  SetValue( &m_poVirtualChip->m_psStackPointer[1], 
            m_poVirtualChip->m_psStackPointer[ 0 ].v_type == DT_HTMLPARSER );
  ++m_poVirtualChip->m_psStackPointer;
  return( 0 );
}
/*****************************************************************************/
int VMVirtualOpSys::HandlerIsSqlLite2Database( int iArgc )
{
  VerifyRunLineArguments( iArgc, 1 );
  SetValue( &m_poVirtualChip->m_psStackPointer[1], 
            m_poVirtualChip->m_psStackPointer[ 0 ].v_type == DT_SQLLITE_2_DB );
  ++m_poVirtualChip->m_psStackPointer;
  return( 0 );
}
/*****************************************************************************/
int VMVirtualOpSys::HandlerIsUnZipper( int iArgc )
{
  VerifyRunLineArguments( iArgc, 1 );
  SetValue( &m_poVirtualChip->m_psStackPointer[1], 
            m_poVirtualChip->m_psStackPointer[ 0 ].v_type == DT_UNZIPPER );
  ++m_poVirtualChip->m_psStackPointer;
  return( 0 );
}
/*****************************************************************************/
int VMVirtualOpSys::HandlerIsZipMaker( int iArgc )
{
  VerifyRunLineArguments( iArgc, 1 );
  SetValue( &m_poVirtualChip->m_psStackPointer[1], 
            m_poVirtualChip->m_psStackPointer[ 0 ].v_type == DT_ZIPMAKER );
  ++m_poVirtualChip->m_psStackPointer;
  return( 0 );
}
/*****************************************************************************/
int VMVirtualOpSys::HandlerIsHttpClient( int iArgc )
{
  VerifyRunLineArguments( iArgc, 1 );
  SetValue( &m_poVirtualChip->m_psStackPointer[1], 
            m_poVirtualChip->m_psStackPointer[ 0 ].v_type == DT_HTTPCLIENT );
  ++m_poVirtualChip->m_psStackPointer;
  return( 0 );
}
/*****************************************************************************/
int VMVirtualOpSys::HandlerIsFtpClient( int iArgc )
{
  VerifyRunLineArguments( iArgc, 1 );
  SetValue( &m_poVirtualChip->m_psStackPointer[1], 
            m_poVirtualChip->m_psStackPointer[ 0 ].v_type == DT_FTPCLIENT );
  ++m_poVirtualChip->m_psStackPointer;
  return( 0 );
}
/*****************************************************************************/
int VMVirtualOpSys::HandlerIsSqlLite2Rowset( int iArgc )
{
  VerifyRunLineArguments( iArgc, 1 );
  SetValue( &m_poVirtualChip->m_psStackPointer[1], 
            m_poVirtualChip->m_psStackPointer[ 0 ].v_type == DT_SQLLITE_2_ROWSET );
  ++m_poVirtualChip->m_psStackPointer;
  return( 0 );
}
/*****************************************************************************/
int VMVirtualOpSys::HandlerIsFileBuilder( int iArgc )
{
  VerifyRunLineArguments( iArgc, 1 );
  SetValue( &m_poVirtualChip->m_psStackPointer[1], 
            m_poVirtualChip->m_psStackPointer[ 0 ].v_type == DT_FILE_BUILDER );
  ++m_poVirtualChip->m_psStackPointer;
  return( 0 );
}
/*****************************************************************************/
int VMVirtualOpSys::HandlerIsDelimitedFile( int iArgc )
{
  VerifyRunLineArguments( iArgc, 1 );
  SetValue( &m_poVirtualChip->m_psStackPointer[1], 
            m_poVirtualChip->m_psStackPointer[ 0 ].v_type == DT_DELIMITED_FILE );
  ++m_poVirtualChip->m_psStackPointer;
  return( 0 );
}
/*****************************************************************************/
int VMVirtualOpSys::HandlerIsExcelExporter( int iArgc )
{
  VerifyRunLineArguments( iArgc, 1 );
  SetValue( &m_poVirtualChip->m_psStackPointer[1], 
            m_poVirtualChip->m_psStackPointer[ 0 ].v_type == DT_EXCEL_EXPORTER );
  ++m_poVirtualChip->m_psStackPointer;
  return( 0 );
}
/*****************************************************************************/
int VMVirtualOpSys::HandlerIsThreadPool( int iArgc )
{
  VerifyRunLineArguments( iArgc, 1 );
  SetValue( &m_poVirtualChip->m_psStackPointer[1], 
            m_poVirtualChip->m_psStackPointer[ 0 ].v_type == DT_THREAD_POOL );
  ++m_poVirtualChip->m_psStackPointer;
  return( 0 );
}
/*****************************************************************************/
int VMVirtualOpSys::HandlerIsThread( int iArgc )
{
  VerifyRunLineArguments( iArgc, 1 );
  SetValue( &m_poVirtualChip->m_psStackPointer[1], 
            m_poVirtualChip->m_psStackPointer[ 0 ].v_type == DT_THREAD );
  ++m_poVirtualChip->m_psStackPointer;
  return( 0 );
}
/*****************************************************************************/
int VMVirtualOpSys::HandlerIsSqlLite3Database( int iArgc )
{
  VerifyRunLineArguments( iArgc, 1 );
  SetValue( &m_poVirtualChip->m_psStackPointer[1], 
            m_poVirtualChip->m_psStackPointer[ 0 ].v_type == DT_SQLLITE_3_DB );
  ++m_poVirtualChip->m_psStackPointer;
  return( 0 );
}
/*****************************************************************************/
int VMVirtualOpSys::HandlerIsSqlLite3Rowset( int iArgc )
{
  VerifyRunLineArguments( iArgc, 1 );
  SetValue( &m_poVirtualChip->m_psStackPointer[1], 
            m_poVirtualChip->m_psStackPointer[ 0 ].v_type == DT_SQLLITE_3_ROWSET );
  ++m_poVirtualChip->m_psStackPointer;
  return( 0 );
}
/*****************************************************************************/
int VMVirtualOpSys::HandlerIsInt64( int iArgc )
{
  VerifyRunLineArguments( iArgc, 1 );
  SetValue( &m_poVirtualChip->m_psStackPointer[1], 
            m_poVirtualChip->m_psStackPointer[ 0 ].v_type == DT_INT_64 );
  ++m_poVirtualChip->m_psStackPointer;
  return( 0 );
}
/*****************************************************************************/
int VMVirtualOpSys::IsType( int iOffset, int iType )
{
 BOOL bReturn = TRUE;
 int iTest = m_poVirtualChip->m_psStackPointer[ iOffset ].v_type;
 if ( _DTMAX >= iTest && _DTMIN <= iTest )
 {
   if ( m_poVirtualChip->m_psStackPointer[ iOffset ].v_type != iType ) 
   {
     m_poInterpreter->BadType( iOffset, iType ); 
     bReturn = FALSE;
   }
 }
 return( bReturn );
}
/* End of function "VMVirtualOpSys::IsTypeXXXX"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerNewTokenizer

       DESCRIPTION:  creates a new tokenizer object

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerNewTokenizer( int iArgc )
{
  m_poInterpreter->SetLastCall( "Tokenizer" );

  char* pchToTokenize   = NULL;
  char* pchDelimiters   = NULL;
  char* pchFieldWrapper = NULL;

  if ( 1 == iArgc )
  {
    VerifyRunLineArguments( iArgc, 1 );
    VerifyElementType( 0, DT_STRING );

    pchToTokenize = m_poVirtualChip->m_psStackPointer[0].v.v_string->str_data;

    VMString oToTokenize( pchToTokenize );

    VMTokenizer* poTokenizer = new VMTokenizer( oToTokenize );
    set_tokenizer( &m_poVirtualChip->m_psStackPointer[iArgc], poTokenizer ); 
  }
  else
  if ( 2 == iArgc )
  {
    VerifyRunLineArguments( iArgc, 2 );
    VerifyElementType( 1, DT_STRING );
    VerifyElementType( 0, DT_STRING );

    pchToTokenize = m_poVirtualChip->m_psStackPointer[1].v.v_string->str_data;
    VMString oToTokenize( pchToTokenize );

    pchDelimiters = m_poVirtualChip->m_psStackPointer[0].v.v_string->str_data;
    VMString oDelims( pchDelimiters );

    VMTokenizer* poTokenizer = new VMTokenizer( oToTokenize, oDelims );
    set_tokenizer( &m_poVirtualChip->m_psStackPointer[iArgc], poTokenizer ); 
  }
  else
  if ( 3 == iArgc )
  {
    VerifyRunLineArguments( iArgc, 3 );
    VerifyElementType( 2, DT_STRING );
    VerifyElementType( 1, DT_STRING );
    VerifyElementType( 0, DT_STRING );

    pchToTokenize = m_poVirtualChip->m_psStackPointer[2].v.v_string->str_data;
    VMString oToTokenize( pchToTokenize );

    pchDelimiters = m_poVirtualChip->m_psStackPointer[1].v.v_string->str_data;
    VMString oDelims( pchDelimiters );

    pchFieldWrapper = m_poVirtualChip->m_psStackPointer[0].v.v_string->str_data;
    VMString oFieldWrapper( pchFieldWrapper );

    VMTokenizer* poTokenizer = new VMTokenizer( oToTokenize, oDelims, oFieldWrapper );
    set_tokenizer( &m_poVirtualChip->m_psStackPointer[iArgc], poTokenizer ); 
  }
  else
  {
    VerifyRunLineArguments( iArgc, 1 );
  }
  m_poVirtualChip->m_psStackPointer += iArgc;
  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerNewTokenizer"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerHasMoreTokens

       DESCRIPTION:  queries the tokenization object for more tokens

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerHasMoreTokens( int iArgc )
{
  m_poInterpreter->SetLastCall( "HasMoreTokens" );

  VerifyRunLineArguments( iArgc, 1 );
  VerifyElementType( 0, DT_TOKENIZER );

  VMTokenizer* poTokenizer = get_tokenizer( m_poVirtualChip->m_psStackPointer );
  SetValue( &m_poVirtualChip->m_psStackPointer[iArgc], 
            poTokenizer->HasMoreTokens() );

  m_poVirtualChip->m_psStackPointer += iArgc;
  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerHasMoreTokens"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerGetNextToken

       DESCRIPTION:  Invokes the tokenization object to eject the next token

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerGetNextToken( int iArgc )
{
  m_poInterpreter->SetLastCall( "GetNextToken" );

  VerifyRunLineArguments( iArgc, 1 );
  VerifyElementType( 0, DT_TOKENIZER );

  VMTokenizer* poTokenizer = get_tokenizer( &m_poVirtualChip->m_psStackPointer[0] );

  try
  {
    VMString oNextToken = poTokenizer->GetNextToken();

    // send back the string
    //
    vmstring* pchReturn = AllocateNewString( oNextToken.GetLength() + 1, true );
    strcpy( pchReturn->str_data, (LPCTSTR)oNextToken );
    m_poVirtualChip->m_psStackPointer[iArgc].v.v_string = pchReturn;

    // set the return code
    //
    SetValue( &m_poVirtualChip->m_psStackPointer[iArgc], pchReturn );
  }
  catch( VMException* poError )
  {
    delete poError;

    // swallow the error, return an empty string and set return code to 
    // indicate failure
    //
    vmstring* pchReturn = AllocateNewString( 1, true );
    strcpy( pchReturn->str_data, "" );
    m_poVirtualChip->m_psStackPointer[iArgc].v.v_string = pchReturn;

    SetValue( &m_poVirtualChip->m_psStackPointer[iArgc], pchReturn );
  }
  m_poVirtualChip->m_psStackPointer += iArgc;
  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerGetNextToken"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerConstCast

       DESCRIPTION:  switches a variable into and out of temp const mode

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerConstCast( int iArgc )
{
  m_poInterpreter->SetLastCall( "ConstCast" );

  VerifyRunLineArguments( iArgc, 2 );

  VerifyElementType( 0, DT_BYTE );

  bool bLockState  = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_byte;

  if ( 0 == bLockState )
  {
    m_poVirtualChip->m_psStackPointer[ 1 ].v_tempconst = false;
  }
  else
  {
    m_poVirtualChip->m_psStackPointer[ 1 ].v_tempconst = true;
  }
  m_poVirtualChip->m_psStackPointer += iArgc;
  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerConstCast"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerSynchronous

       DESCRIPTION:  switches a variable into and out of synchronouse mode

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerSynchronous( int iArgc )
{
  m_poInterpreter->SetLastCall( "Synchronize" );

  VerifyRunLineArguments( iArgc, 2 );

  VerifyElementType( 0, DT_BYTE );

  // make sure that deleting the monitor is safe to do!!!
  //
  if ( false == m_poVirtualChip->m_psStackPointer[ 0 ].v.v_byte )
  {
    m_poVirtualChip->m_psStackPointer[ 1 ].v_monitored = false;
    delete m_poVirtualChip->m_psStackPointer[ 1 ].v_poMonitor;
    m_poVirtualChip->m_psStackPointer[ 1 ].v_poMonitor = NULL;
  }
  else
  {
    m_poVirtualChip->m_psStackPointer[ 1 ].v_monitored = true;
    m_poVirtualChip->m_psStackPointer[ 1 ].v_poMonitor = new VMDataMonitor;
  }
  m_poVirtualChip->m_psStackPointer += 2;
  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerSynchronous"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  "HandlerGetReadLock  / HandlerFreeReadLock"
                     "HandlerGetWriteLock / HandlerFreeWriteLock"

       DESCRIPTION:  handlers for thread-safe access to variables

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerGetReadLock( int iArgc )
{
  m_poInterpreter->SetLastCall( "AcquireReadLock" );

  VerifyRunLineArguments( iArgc, 1 );

  GetReadLock( m_poVirtualChip->m_psStackPointer );

  m_poVirtualChip->m_psStackPointer += 1;
  return( 0 );
}
/*****************************************************************************/
int VMVirtualOpSys::HandlerFreeReadLock( int iArgc )
{
  m_poInterpreter->SetLastCall( "ReleaseReadLock" );

  VerifyRunLineArguments( iArgc, 1 );

  UnlockData( m_poVirtualChip->m_psStackPointer, false );

  m_poVirtualChip->m_psStackPointer += 1;
  return( 0 );
}
/*****************************************************************************/
int VMVirtualOpSys::HandlerGetWriteLock( int iArgc )
{
  m_poInterpreter->SetLastCall( "AcquireWriteLock" );

  VerifyRunLineArguments( iArgc, 1 );

  GetWriteLock( m_poVirtualChip->m_psStackPointer );

  m_poVirtualChip->m_psStackPointer += 1;
  return( 0 );
}
/*****************************************************************************/
int VMVirtualOpSys::HandlerFreeWriteLock( int iArgc )
{
  m_poInterpreter->SetLastCall( "ReleaseWriteLock" );

  VerifyRunLineArguments( iArgc, 1 );

  UnlockData( m_poVirtualChip->m_psStackPointer, true );

  m_poVirtualChip->m_psStackPointer += 1;
  return( 0 );
}
/* End of function "HandlerGetReadLock  / HandlerFreeReadLock"
                   "HandlerGetWriteLock / HandlerFreeWriteLock"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerNewVector

       DESCRIPTION:  allocate a new vector

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerNewVector( int iArgc )
{
  m_poInterpreter->SetLastCall( "Vector" );

  VerifyRunLineArguments( iArgc, 0 );

  VMDataVector* poVector = new VMDataVector;

  // all heap based variables are tracked separately in an allocation tracker
  // 
  // the work below is how that is accomplished. All heap based variable types
  // are tracked the same way, so you will see similar code in many other 
  // object allocation routines in this file.
  //
  VMTrackedAllocs* poAlloc = new VMTrackedAllocs;
  poAlloc->v.v_uservector  = poVector;
  poAlloc->v_type          = DT_USERVECTOR;
  m_oTrackedAllocs.push_back( poAlloc );

  set_uservector( &m_poVirtualChip->m_psStackPointer[ iArgc ], poVector );

  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerNewVector"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerNewByteArray

       DESCRIPTION:  allocate a new byte array

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerNewByteArray( int iArgc )
{
  m_poInterpreter->SetLastCall( "ByteArray" );

  int size;
  int growby;

  if ( iArgc == 1 )
  {
    VerifyElementType( 0, DT_INTEGER );
    size   = m_poVirtualChip->m_psStackPointer[0].v.v_integer;
    growby = -1;
  }
  else
  if ( iArgc == 2 )
  {
    VerifyElementType( 0, DT_INTEGER );
    VerifyElementType( 1, DT_INTEGER );

    size   = m_poVirtualChip->m_psStackPointer[0].v.v_integer;
    growby = m_poVirtualChip->m_psStackPointer[1].v.v_integer;
  }
  else
  {
    size   = 256;
    growby = -1;
  }
  VMByteArray* poByteArray = new VMByteArray();
  poByteArray->SetSize( size, growby );

  VMTrackedAllocs* poAlloc = new VMTrackedAllocs;
  poAlloc->v.v_bytearray   = poByteArray;
  poAlloc->v_type          = DT_BYTEARRAY;
  m_oTrackedAllocs.push_back( poAlloc );

  set_bytearray( &m_poVirtualChip->m_psStackPointer[ iArgc ], poByteArray ); 

  m_poVirtualChip->m_psStackPointer += iArgc;
  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerNewByteArray"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerNewDateTime

       DESCRIPTION:  allocate a new long

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerNewDateTime( int iArgc )
{
  m_poInterpreter->SetLastCall( "DateTime" );

  SYSTEMTIME value;

  if ( iArgc == 0 )
  {
    GetLocalTime( &value );
  }
  else
  if ( iArgc == 1 )
  {
    VerifyElementType( 0, DT_DATETIME );
    value  = m_poVirtualChip->m_psStackPointer[0].v.v_datetime;
  }
  else
  if ( iArgc == 6 )
  {
    VerifyElementType( 0, DT_INTEGER );
    VerifyElementType( 1, DT_INTEGER );
    VerifyElementType( 2, DT_INTEGER );
    VerifyElementType( 3, DT_INTEGER );
    VerifyElementType( 4, DT_INTEGER );
    VerifyElementType( 5, DT_INTEGER );

    value.wYear   = static_cast< WORD >( m_poVirtualChip->m_psStackPointer[ 5 ].v.v_integer );	// 2b|!2b==?
    value.wMonth  = static_cast< WORD >( m_poVirtualChip->m_psStackPointer[ 4 ].v.v_integer );	// 2b|!2b==?
    value.wDay    = static_cast< WORD >( m_poVirtualChip->m_psStackPointer[ 3 ].v.v_integer );	// 2b|!2b==?
    value.wHour   = static_cast< WORD >( m_poVirtualChip->m_psStackPointer[ 2 ].v.v_integer );	// 2b|!2b==?
    value.wMinute = static_cast< WORD >( m_poVirtualChip->m_psStackPointer[ 1 ].v.v_integer );	// 2b|!2b==?
    value.wSecond = static_cast< WORD >( m_poVirtualChip->m_psStackPointer[ 0 ].v.v_integer );	// 2b|!2b==?
  }
  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], value ); 

  m_poVirtualChip->m_psStackPointer += iArgc;

  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerNewDateTime"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerNewHandle

       DESCRIPTION:  allocate a new long

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerNewHandle( int iArgc )
{
  m_poInterpreter->SetLastCall( "Handle" );

  HANDLE value;
  VerifyRunLineArguments( iArgc, 1 );

  if ( iArgc == 1 )
  {
    if ( m_poVirtualChip->m_psStackPointer[0].v_type == DT_HANDLE )
    {
      value = m_poVirtualChip->m_psStackPointer[0].v.v_handle;
    }
    else
    if ( m_poVirtualChip->m_psStackPointer[0].v_type == DT_INTEGER )
    {
      value = (HANDLE)m_poVirtualChip->m_psStackPointer[0].v.v_integer;
    }
  }
  else
  {
    value = 0;
  }
  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], value ); 

  m_poVirtualChip->m_psStackPointer += iArgc;

  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerNewHandle"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerNewLong

       DESCRIPTION:  allocate a new long

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerNewLong( int iArgc )
{
  m_poInterpreter->SetLastCall( "Long" );

  long value;
  VerifyRunLineArguments( iArgc, 1 );

  if ( iArgc == 1 )
  {
    VerifyElementType( 0, DT_INTEGER );
    value   = m_poVirtualChip->m_psStackPointer[0].v.v_integer;
  }
  else
  {
    value = 0;
  }
  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], value ); 

  m_poVirtualChip->m_psStackPointer += iArgc;

  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerNewLong"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerNewColor

       DESCRIPTION:  allocate a new long

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerNewColor( int iArgc )
{
  m_poInterpreter->SetLastCall( "Color" );

  if ( iArgc == 0 )
  {
    m_poVirtualChip->m_psStackPointer[ iArgc ].v.v_color = RGB( 255, 255, 255 );
    m_poVirtualChip->m_psStackPointer[ iArgc ].v_type    = DT_COLOR;
    ++m_poVirtualChip->m_psStackPointer;
  }
  else
  if ( iArgc == 1 )
  {
    if ( m_poVirtualChip->m_psStackPointer[ 0 ].v_type == DT_COLOR )
    {
      m_poVirtualChip->m_psStackPointer[ iArgc ].v.v_color = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_color;
      m_poVirtualChip->m_psStackPointer[ iArgc ].v_type    = DT_COLOR;
      m_poVirtualChip->m_psStackPointer += iArgc;
    }
    else
    if ( m_poVirtualChip->m_psStackPointer[ 0 ].v_type == DT_STRING )
    {
      const char* pchColor = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_string->str_data;

      if ( 0 == strcmp( pchColor, "COLOR_3DDKSHADOW" ) )
      {
        m_poVirtualChip->m_psStackPointer[ iArgc ].v.v_color = GetSysColor( COLOR_3DDKSHADOW );
        m_poVirtualChip->m_psStackPointer[ iArgc ].v_type    = DT_COLOR;
        m_poVirtualChip->m_psStackPointer += iArgc;
      }
      else
      if ( 0 == strcmp( pchColor, "COLOR_3DFACE" ) )
      {
        m_poVirtualChip->m_psStackPointer[ iArgc ].v.v_color = GetSysColor( COLOR_3DFACE );
        m_poVirtualChip->m_psStackPointer[ iArgc ].v_type    = DT_COLOR;
        m_poVirtualChip->m_psStackPointer += iArgc;
      }
      else
      if ( 0 == strcmp( pchColor, "COLOR_BTNFACE" ) )
      {
        m_poVirtualChip->m_psStackPointer[ iArgc ].v.v_color = GetSysColor( COLOR_BTNFACE );
        m_poVirtualChip->m_psStackPointer[ iArgc ].v_type    = DT_COLOR;
        m_poVirtualChip->m_psStackPointer += iArgc;
      }
      else
      if ( 0 == strcmp( pchColor, "COLOR_3DHILIGHT" ) )
      {
        m_poVirtualChip->m_psStackPointer[ iArgc ].v.v_color = GetSysColor( COLOR_3DHILIGHT );
        m_poVirtualChip->m_psStackPointer[ iArgc ].v_type    = DT_COLOR;
        m_poVirtualChip->m_psStackPointer += iArgc;
      }
      else
      if ( 0 == strcmp( pchColor, "COLOR_3DHIGHLIGHT" ) )
      {
        m_poVirtualChip->m_psStackPointer[ iArgc ].v.v_color = GetSysColor( COLOR_3DHIGHLIGHT );
        m_poVirtualChip->m_psStackPointer[ iArgc ].v_type    = DT_COLOR;
        m_poVirtualChip->m_psStackPointer += iArgc;
      }
      else
      if ( 0 == strcmp( pchColor, "COLOR_BTNHILIGHT" ) )
      {
        m_poVirtualChip->m_psStackPointer[ iArgc ].v.v_color = GetSysColor( COLOR_BTNHILIGHT );
        m_poVirtualChip->m_psStackPointer[ iArgc ].v_type    = DT_COLOR;
        m_poVirtualChip->m_psStackPointer += iArgc;
      }
      else
      if ( 0 == strcmp( pchColor, "COLOR_BTNHIGHLIGHT" ) )
      {
        m_poVirtualChip->m_psStackPointer[ iArgc ].v.v_color = GetSysColor( COLOR_BTNHIGHLIGHT );
        m_poVirtualChip->m_psStackPointer[ iArgc ].v_type    = DT_COLOR;
        m_poVirtualChip->m_psStackPointer += iArgc;
      }
      else
      if ( 0 == strcmp( pchColor, "COLOR_3DLIGHT" ) )
      {
        m_poVirtualChip->m_psStackPointer[ iArgc ].v.v_color = GetSysColor( COLOR_3DLIGHT );
        m_poVirtualChip->m_psStackPointer[ iArgc ].v_type    = DT_COLOR;
        m_poVirtualChip->m_psStackPointer += iArgc;
      }
      else
      if ( 0 == strcmp( pchColor, "COLOR_3DSHADOW" ) )
      {
        m_poVirtualChip->m_psStackPointer[ iArgc ].v.v_color = GetSysColor( COLOR_3DSHADOW );
        m_poVirtualChip->m_psStackPointer[ iArgc ].v_type    = DT_COLOR;
        m_poVirtualChip->m_psStackPointer += iArgc;
      }
      else
      if ( 0 == strcmp( pchColor, "COLOR_BTNSHADOW" ) )
      {
        m_poVirtualChip->m_psStackPointer[ iArgc ].v.v_color = GetSysColor( COLOR_BTNSHADOW );
        m_poVirtualChip->m_psStackPointer[ iArgc ].v_type    = DT_COLOR;
        m_poVirtualChip->m_psStackPointer += iArgc;
      }
      else
      if ( 0 == strcmp( pchColor, "COLOR_ACTIVEBORDER" ) )
      {
        m_poVirtualChip->m_psStackPointer[ iArgc ].v.v_color = GetSysColor( COLOR_ACTIVEBORDER );
        m_poVirtualChip->m_psStackPointer[ iArgc ].v_type    = DT_COLOR;
        m_poVirtualChip->m_psStackPointer += iArgc;
      }
      else
      if ( 0 == strcmp( pchColor, "COLOR_ACTIVECAPTION" ) )
      {
        m_poVirtualChip->m_psStackPointer[ iArgc ].v.v_color = GetSysColor( COLOR_ACTIVECAPTION );
        m_poVirtualChip->m_psStackPointer[ iArgc ].v_type    = DT_COLOR;
        m_poVirtualChip->m_psStackPointer += iArgc;
      }
      else
      if ( 0 == strcmp( pchColor, "COLOR_APPWORKSPACE" ) )
      {
        m_poVirtualChip->m_psStackPointer[ iArgc ].v.v_color = GetSysColor( COLOR_APPWORKSPACE );
        m_poVirtualChip->m_psStackPointer[ iArgc ].v_type    = DT_COLOR;
        m_poVirtualChip->m_psStackPointer += iArgc;
      }
      else
      if ( 0 == strcmp( pchColor, "COLOR_BACKGROUND" ) )
      {
        m_poVirtualChip->m_psStackPointer[ iArgc ].v.v_color = GetSysColor( COLOR_BACKGROUND );
        m_poVirtualChip->m_psStackPointer[ iArgc ].v_type    = DT_COLOR;
        m_poVirtualChip->m_psStackPointer += iArgc;
      }
      else
      if ( 0 == strcmp( pchColor, "COLOR_DESKTOP" ) )
      {
        m_poVirtualChip->m_psStackPointer[ iArgc ].v.v_color = GetSysColor( COLOR_DESKTOP );
        m_poVirtualChip->m_psStackPointer[ iArgc ].v_type    = DT_COLOR;
        m_poVirtualChip->m_psStackPointer += iArgc;
      }
      else
      if ( 0 == strcmp( pchColor, "COLOR_BTNTEXT" ) )
      {
        m_poVirtualChip->m_psStackPointer[ iArgc ].v.v_color = GetSysColor( COLOR_BTNTEXT );
        m_poVirtualChip->m_psStackPointer[ iArgc ].v_type    = DT_COLOR;
        m_poVirtualChip->m_psStackPointer += iArgc;
      }
      else
      if ( 0 == strcmp( pchColor, "COLOR_CAPTIONTEXT" ) )
      {
        m_poVirtualChip->m_psStackPointer[ iArgc ].v.v_color = GetSysColor( COLOR_CAPTIONTEXT );
        m_poVirtualChip->m_psStackPointer[ iArgc ].v_type    = DT_COLOR;
        m_poVirtualChip->m_psStackPointer += iArgc;
      }
      else
      if ( 0 == strcmp( pchColor, "COLOR_GRADIENTACTIVECAPTION" ) )
      {
//        m_poVirtualChip->m_psStackPointer[ iArgc ].v.v_color = GetSysColor( COLOR_GRADIENTACTIVECAPTION );
        m_poVirtualChip->m_psStackPointer[ iArgc ].v_type    = DT_COLOR;
        m_poVirtualChip->m_psStackPointer += iArgc;
      }
      else
      if ( 0 == strcmp( pchColor, "COLOR_GRADIENTINACTIVECAPTION" ) )
      {
//        m_poVirtualChip->m_psStackPointer[ iArgc ].v.v_color = GetSysColor( COLOR_GRADIENTINACTIVECAPTION );
        m_poVirtualChip->m_psStackPointer[ iArgc ].v_type    = DT_COLOR;
        m_poVirtualChip->m_psStackPointer += iArgc;
      }
      else
      if ( 0 == strcmp( pchColor, "COLOR_GRAYTEXT" ) )
      {
        m_poVirtualChip->m_psStackPointer[ iArgc ].v.v_color = GetSysColor( COLOR_GRAYTEXT );
        m_poVirtualChip->m_psStackPointer[ iArgc ].v_type    = DT_COLOR;
        m_poVirtualChip->m_psStackPointer += iArgc;
      }
      else
      if ( 0 == strcmp( pchColor, "COLOR_HIGHLIGHT" ) )
      {
        m_poVirtualChip->m_psStackPointer[ iArgc ].v.v_color = GetSysColor( COLOR_HIGHLIGHT );
        m_poVirtualChip->m_psStackPointer[ iArgc ].v_type    = DT_COLOR;
        m_poVirtualChip->m_psStackPointer += iArgc;
      }
      else
      if ( 0 == strcmp( pchColor, "COLOR_HIGHLIGHTTEXT" ) )
      {
        m_poVirtualChip->m_psStackPointer[ iArgc ].v.v_color = GetSysColor( COLOR_HIGHLIGHTTEXT );
        m_poVirtualChip->m_psStackPointer[ iArgc ].v_type    = DT_COLOR;
        m_poVirtualChip->m_psStackPointer += iArgc;
      }
      else
      if ( 0 == strcmp( pchColor, "COLOR_HOTLIGHT" ) )
      {
//        m_poVirtualChip->m_psStackPointer[ iArgc ].v.v_color = GetSysColor( COLOR_HOTLIGHT );
        m_poVirtualChip->m_psStackPointer[ iArgc ].v_type    = DT_COLOR;
        m_poVirtualChip->m_psStackPointer += iArgc;
      }
      else
      if ( 0 == strcmp( pchColor, "COLOR_INACTIVEBORDER" ) )
      {
        m_poVirtualChip->m_psStackPointer[ iArgc ].v.v_color = GetSysColor( COLOR_INACTIVEBORDER );
        m_poVirtualChip->m_psStackPointer[ iArgc ].v_type    = DT_COLOR;
        m_poVirtualChip->m_psStackPointer += iArgc;
      }
      else
      if ( 0 == strcmp( pchColor, "COLOR_INACTIVECAPTION" ) )
      {
        m_poVirtualChip->m_psStackPointer[ iArgc ].v.v_color = GetSysColor( COLOR_INACTIVECAPTION );
        m_poVirtualChip->m_psStackPointer[ iArgc ].v_type    = DT_COLOR;
        m_poVirtualChip->m_psStackPointer += iArgc;
      }
      else
      if ( 0 == strcmp( pchColor, "COLOR_INACTIVECAPTIONTEXT" ) )
      {
        m_poVirtualChip->m_psStackPointer[ iArgc ].v.v_color = GetSysColor( COLOR_INACTIVECAPTIONTEXT );
        m_poVirtualChip->m_psStackPointer[ iArgc ].v_type    = DT_COLOR;
        m_poVirtualChip->m_psStackPointer += iArgc;
      }
      else
      if ( 0 == strcmp( pchColor, "COLOR_INFOBK" ) )
      {
        m_poVirtualChip->m_psStackPointer[ iArgc ].v.v_color = GetSysColor( COLOR_INFOBK );
        m_poVirtualChip->m_psStackPointer[ iArgc ].v_type    = DT_COLOR;
        m_poVirtualChip->m_psStackPointer += iArgc;
      }
      else
      if ( 0 == strcmp( pchColor, "COLOR_INFOTEXT" ) )
      {
        m_poVirtualChip->m_psStackPointer[ iArgc ].v.v_color = GetSysColor( COLOR_INFOTEXT );
        m_poVirtualChip->m_psStackPointer[ iArgc ].v_type    = DT_COLOR;
        m_poVirtualChip->m_psStackPointer += iArgc;
      }
      else
      if ( 0 == strcmp( pchColor, "COLOR_MENU" ) )
      {
        m_poVirtualChip->m_psStackPointer[ iArgc ].v.v_color = GetSysColor( COLOR_MENU );
        m_poVirtualChip->m_psStackPointer[ iArgc ].v_type    = DT_COLOR;
        m_poVirtualChip->m_psStackPointer += iArgc;
      }
      else
      if ( 0 == strcmp( pchColor, "COLOR_MENUHILIGHT" ) )
      {
//        m_poVirtualChip->m_psStackPointer[ iArgc ].v.v_color = GetSysColor( COLOR_MENUHILIGHT );
        m_poVirtualChip->m_psStackPointer[ iArgc ].v_type    = DT_COLOR;
        m_poVirtualChip->m_psStackPointer += iArgc;
      }
      else
      if ( 0 == strcmp( pchColor, "COLOR_MENUBAR" ) )
      {
//        m_poVirtualChip->m_psStackPointer[ iArgc ].v.v_color = GetSysColor( COLOR_MENUBAR );
        m_poVirtualChip->m_psStackPointer[ iArgc ].v_type    = DT_COLOR;
        m_poVirtualChip->m_psStackPointer += iArgc;
      }
      else
      if ( 0 == strcmp( pchColor, "COLOR_MENUTEXT" ) )
      {
        m_poVirtualChip->m_psStackPointer[ iArgc ].v.v_color = GetSysColor( COLOR_MENUTEXT );
        m_poVirtualChip->m_psStackPointer[ iArgc ].v_type    = DT_COLOR;
        m_poVirtualChip->m_psStackPointer += iArgc;
      }
      else
      if ( 0 == strcmp( pchColor, "COLOR_SCROLLBAR" ) )
      {
        m_poVirtualChip->m_psStackPointer[ iArgc ].v.v_color = GetSysColor( COLOR_SCROLLBAR );
        m_poVirtualChip->m_psStackPointer[ iArgc ].v_type    = DT_COLOR;
        m_poVirtualChip->m_psStackPointer += iArgc;
      }
      else
      if ( 0 == strcmp( pchColor, "COLOR_WINDOW" ) )
      {
        m_poVirtualChip->m_psStackPointer[ iArgc ].v.v_color = GetSysColor( COLOR_WINDOW );
        m_poVirtualChip->m_psStackPointer[ iArgc ].v_type    = DT_COLOR;
        m_poVirtualChip->m_psStackPointer += iArgc;
      }
      else
      if ( 0 == strcmp( pchColor, "COLOR_WINDOWFRAME" ) )
      {
        m_poVirtualChip->m_psStackPointer[ iArgc ].v.v_color = GetSysColor( COLOR_WINDOWFRAME );
        m_poVirtualChip->m_psStackPointer[ iArgc ].v_type    = DT_COLOR;
        m_poVirtualChip->m_psStackPointer += iArgc;
      }
      else
      if ( 0 == strcmp( pchColor, "COLOR_WINDOWTEXT" ) )
      {
        m_poVirtualChip->m_psStackPointer[ iArgc ].v.v_color = GetSysColor( COLOR_WINDOWTEXT );
        m_poVirtualChip->m_psStackPointer[ iArgc ].v_type    = DT_COLOR;
        m_poVirtualChip->m_psStackPointer += iArgc;
      }
      else
      {
        m_poVirtualChip->m_psStackPointer[ iArgc ].v.v_color = RGB( 0, 0, 0 );
        m_poVirtualChip->m_psStackPointer[ iArgc ].v_type    = DT_COLOR;
        m_poVirtualChip->m_psStackPointer += iArgc;
      }
    }
    else
    {
      m_poVirtualChip->m_psStackPointer[ iArgc ].v.v_color = RGB( 0, 0, 0 );
      m_poVirtualChip->m_psStackPointer[ iArgc ].v_type    = DT_COLOR;
      m_poVirtualChip->m_psStackPointer += iArgc;
    }
  }
  else
  if ( iArgc == 3 )
  {
    VerifyElementType( 0, DT_INTEGER );
    VerifyElementType( 1, DT_INTEGER );
    VerifyElementType( 2, DT_INTEGER );

    m_poVirtualChip->m_psStackPointer[ iArgc ].v.v_color = RGB( m_poVirtualChip->m_psStackPointer[ 2 ].v.v_color,
                                                                m_poVirtualChip->m_psStackPointer[ 1 ].v.v_color,
                                                                m_poVirtualChip->m_psStackPointer[ 0 ].v.v_color );
    m_poVirtualChip->m_psStackPointer[ iArgc ].v_type    = DT_COLOR;
    m_poVirtualChip->m_psStackPointer += iArgc;
  }
  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerNewColor"
/*****************************************************************************/


/*****************************************************************************/
/*

     FUNCTION NAME:  VMVirtualOpSys::HandlerNewDBConnection

       DESCRIPTION:  creates a new odbc object 

             INPUT:  iArgc - the number of arguments passed to the call
            OUTPUT:  none

           RETURNS:  zero 
*/
int VMVirtualOpSys::HandlerNewDBConnection( int iArgc )
{
  m_poInterpreter->SetLastCall( "Database" );

  VerifyRunLineArguments( iArgc, 0 );

  VMTrackedAllocs* poAlloc = new VMTrackedAllocs;
  poAlloc->v.v_odbc        = new VMODBC;
  poAlloc->v_type          = DT_ODBC;
  m_oTrackedAllocs.push_back( poAlloc );

  set_odbc( &m_poVirtualChip->m_psStackPointer[iArgc], 
            poAlloc->v.v_odbc ); 
  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerNewDBConnection"
/*****************************************************************************/


/*****************************************************************************/
/*

     FUNCTION NAME:  VMVirtualOpSys::HandlerNewCalculator

       DESCRIPTION:  creates a new calculator / equation solving object 

             INPUT:  iArgc - the number of arguments passed to the call
            OUTPUT:  none

           RETURNS:  zero 
*/
int VMVirtualOpSys::HandlerNewCalculator( int iArgc )
{
  m_poInterpreter->SetLastCall( "Calculator" );

  VerifyRunLineArguments( iArgc, 0 );

  VMTrackedAllocs* poAlloc = new VMTrackedAllocs;
  poAlloc->v.v_calculator  = new VMCalculator;
  poAlloc->v_type          = DT_CALCULATOR;
  m_oTrackedAllocs.push_back( poAlloc );

  set_calculator( &m_poVirtualChip->m_psStackPointer[iArgc], 
                  poAlloc->v.v_calculator );
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerNewCalculator"
/*****************************************************************************/


/*****************************************************************************/
/*

     FUNCTION NAME:  VMVirtualOpSys::HandlerNewNullValue

       DESCRIPTION:  creates a new calculator / equation solving object 

             INPUT:  iArgc - the number of arguments passed to the call
            OUTPUT:  none

           RETURNS:  zero 
*/
int VMVirtualOpSys::HandlerNewNullValue( int iArgc )
{
  m_poInterpreter->SetLastCall( "Calculator" );

  VerifyRunLineArguments( iArgc, 0 );
  set_nil( &m_poVirtualChip->m_psStackPointer[iArgc] );

  return 0;
}
/* End of function "VMVirtualOpSys::HandlerNewNullValue"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerNewSqlLite2Database

       DESCRIPTION:  allocate a mini (sql lite) dataabase

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerNewSqlLite2Database( int iArgc )
{
  m_poInterpreter->SetLastCall( "SqlLite2Database" );

  VMSqlLiteDatabase* poMiniDB = NULL;
  char*              pchFile  = NULL;

  if ( iArgc == 1 )
  {
    VerifyElementType( 0, DT_STRING );
  
    pchFile = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_string->str_data;
  }
  else
  if ( iArgc != 0 )
  {
    VerifyRunLineArguments( iArgc, 1 );
  }

  poMiniDB = new VMSqlLiteDatabase( pchFile );

  // all heap based variables are tracked separately in an allocation tracker
  // 
  // the work below is how that is accomplished. All heap based variable types
  // are tracked the same way, so you will see similar code in many other 
  // object allocation routines in this file.
  //
  VMTrackedAllocs* poAlloc = new VMTrackedAllocs;
  poAlloc->v.v_sqllite2db   = poMiniDB;
  poAlloc->v_type          = DT_SQLLITE_2_DB;
  m_oTrackedAllocs.push_back( poAlloc );

  set_sqllite2db( &m_poVirtualChip->m_psStackPointer[ iArgc ], poMiniDB );
  m_poVirtualChip->m_psStackPointer += iArgc;

  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerNewSqlLite2Database"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerNewUnZipper

       DESCRIPTION:  allocate a mini (sql lite) dataabase

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerNewUnZipper( int iArgc )
{
  m_poInterpreter->SetLastCall( "UnZipper" );

  VerifyRunLineArguments( iArgc, 0 );

  VMUnzipper* poZip = new VMUnzipper;

  // all heap based variables are tracked separately in an allocation tracker
  // 
  // the work below is how that is accomplished. All heap based variable types
  // are tracked the same way, so you will see similar code in many other 
  // object allocation routines in this file.
  //
  VMTrackedAllocs* poAlloc = new VMTrackedAllocs;
  poAlloc->v.v_unzipper    = poZip;
  poAlloc->v_type          = DT_UNZIPPER;
  m_oTrackedAllocs.push_back( poAlloc );

  set_unzipper( &m_poVirtualChip->m_psStackPointer[ iArgc ], poZip );

  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerNewUnZipper"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerNewZipMaker

       DESCRIPTION:  allocate a mini (sql lite) dataabase

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerNewZipMaker( int iArgc )
{
  m_poInterpreter->SetLastCall( "ZipMaker" );

  VerifyRunLineArguments( iArgc, 0 );

  VMZipper* poZip = new VMZipper;

  // all heap based variables are tracked separately in an allocation tracker
  // 
  // the work below is how that is accomplished. All heap based variable types
  // are tracked the same way, so you will see similar code in many other 
  // object allocation routines in this file.
  //
  VMTrackedAllocs* poAlloc = new VMTrackedAllocs;
  poAlloc->v.v_zipmaker    = poZip;
  poAlloc->v_type          = DT_ZIPMAKER;
  m_oTrackedAllocs.push_back( poAlloc );

  set_zipmaker( &m_poVirtualChip->m_psStackPointer[ iArgc ], poZip );

  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerNewZipMaker"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerNewFileBuilder

       DESCRIPTION:  allocate a string file builder object

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerNewFileBuilder( int iArgc )
{
  m_poInterpreter->SetLastCall( "FileBuilder" );

  VerifyRunLineArguments( iArgc, 0 );

  VMStringFileBuilder* poObj = new VMStringFileBuilder;

  // all heap based variables are tracked separately in an allocation tracker
  // 
  // the work below is how that is accomplished. All heap based variable types
  // are tracked the same way, so you will see similar code in many other 
  // object allocation routines in this file.
  //
  VMTrackedAllocs* poAlloc = new VMTrackedAllocs;
  poAlloc->v.v_filebuilder = poObj;
  poAlloc->v_type          = DT_FILE_BUILDER;
  m_oTrackedAllocs.push_back( poAlloc );

  set_filebuilder( &m_poVirtualChip->m_psStackPointer[ iArgc ], poObj );

  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerNewFileBuilder"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerNewDelimitedFile

       DESCRIPTION:  allocate a delimited file wrapper

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerNewDelimitedFile( int iArgc )
{
  m_poInterpreter->SetLastCall( "DelimitedFile" );

  VerifyRunLineArguments( iArgc, 0 );

  VMFileParser* poObj = new VMFileParser( RF_READ_AS_STRING | RF_APPEND_DATA );

  // all heap based variables are tracked separately in an allocation tracker
  // 
  // the work below is how that is accomplished. All heap based variable types
  // are tracked the same way, so you will see similar code in many other 
  // object allocation routines in this file.
  //
  VMTrackedAllocs* poAlloc   = new VMTrackedAllocs;
  poAlloc->v.v_delimitedfile = poObj;
  poAlloc->v_type            = DT_DELIMITED_FILE;
  m_oTrackedAllocs.push_back( poAlloc );

  set_delimitedfile( &m_poVirtualChip->m_psStackPointer[ iArgc ], poObj );

  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerNewDelimitedFile"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerNewExcelExporter

       DESCRIPTION:  allocate a delimited file wrapper

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerNewExcelExporter( int iArgc )
{
  m_poInterpreter->SetLastCall( "ExcelExporter" );

  VerifyRunLineArguments( iArgc, 0 );

  VMExcelExporter* poObj = new VMExcelExporter();

  // all heap based variables are tracked separately in an allocation tracker
  // 
  // the work below is how that is accomplished. All heap based variable types
  // are tracked the same way, so you will see similar code in many other 
  // object allocation routines in this file.
  //
  VMTrackedAllocs* poAlloc   = new VMTrackedAllocs;
  poAlloc->v.v_excelwriter   = poObj;
  poAlloc->v_type            = DT_EXCEL_EXPORTER;
  m_oTrackedAllocs.push_back( poAlloc );

  set_excelwriter( &m_poVirtualChip->m_psStackPointer[ iArgc ], poObj );

  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerNewExcelExporter"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerNewDWord

       DESCRIPTION:  allocate a new DWORD

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerNewDWord( int iArgc )
{
  m_poInterpreter->SetLastCall( "DWORD" );

  DWORD value;
  VerifyRunLineArguments( iArgc, 1 );

  if ( iArgc == 1 )
  {
    if ( m_poVirtualChip->m_psStackPointer[0].v_type == DT_DWORD )
    {
      value = m_poVirtualChip->m_psStackPointer[0].v.v_dword;
    }
    else
    if ( m_poVirtualChip->m_psStackPointer[0].v_type == DT_INTEGER )
    {
      value = (DWORD)m_poVirtualChip->m_psStackPointer[0].v.v_integer;
    }
  }
  else
  {
    value = 0;
  }
  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], value ); 

  m_poVirtualChip->m_psStackPointer += iArgc;

  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerNewDWord"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerNewDouble

       DESCRIPTION:  allocate a new double

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerNewDouble( int iArgc )
{
  m_poInterpreter->SetLastCall( "Double" );

  double value;
  VerifyRunLineArguments( iArgc, 1 );

  if ( iArgc == 1 )
  {
    if ( m_poVirtualChip->m_psStackPointer[0].v_type == DT_DOUBLE )
    {
      value = m_poVirtualChip->m_psStackPointer[0].v.v_double;
    }
    else
    if ( m_poVirtualChip->m_psStackPointer[0].v_type == DT_INTEGER )
    {
      value = (double)m_poVirtualChip->m_psStackPointer[0].v.v_integer;
    }
    else
    if ( m_poVirtualChip->m_psStackPointer[0].v_type == DT_STRING )
    {
      value = atof( m_poVirtualChip->m_psStackPointer[0].v.v_string->str_data );
    }
  }
  else
  {
    value = 0;
  }
  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], value ); 

  m_poVirtualChip->m_psStackPointer += iArgc;

  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerNewDouble"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerNewByte

       DESCRIPTION:  allocate a new double

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerNewByte( int iArgc )
{
  m_poInterpreter->SetLastCall( "Byte" );

  unsigned char value;
  VerifyRunLineArguments( iArgc, 1 );

  if ( iArgc == 1 )
  {
    if ( m_poVirtualChip->m_psStackPointer[0].v_type == DT_BYTE )
    {
      value = m_poVirtualChip->m_psStackPointer[0].v.v_byte;
    }
    else
    if ( m_poVirtualChip->m_psStackPointer[0].v_type == DT_INTEGER )
    {
      value = (unsigned char)m_poVirtualChip->m_psStackPointer[0].v.v_integer;
    }
  }
  else
  {
    value = 0;
  }
  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], value ); 

  m_poVirtualChip->m_psStackPointer += iArgc;
  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerNewByte"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerNewString

       DESCRIPTION:  allocate a new string

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerNewString( int iArgc )
{
  m_poInterpreter->SetLastCall( "String" );

  int size;
  VerifyRunLineArguments( iArgc, 1 );
   
  if ( m_poVirtualChip->m_psStackPointer[0].v_type == DT_INTEGER )
  {
    size = m_poVirtualChip->m_psStackPointer[0].v.v_integer;
    SetValue( &m_poVirtualChip->m_psStackPointer[1], AllocateNewString( size, true ) );
    m_poVirtualChip->m_psStackPointer++;
  }
  else
  if ( m_poVirtualChip->m_psStackPointer[0].v_type == DT_STRING )
  {
    char* pchInit = m_poVirtualChip->m_psStackPointer[0].v.v_string->str_data;
    size = strlen( pchInit );
    vmstring* pResult = AllocateNewString( size + 1, true );
    strcpy( pResult->str_data, pchInit );
    SetValue( &m_poVirtualChip->m_psStackPointer[1], pResult );
    m_poVirtualChip->m_psStackPointer++;
  }
  
  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerNewString"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerNewQueue

       DESCRIPTION:  allocate a new string

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerNewQueue( int iArgc )
{
  m_poInterpreter->SetLastCall( "Queue" );

  VerifyRunLineArguments( iArgc, 0 );

  VMTrackedAllocs* poAlloc = new VMTrackedAllocs;
  poAlloc->v.v_queue       = new VMDataQueue;
  poAlloc->v_type          = DT_QUEUE;
  m_oTrackedAllocs.push_back( poAlloc );

  set_queue( &m_poVirtualChip->m_psStackPointer[ iArgc ], poAlloc->v.v_queue );

  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerNewQueue"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerNewStack

       DESCRIPTION:  allocate a new string

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerNewStack( int iArgc )
{
  m_poInterpreter->SetLastCall( "Stack" );

  VerifyRunLineArguments( iArgc, 0 );

  VMTrackedAllocs* poAlloc = new VMTrackedAllocs;
  poAlloc->v.v_stack       = new VMDataStack;
  poAlloc->v_type          = DT_STACK;
  m_oTrackedAllocs.push_back( poAlloc );

  set_stack( &m_poVirtualChip->m_psStackPointer[ iArgc ], poAlloc->v.v_stack );

  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerNewStack"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerNewHashTable

       DESCRIPTION:  allocate a new string

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerNewHashTable( int iArgc )
{
  m_poInterpreter->SetLastCall( "Map" );

  VerifyRunLineArguments( iArgc, 0 );

  VMTrackedAllocs* poAlloc = new VMTrackedAllocs;
  poAlloc->v.v_hashtable   = new VMHashTable;
  poAlloc->v_type          = DT_HASHTABLE;
  m_oTrackedAllocs.push_back( poAlloc );

  set_hashtable( &m_poVirtualChip->m_psStackPointer[ iArgc ], poAlloc->v.v_hashtable );

  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerNewHashTable"
/*****************************************************************************/


/*****************************************************************************/
/*

     FUNCTION NAME:  VMVirtualOpSys::HandlerNewPage

       DESCRIPTION:  creates a report page context. also confirms runtime env
                     is correct for report scripts

             INPUT:  iArgc - count of script params passed to this
            OUTPUT:  none

           RETURNS:  zero
*/
int VMVirtualOpSys::HandlerNewPage( int iArgc )
{
  m_poInterpreter->SetLastCall( "Page" );

  VerifyRunLineArguments( iArgc, 0 );

  if ( NULL == m_poPageInitInfo )
  {
    // treat a missing page context as a fatal error
    //
    char achMsg[255];
    sprintf( achMsg, "HandlerNewPage Did Not Find Page Creation Parameters." );

    VMException* pThrow = new VMException(  __FILE__, __LINE__, achMsg );
    throw pThrow;
  }
 
  VMPage* poPage = new VMPage( m_poPageInitInfo->m_xPageRect, 
                               m_poPageInitInfo->m_poPageCDC,
                               m_poPageInitInfo->m_iMappingMode,
                               m_poPageInitInfo->m_dblZoomFactor );

  VMTrackedAllocs* poAlloc = new VMTrackedAllocs;
  poAlloc->v.v_page        = poPage;
  poAlloc->v_type          = DT_REPORTPAGE;
  m_oTrackedAllocs.push_back( poAlloc );

  set_page( &m_poVirtualChip->m_psStackPointer[ iArgc ], poAlloc->v.v_page );

  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerNewPage"
/*****************************************************************************/


/*****************************************************************************/
/*

     FUNCTION NAME:  VMVirtualOpSys::HandlerNewTable

       DESCRIPTION:  creates a data table context in a report page

             INPUT:  iArgc - count of script params passed to this
            OUTPUT:  none

           RETURNS:  zero
*/
int VMVirtualOpSys::HandlerNewTable( int iArgc )
{
  m_poInterpreter->SetLastCall( "Table" );

  VerifyRunLineArguments( iArgc, 0 );

  TABLEHEADER* pxTable = new TABLEHEADER;
  pxTable->AutoSize    = FALSE;
  pxTable->Border      = TRUE;
  pxTable->FillFlag    = FILL_NONE;
  pxTable->UseInches   = TRUE;
  pxTable->LineSize    = 1;
  pxTable->PointSize   = 10;

  VMTrackedAllocs* poAlloc = new VMTrackedAllocs;
  poAlloc->v.v_pagetable   = pxTable;
  poAlloc->v_type          = DT_REPORTTABLE;
  m_oTrackedAllocs.push_back( poAlloc );

  set_pagetable( &m_poVirtualChip->m_psStackPointer[ iArgc ], poAlloc->v.v_pagetable );

  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerNewTable"
/*****************************************************************************/

/*****************************************************************************/
/*

     FUNCTION NAME:  VMVirtualOpSys::HandlerNewSqlLite3Database

       DESCRIPTION:  creates an sqlite 3 database connection object

             INPUT:  iArgc - count of script params passed to this
            OUTPUT:  none

           RETURNS:  zero
*/
int VMVirtualOpSys::HandlerNewSqlLite3Database( int iArgc )
{
  m_poInterpreter->SetLastCall( "SqlLite3Database" );

  VerifyRunLineArguments( iArgc, 0 );

  VMSqlite3xDatabase* poDatabase = new VMSqlite3xDatabase;

  VMTrackedAllocs* poAlloc = new VMTrackedAllocs;
  poAlloc->v.v_sqllite3db  = poDatabase;
  poAlloc->v_type          = DT_SQLLITE_3_DB;
  m_oTrackedAllocs.push_back( poAlloc );

  set_sqllite3db( &m_poVirtualChip->m_psStackPointer[ iArgc ], poAlloc->v.v_sqllite3db );

  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerNewSqlLite3Database"
/*****************************************************************************/


/*****************************************************************************/
/*

     FUNCTION NAME:  VMVirtualOpSys::HandlerNewInt64

       DESCRIPTION:  assigns the top of stack to an int64 value of zero

             INPUT:  iArgc - count of script params passed to this
            OUTPUT:  none

           RETURNS:  zero
*/
int VMVirtualOpSys::HandlerNewInt64( int iArgc )
{
  m_poInterpreter->SetLastCall( "Int64" );

  VerifyRunLineArguments( iArgc, 0 );

  set_int64( &m_poVirtualChip->m_psStackPointer[ iArgc ], 0 );

  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerNewInt64"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerFreeObject

       DESCRIPTION:  deletes an object from the heap

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerFreeObject( int iArgc )
{
  m_poInterpreter->SetLastCall( "FreeObject" );

  VerifyRunLineArguments( iArgc, 1 );

  switch ( m_poVirtualChip->m_psStackPointer[0].v_type )
  {
    case DT_EXCEL_EXPORTER:
    {
      VMExcelExporter* poObj = get_excelwriter( m_poVirtualChip->m_psStackPointer );

      // all heap based variable types are tracked in the heap allocation tracking
      // object referenced below. So, when the user specifically destroys one of 
      // these variable types, we remove it from the allocation tracker so that
      // when our 'post program object clean up runs' we don't have to worry about
      // dead objects in the collection
      //
      TRACKED_ALLOCS_ITER oAllocIter;
      for( oAllocIter  = m_oTrackedAllocs.begin();
           oAllocIter != m_oTrackedAllocs.end();
           oAllocIter++ )
      {
        VMTrackedAllocs* poAlloc = (*oAllocIter);
        if ( poAlloc->v_type == m_poVirtualChip->m_psStackPointer[0].v_type )
        {
          if ( poObj == poAlloc->v.v_excelwriter )
          {
             m_oTrackedAllocs.erase( oAllocIter );
             delete poAlloc;
             break;
          }
        }
      }

      delete poObj;
      set_excelwriter( &m_poVirtualChip->m_psStackPointer[0], NULL ); 
      m_poVirtualChip->m_psStackPointer[0].ResetValue( false );
    }
    break;
  
    case DT_DELIMITED_FILE:
    {
      VMFileParser* poObj = get_delimitedfile( m_poVirtualChip->m_psStackPointer );

      TRACKED_ALLOCS_ITER oAllocIter;
      for( oAllocIter  = m_oTrackedAllocs.begin();
           oAllocIter != m_oTrackedAllocs.end();
           oAllocIter++ )
      {
        VMTrackedAllocs* poAlloc = (*oAllocIter);
        if ( poAlloc->v_type == m_poVirtualChip->m_psStackPointer[0].v_type )
        {
          if ( poObj == poAlloc->v.v_delimitedfile )
          {
             m_oTrackedAllocs.erase( oAllocIter );
             delete poAlloc;
             break;
          }
        }
      }

      delete poObj;
      set_filebuilder( &m_poVirtualChip->m_psStackPointer[0], NULL ); 
      m_poVirtualChip->m_psStackPointer[0].ResetValue( false );
    }
    break;
 
    case DT_FILE_BUILDER:
    {
      VMStringFileBuilder* poObj = get_filebuilder( m_poVirtualChip->m_psStackPointer );

      TRACKED_ALLOCS_ITER oAllocIter;
      for( oAllocIter  = m_oTrackedAllocs.begin();
           oAllocIter != m_oTrackedAllocs.end();
           oAllocIter++ )
      {
        VMTrackedAllocs* poAlloc = (*oAllocIter);
        if ( poAlloc->v_type == m_poVirtualChip->m_psStackPointer[0].v_type )
        {
          if ( poObj == poAlloc->v.v_filebuilder )
          {
             m_oTrackedAllocs.erase( oAllocIter );
             delete poAlloc;
             break;
          }
        }
      }

      delete poObj;
      set_filebuilder( &m_poVirtualChip->m_psStackPointer[0], NULL ); 
      m_poVirtualChip->m_psStackPointer[0].ResetValue( false );
    }
    break;

    case DT_SQLLITE_2_ROWSET:
    {
      VMSqlLiteQueryResult * poObj = get_sqllite2rowset( m_poVirtualChip->m_psStackPointer );

      TRACKED_ALLOCS_ITER oAllocIter;
      for( oAllocIter  = m_oTrackedAllocs.begin();
           oAllocIter != m_oTrackedAllocs.end();
           oAllocIter++ )
      {
        VMTrackedAllocs* poAlloc = (*oAllocIter);
        if ( poAlloc->v_type == m_poVirtualChip->m_psStackPointer[0].v_type )
        {
          if ( poObj == poAlloc->v.v_sqllite2rowset )
          {
             m_oTrackedAllocs.erase( oAllocIter );
             delete poAlloc;
             break;
          }
        }
      }

      delete poObj;
      set_sqllite2rowset( &m_poVirtualChip->m_psStackPointer[0], NULL ); 
      m_poVirtualChip->m_psStackPointer[0].ResetValue( false );
    }
    break;

    case DT_SQLLITE_3_ROWSET:
    {
      VMSqlite3xTable * poObj = get_sqllite3rowset( m_poVirtualChip->m_psStackPointer );

      TRACKED_ALLOCS_ITER oAllocIter;
      for( oAllocIter  = m_oTrackedAllocs.begin();
           oAllocIter != m_oTrackedAllocs.end();
           oAllocIter++ )
      {
        VMTrackedAllocs* poAlloc = (*oAllocIter);
        if ( poAlloc->v_type == m_poVirtualChip->m_psStackPointer[0].v_type )
        {
          if ( poObj == poAlloc->v.v_sqllite3rowset )
          {
             m_oTrackedAllocs.erase( oAllocIter );
             delete poAlloc;
             break;
          }
        }
      }

      delete poObj;
      set_sqllite3rowset( &m_poVirtualChip->m_psStackPointer[0], NULL ); 
      m_poVirtualChip->m_psStackPointer[0].ResetValue( false );
    }
    break;

    case DT_UNZIPPER:
    {
      VMUnzipper* poZip = get_unzipper( m_poVirtualChip->m_psStackPointer );

      TRACKED_ALLOCS_ITER oAllocIter;
      for( oAllocIter  = m_oTrackedAllocs.begin();
           oAllocIter != m_oTrackedAllocs.end();
           oAllocIter++ )
      {
        VMTrackedAllocs* poAlloc = (*oAllocIter);
        if ( poAlloc->v_type == m_poVirtualChip->m_psStackPointer[0].v_type )
        {
          if ( poZip == poAlloc->v.v_unzipper )
          {
             m_oTrackedAllocs.erase( oAllocIter );
             delete poAlloc;
             break;
          }
        }
      }

      delete poZip;
      set_unzipper( &m_poVirtualChip->m_psStackPointer[0], NULL ); 
      m_poVirtualChip->m_psStackPointer[0].ResetValue( false );
    }
    break;

    case DT_ZIPMAKER:
    {
      VMZipper* poZip = get_zipmaker( m_poVirtualChip->m_psStackPointer );

      TRACKED_ALLOCS_ITER oAllocIter;
      for( oAllocIter  = m_oTrackedAllocs.begin();
           oAllocIter != m_oTrackedAllocs.end();
           oAllocIter++ )
      {
        VMTrackedAllocs* poAlloc = (*oAllocIter);
        if ( poAlloc->v_type == m_poVirtualChip->m_psStackPointer[0].v_type )
        {
          if ( poZip == poAlloc->v.v_zipmaker )
          {
             m_oTrackedAllocs.erase( oAllocIter );
             delete poAlloc;
             break;
          }
        }
      }

      delete poZip;
      set_zipmaker( &m_poVirtualChip->m_psStackPointer[0], NULL ); 
      m_poVirtualChip->m_psStackPointer[0].ResetValue( false );
    }
    break;

#ifndef TOOL_PUBLIC_BUILD
    case DT_HTTPCLIENT:
    {
      VMHttpClient* poHttp = get_httpclient( m_poVirtualChip->m_psStackPointer );

      TRACKED_ALLOCS_ITER oAllocIter;
      for( oAllocIter  = m_oTrackedAllocs.begin();
           oAllocIter != m_oTrackedAllocs.end();
           oAllocIter++ )
      {
        VMTrackedAllocs* poAlloc = (*oAllocIter);
        if ( poAlloc->v_type == m_poVirtualChip->m_psStackPointer[0].v_type )
        {
          if ( poHttp == poAlloc->v.v_httpclient )
          {
             m_oTrackedAllocs.erase( oAllocIter );
             delete poAlloc;
             break;
          }
        }
      }

      delete poHttp;
      set_httpclient( &m_poVirtualChip->m_psStackPointer[0], NULL ); 
      m_poVirtualChip->m_psStackPointer[0].ResetValue( false );
    }
    break;

    case DT_FTPCLIENT:
    {
      VMSocketFtpClient* poFtp = get_ftpclient( m_poVirtualChip->m_psStackPointer );

      TRACKED_ALLOCS_ITER oAllocIter;
      for( oAllocIter  = m_oTrackedAllocs.begin();
           oAllocIter != m_oTrackedAllocs.end();
           oAllocIter++ )
      {
        VMTrackedAllocs* poAlloc = (*oAllocIter);
        if ( poAlloc->v_type == m_poVirtualChip->m_psStackPointer[0].v_type )
        {
          if ( poFtp == poAlloc->v.v_ftpclient )
          {
             m_oTrackedAllocs.erase( oAllocIter );
             delete poAlloc;
             break;
          }
        }
      }

      delete poFtp;
      set_ftpclient( &m_poVirtualChip->m_psStackPointer[0], NULL ); 
      m_poVirtualChip->m_psStackPointer[0].ResetValue( false );
    }
    break;
#endif

    case DT_SQLLITE_2_DB:
    {
      VMSqlLiteDatabase* poMiniDb = get_sqllit2edb( m_poVirtualChip->m_psStackPointer );

      TRACKED_ALLOCS_ITER oAllocIter;
      for( oAllocIter  = m_oTrackedAllocs.begin();
           oAllocIter != m_oTrackedAllocs.end();
           oAllocIter++ )
      {
        VMTrackedAllocs* poAlloc = (*oAllocIter);
        if ( poAlloc->v_type == m_poVirtualChip->m_psStackPointer[0].v_type )
        {
          if ( poMiniDb == poAlloc->v.v_sqllite2db )
          {
             m_oTrackedAllocs.erase( oAllocIter );
             delete poAlloc;
             break;
          }
        }
      }

      delete poMiniDb;
      set_sqllite2db( &m_poVirtualChip->m_psStackPointer[0], NULL ); 
      m_poVirtualChip->m_psStackPointer[0].ResetValue( false );
    }
    break;

    case DT_SQLLITE_3_DB:
    {
      VMSqlite3xDatabase* poMiniDb = get_sqllit3edb( m_poVirtualChip->m_psStackPointer );

      TRACKED_ALLOCS_ITER oAllocIter;
      for( oAllocIter  = m_oTrackedAllocs.begin();
           oAllocIter != m_oTrackedAllocs.end();
           oAllocIter++ )
      {
        VMTrackedAllocs* poAlloc = (*oAllocIter);
        if ( poAlloc->v_type == m_poVirtualChip->m_psStackPointer[0].v_type )
        {
          if ( poMiniDb == poAlloc->v.v_sqllite3db )
          {
             m_oTrackedAllocs.erase( oAllocIter );
             delete poAlloc;
             break;
          }
        }
      }

      delete poMiniDb;
      set_sqllite3db( &m_poVirtualChip->m_psStackPointer[0], NULL ); 
      m_poVirtualChip->m_psStackPointer[0].ResetValue( false );
    }
    break;

#ifndef TOOL_PUBLIC_BUILD
    case DT_HTMLPARSER:
    {
      VMHtmlParser* poParser = get_htmlparser( m_poVirtualChip->m_psStackPointer );

      TRACKED_ALLOCS_ITER oAllocIter;
      for( oAllocIter  = m_oTrackedAllocs.begin();
           oAllocIter != m_oTrackedAllocs.end();
           oAllocIter++ )
      {
        VMTrackedAllocs* poAlloc = (*oAllocIter);
        if ( poAlloc->v_type == m_poVirtualChip->m_psStackPointer[0].v_type )
        {
          if ( poParser == poAlloc->v.v_htmlparser )
          {
             m_oTrackedAllocs.erase( oAllocIter );
             delete poAlloc;
             break;
          }
        }
      }

      delete poParser;
      set_htmlparser( &m_poVirtualChip->m_psStackPointer[0], NULL ); 
      m_poVirtualChip->m_psStackPointer[0].ResetValue( false );
    }
    break;

    case DT_REGEX:
    {
      VMRegExWrapper* poRegEx = get_regex( m_poVirtualChip->m_psStackPointer );

      TRACKED_ALLOCS_ITER oAllocIter;
      for( oAllocIter  = m_oTrackedAllocs.begin();
           oAllocIter != m_oTrackedAllocs.end();
           oAllocIter++ )
      {
        VMTrackedAllocs* poAlloc = (*oAllocIter);
        if ( poAlloc->v_type == m_poVirtualChip->m_psStackPointer[0].v_type )
        {
          if ( poRegEx == poAlloc->v.v_regex )
          {
             m_oTrackedAllocs.erase( oAllocIter );
             delete poAlloc;
             break;
          }
        }
      }

      delete poRegEx;
      set_regex( &m_poVirtualChip->m_psStackPointer[0], NULL ); 
      m_poVirtualChip->m_psStackPointer[0].ResetValue( false );
    }
    break;

    case DT_THREAD_POOL:
    {
      VMGrowableThreadPool* poPool = get_threadpool( m_poVirtualChip->m_psStackPointer );

      TRACKED_ALLOCS_ITER oAllocIter;
      for( oAllocIter  = m_oTrackedAllocs.begin();
           oAllocIter != m_oTrackedAllocs.end();
           oAllocIter++ )
      {
        VMTrackedAllocs* poAlloc = (*oAllocIter);
        if ( poAlloc->v_type == m_poVirtualChip->m_psStackPointer[0].v_type )
        {
          if ( poPool == poAlloc->v.v_threadpool )
          {
             m_oTrackedAllocs.erase( oAllocIter );
             delete poAlloc;
             break;
          }
        }
      }

      delete poPool;
      set_threadpool( &m_poVirtualChip->m_psStackPointer[0], NULL ); 
      m_poVirtualChip->m_psStackPointer[0].ResetValue( false );
    }
    break;

    case DT_THREAD:
    {
      VMThreadRunnableObject* poThread = get_thread( m_poVirtualChip->m_psStackPointer );

      TRACKED_ALLOCS_ITER oAllocIter;
      for( oAllocIter  = m_oTrackedAllocs.begin();
           oAllocIter != m_oTrackedAllocs.end();
           oAllocIter++ )
      {
        VMTrackedAllocs* poAlloc = (*oAllocIter);
        if ( poAlloc->v_type == m_poVirtualChip->m_psStackPointer[0].v_type )
        {
          if ( poThread == poAlloc->v.v_thread )
          {
             m_oTrackedAllocs.erase( oAllocIter );
             delete poAlloc;
             break;
          }
        }
      }

      delete poThread;
      set_thread( &m_poVirtualChip->m_psStackPointer[0], NULL ); 
      m_poVirtualChip->m_psStackPointer[0].ResetValue( false );
    }
    break;
#endif

    case DT_TOKENIZER:
    {
      VMTokenizer* poTokenizer = get_tokenizer( m_poVirtualChip->m_psStackPointer );

      TRACKED_ALLOCS_ITER oAllocIter;
      for( oAllocIter  = m_oTrackedAllocs.begin();
           oAllocIter != m_oTrackedAllocs.end();
           oAllocIter++ )
      {
        VMTrackedAllocs* poAlloc = (*oAllocIter);
        if ( poAlloc->v_type == m_poVirtualChip->m_psStackPointer[0].v_type )
        {
          if ( poTokenizer == poAlloc->v.v_tokenizer )
          {
             m_oTrackedAllocs.erase( oAllocIter );
             delete poAlloc;
             break;
          }
        }
      }

      delete poTokenizer;
      set_tokenizer( &m_poVirtualChip->m_psStackPointer[0], NULL ); 
      m_poVirtualChip->m_psStackPointer[0].ResetValue( false );
    }
    break;

    case DT_STACK:
    {
      VMDataStack* poStack = get_stack( m_poVirtualChip->m_psStackPointer );

      TRACKED_ALLOCS_ITER oAllocIter;
      for( oAllocIter  = m_oTrackedAllocs.begin();
           oAllocIter != m_oTrackedAllocs.end();
           oAllocIter++ )
      {
        VMTrackedAllocs* poAlloc = (*oAllocIter);
        if ( poAlloc->v_type == m_poVirtualChip->m_psStackPointer[0].v_type )
        {
          if ( poStack == poAlloc->v.v_stack )
          {
             m_oTrackedAllocs.erase( oAllocIter );
             delete poAlloc;
             break;
          }
        }
      }

      delete poStack;
      set_stack( &m_poVirtualChip->m_psStackPointer[0], NULL ); 
      m_poVirtualChip->m_psStackPointer[0].ResetValue( false );
    }
    break;

    case DT_QUEUE:
    {
      VMDataQueue* poQueue = get_queue( m_poVirtualChip->m_psStackPointer );

      TRACKED_ALLOCS_ITER oAllocIter;
      for( oAllocIter  = m_oTrackedAllocs.begin();
           oAllocIter != m_oTrackedAllocs.end();
           oAllocIter++ )
      {
        VMTrackedAllocs* poAlloc = (*oAllocIter);
        if ( poAlloc->v_type == m_poVirtualChip->m_psStackPointer[0].v_type )
        {
          if ( poQueue == poAlloc->v.v_queue )
          {
             m_oTrackedAllocs.erase( oAllocIter );
             delete poAlloc;
             break;
          }
        }
      }

      delete poQueue;
      set_queue( &m_poVirtualChip->m_psStackPointer[0], NULL ); 
      m_poVirtualChip->m_psStackPointer[0].ResetValue( false );
    }
    break;

    case DT_HASHTABLE:
    {
      VMHashTable* poHashTable = get_hashtable( m_poVirtualChip->m_psStackPointer );

      TRACKED_ALLOCS_ITER oAllocIter;
      for( oAllocIter  = m_oTrackedAllocs.begin();
           oAllocIter != m_oTrackedAllocs.end();
           oAllocIter++ )
      {
        VMTrackedAllocs* poAlloc = (*oAllocIter);
        if ( poAlloc->v_type == m_poVirtualChip->m_psStackPointer[0].v_type )
        {
          if ( poHashTable == poAlloc->v.v_hashtable )
          {
             m_oTrackedAllocs.erase( oAllocIter );
             delete poAlloc;
             break;
          }
        }
      }

      delete poHashTable;
      set_hashtable( &m_poVirtualChip->m_psStackPointer[0], NULL ); 
      m_poVirtualChip->m_psStackPointer[0].ResetValue( false );
    }
    break;

    case DT_CALCULATOR:
    {
      VMCalculator* poCalculator = get_calculator( m_poVirtualChip->m_psStackPointer );

      TRACKED_ALLOCS_ITER oAllocIter;
      for( oAllocIter  = m_oTrackedAllocs.begin();
           oAllocIter != m_oTrackedAllocs.end();
           oAllocIter++ )
      {
        VMTrackedAllocs* poAlloc = (*oAllocIter);
        if ( poAlloc->v_type == m_poVirtualChip->m_psStackPointer[0].v_type )
        {
          if ( poCalculator == poAlloc->v.v_calculator )
          {
             m_oTrackedAllocs.erase( oAllocIter );
             delete poAlloc;
             break;
          }
        }
      }

      delete poCalculator;
      set_calculator( &m_poVirtualChip->m_psStackPointer[0], NULL ); 
      m_poVirtualChip->m_psStackPointer[0].ResetValue( false );
    }
    break;

    case DT_BYTEARRAY:
    {
      VMByteArray* poByteArray = get_bytearray( m_poVirtualChip->m_psStackPointer );

      TRACKED_ALLOCS_ITER oAllocIter;
      for( oAllocIter  = m_oTrackedAllocs.begin();
           oAllocIter != m_oTrackedAllocs.end();
           oAllocIter++ )
      {
        VMTrackedAllocs* poAlloc = (*oAllocIter);
        if ( poAlloc->v_type == m_poVirtualChip->m_psStackPointer[0].v_type )
        {
          if ( poByteArray == poAlloc->v.v_bytearray )
          {
             m_oTrackedAllocs.erase( oAllocIter );
             delete poAlloc;
             break;
          }
        }
      }

      delete poByteArray;
      set_bytearray( &m_poVirtualChip->m_psStackPointer[0], NULL ); 
      m_poVirtualChip->m_psStackPointer[0].ResetValue( false );
    }
    break;

    case DT_USERVECTOR:
    {
      VMDataVector* poVector = get_uservector( m_poVirtualChip->m_psStackPointer );

      TRACKED_ALLOCS_ITER oAllocIter;
      for( oAllocIter  = m_oTrackedAllocs.begin();
           oAllocIter != m_oTrackedAllocs.end();
           oAllocIter++ )
      {
        VMTrackedAllocs* poAlloc = (*oAllocIter);
        if ( poAlloc->v_type == m_poVirtualChip->m_psStackPointer[0].v_type )
        {
          if ( poVector == poAlloc->v.v_uservector )
          {
             m_oTrackedAllocs.erase( oAllocIter );
             delete poAlloc;
             break;
          }
        }
      }

      delete poVector;
      set_uservector( &m_poVirtualChip->m_psStackPointer[0], NULL ); 
      m_poVirtualChip->m_psStackPointer[0].ResetValue( false );
    }
    break;

    case DT_REPORTPAGE:
    {
      VMPage* poPage = get_page( m_poVirtualChip->m_psStackPointer );

      TRACKED_ALLOCS_ITER oAllocIter;
      for( oAllocIter  = m_oTrackedAllocs.begin();
           oAllocIter != m_oTrackedAllocs.end();
           oAllocIter++ )
      {
        VMTrackedAllocs* poAlloc = (*oAllocIter);
        if ( poAlloc->v_type == m_poVirtualChip->m_psStackPointer[0].v_type )
        {
          if ( poPage == poAlloc->v.v_page )
          {
             m_oTrackedAllocs.erase( oAllocIter );
             delete poAlloc;
             break;
          }
        }
      }

      delete poPage;
      set_page( &m_poVirtualChip->m_psStackPointer[0], NULL ); 
      m_poVirtualChip->m_psStackPointer[0].ResetValue( false );
    }
    break;
/*
    case DT_REPORTPAGEREGION:
    {
      VMPrintRegion* poRegion = get_region( m_poVirtualChip->m_psStackPointer );

      TRACKED_ALLOCS_ITER oAllocIter;
      for( oAllocIter  = m_oTrackedAllocs.begin();
           oAllocIter != m_oTrackedAllocs.end();
           oAllocIter++ )
      {
        VMTrackedAllocs* poAlloc = (*oAllocIter);
        if ( poAlloc->v_type == m_poVirtualChip->m_psStackPointer[0].v_type )
        {
          if ( poRegion == poAlloc->v.v_pageregion )
          {
             m_oTrackedAllocs.erase( oAllocIter );
             delete poAlloc;
             break;
          }
        }
      }

      delete poRegion;
      set_pageregion( &m_poVirtualChip->m_psStackPointer[0], NULL ); 
      m_poVirtualChip->m_psStackPointer[0].ResetValue( false );
    }
    break;
*/
    case DT_REPORTTABLE:
    {
      TABLEHEADER* poTable = get_table( m_poVirtualChip->m_psStackPointer );

      TRACKED_ALLOCS_ITER oAllocIter;
      for( oAllocIter  = m_oTrackedAllocs.begin();
           oAllocIter != m_oTrackedAllocs.end();
           oAllocIter++ )
      {
        VMTrackedAllocs* poAlloc = (*oAllocIter);
        if ( poAlloc->v_type == m_poVirtualChip->m_psStackPointer[0].v_type )
        {
          if ( poTable == poAlloc->v.v_pagetable )
          {
             m_oTrackedAllocs.erase( oAllocIter );
             delete poAlloc;
             break;
          }
        }
      }

      delete poTable;
      set_pagetable( &m_poVirtualChip->m_psStackPointer[0], NULL ); 
      m_poVirtualChip->m_psStackPointer[0].ResetValue( false );
    }
    break;

    case DT_ODBC:
    {
      VMODBC* poODBC = get_odbc( m_poVirtualChip->m_psStackPointer );

      TRACKED_ALLOCS_ITER oAllocIter;
      for( oAllocIter  = m_oTrackedAllocs.begin();
           oAllocIter != m_oTrackedAllocs.end();
           oAllocIter++ )
      {
        VMTrackedAllocs* poAlloc = (*oAllocIter);
        if ( poAlloc->v_type == m_poVirtualChip->m_psStackPointer[0].v_type )
        {
          if ( poODBC == poAlloc->v.v_odbc )
          {
             m_oTrackedAllocs.erase( oAllocIter );
             delete poAlloc;
             break;
          }
        }
      }

      poODBC->Close();
      delete poODBC;

      set_odbc( &m_poVirtualChip->m_psStackPointer[0], NULL ); 
      m_poVirtualChip->m_psStackPointer[0].ResetValue( false );
    }
    break;
  }
  m_poVirtualChip->m_psStackPointer += iArgc;
  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerFreeObject"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerSizeOf

       DESCRIPTION:  get the size of a vector or string

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerSizeOf( int iArgc )
{
  m_poInterpreter->SetLastCall( "SizeOf" );

  VMDataStack*     poStack  = NULL;
  VMDataQueue*     poQueue  = NULL;
  VMHashTable*     poTable  = NULL;
  VMDataVector*    poVector = NULL;
  VMByteArray*     poBytes  = NULL;

  VerifyRunLineArguments( iArgc, 1 );
  switch ( m_poVirtualChip->m_psStackPointer->v_type ) 
  {
    case DT_STRING:
    {
      SetValue( &m_poVirtualChip->m_psStackPointer[1], 
                m_poVirtualChip->m_psStackPointer->v.v_string->str_size );
    }
    break;

    case DT_STACK:
    {
      poStack = get_stack( m_poVirtualChip->m_psStackPointer );
      SetValue( &m_poVirtualChip->m_psStackPointer[1], 
                (int)poStack->GetCount() );
    }
    break;

    case DT_QUEUE:
    {
      poQueue = get_queue( m_poVirtualChip->m_psStackPointer );
      SetValue( &m_poVirtualChip->m_psStackPointer[1], 
                (int)poQueue->GetCount() );
    }
    break;

    case DT_HASHTABLE:
    {
      poTable = get_hashtable( m_poVirtualChip->m_psStackPointer );
      SetValue( &m_poVirtualChip->m_psStackPointer[1], 
                (int)poTable->GetCount() );
    }
    break;

    case DT_USERVECTOR:
    {
      poVector = get_uservector( m_poVirtualChip->m_psStackPointer );
      SetValue( &m_poVirtualChip->m_psStackPointer[1], 
                (int)poVector->GetCount() );
    }
    break;

    case DT_BYTEARRAY:
    {
      poBytes = get_bytearray( m_poVirtualChip->m_psStackPointer );
      SetValue( &m_poVirtualChip->m_psStackPointer[1], 
                poBytes->GetUpperBound() );
    }
    break;

    default:
    {
      SetValue( &m_poVirtualChip->m_psStackPointer[ 1 ], 1 );
    }
    break;
  }
  ++m_poVirtualChip->m_psStackPointer;
  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerSizeOf"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  "HandlerHashTablePut / HandlerHashTableRemove 
                     / HandlerHashTableFind / HandlerHashTableHasKey"

       DESCRIPTION:  HashTable Object Managment Methods

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerHashTablePut( int iArgc )
{
  m_poInterpreter->SetLastCall( "MapAddKey" );

  VerifyRunLineArguments( iArgc, 3 );
  VerifyElementType( 2, DT_HASHTABLE );

  VMHashTable*  poMap  = get_hashtable( &m_poVirtualChip->m_psStackPointer[2] );
  VMVariant*    pxKey    = &m_poVirtualChip->m_psStackPointer[1];
  VMVariant*    pxVal    = m_poVirtualChip->m_psStackPointer;

  poMap->Insert( *pxKey, *pxVal );
  
  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], true );
  m_poVirtualChip->m_psStackPointer += iArgc;

  return( 0 );
}
/*****************************************************************************/
int VMVirtualOpSys::HandlerHashTableRemove( int iArgc )
{
  m_poInterpreter->SetLastCall( "MapRemoveKey" );

  VerifyRunLineArguments( iArgc, 2 );
  VerifyElementType( 1, DT_HASHTABLE );

  VMHashTable*  poStack  = get_hashtable( &m_poVirtualChip->m_psStackPointer[1] );
  VMVariant*    pxToNuke = m_poVirtualChip->m_psStackPointer;
  
  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], 
            poStack->Delete( *pxToNuke ) );
  m_poVirtualChip->m_psStackPointer += iArgc;

  return( 0 );
}
/*****************************************************************************/
int VMVirtualOpSys::HandlerHashTableFind( int iArgc )
{
  m_poInterpreter->SetLastCall( "MapFindByKey" );

  VMVariant xResult;
  VerifyRunLineArguments( iArgc, 2 );
  VerifyElementType( 1, DT_HASHTABLE );

  VMHashTable*  poStack  = get_hashtable( &m_poVirtualChip->m_psStackPointer[1] );
  VMVariant*    pxToSeek = &m_poVirtualChip->m_psStackPointer[0];
  
  bool bResult = poStack->LookUp( *pxToSeek, xResult );
  if ( bResult )
  {
    m_poVirtualChip->m_psStackPointer[ iArgc ].ResetValue( true );
    m_poVirtualChip->m_psStackPointer[ iArgc ].v_type = xResult.v_type;
    m_poVirtualChip->m_psStackPointer[ iArgc ].v      = xResult.v;
  }
  else
  {
    set_nil( &m_poVirtualChip->m_psStackPointer[ iArgc ] );
  }

  xResult.v_type = 0;

  m_poVirtualChip->m_psStackPointer += iArgc;

  return( 0 );
}
/*****************************************************************************/
int VMVirtualOpSys::HandlerHashTableHasKey( int iArgc )
{
  m_poInterpreter->SetLastCall( "MapHasKey" );

  VerifyRunLineArguments( iArgc, 2 );
  VerifyElementType( 1, DT_HASHTABLE );

  VMHashTable*  poStack  = get_hashtable( &m_poVirtualChip->m_psStackPointer[1] );
  VMVariant*    pxToSeek = m_poVirtualChip->m_psStackPointer;
  
  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], 
            poStack->Holds( *pxToSeek ) );
  m_poVirtualChip->m_psStackPointer += iArgc;

  return( 0 );
}
/* End of function "HandlerHashTablePut / HandlerHashTableRemove 
                  / HandlerHashTableFind / HandlerHashTableHasKey"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  "HandlerStackPush / HandlerStackPop / HandlerStackPeek"

       DESCRIPTION:  Stack Object Managment Methods

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerStackPush( int iArgc )
{
  m_poInterpreter->SetLastCall( "StackPush" );

  VerifyRunLineArguments( iArgc, 2 );
  VerifyElementType( 1, DT_STACK );

  VMDataStack*   poStack = get_stack( &m_poVirtualChip->m_psStackPointer[1] );
  VMVariant*     pxToAdd = m_poVirtualChip->m_psStackPointer;

  poStack->Push( *pxToAdd );

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], true );
  m_poVirtualChip->m_psStackPointer += iArgc;

  return( 0 );
}
/*****************************************************************************/
int VMVirtualOpSys::HandlerStackPop( int iArgc )
{
  m_poInterpreter->SetLastCall( "StackPop" );

  VerifyRunLineArguments( iArgc, 1 );
  VerifyElementType( 0, DT_STACK );

  VMDataStack* poStack = get_stack( &m_poVirtualChip->m_psStackPointer[0] );

  VMVariant xResult;
  
  bool bResult = poStack->Pop( xResult );
  if ( bResult )
  {
    m_poVirtualChip->m_psStackPointer[ iArgc ].ResetValue( true );
    m_poVirtualChip->m_psStackPointer[ iArgc ].v_type = xResult.v_type;
    m_poVirtualChip->m_psStackPointer[ iArgc ].v      = xResult.v;
  }
  else
  {
    set_nil( &m_poVirtualChip->m_psStackPointer[ 0 ] );
  }

  xResult.v_type = 0;

  m_poVirtualChip->m_psStackPointer += iArgc;

  return( 0 );
}
/*****************************************************************************/
int VMVirtualOpSys::HandlerStackPeek( int iArgc )
{
  m_poInterpreter->SetLastCall( "StackPeek" );

  VerifyRunLineArguments( iArgc, 1 );
  VerifyElementType( 0, DT_STACK );

  VMVariant xResult;
  
  VMDataStack* poStack = get_stack( &m_poVirtualChip->m_psStackPointer[0] );

  bool bResult = poStack->PeekTop( xResult );
  if ( bResult )
  {
    m_poVirtualChip->m_psStackPointer[ iArgc ].ResetValue( true );
    m_poVirtualChip->m_psStackPointer[ iArgc ].v_type = xResult.v_type;
    m_poVirtualChip->m_psStackPointer[ iArgc ].v      = xResult.v;
  }
  else
  {
    set_nil( &m_poVirtualChip->m_psStackPointer[ iArgc ] );
  }

  xResult.v_type = 0;

  m_poVirtualChip->m_psStackPointer += iArgc;

  return( 0 );
}
/* End of function "HandlerStackPush / HandlerStackPop / HandlerStackPeek"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  "HandlerEnQueue / HandlerDeQueue"

       DESCRIPTION:  Queue Object Managment Methods

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerEnQueue( int iArgc )
{
  m_poInterpreter->SetLastCall( "EnQueue" );

  VerifyRunLineArguments( iArgc, 2 );
  VerifyElementType( 1, DT_QUEUE );

  VMDataQueue*   poQueue = get_queue( &m_poVirtualChip->m_psStackPointer[1] );
  VMVariant*     pxToAdd = m_poVirtualChip->m_psStackPointer;

  poQueue->Enqueue( *pxToAdd );

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], true );
  m_poVirtualChip->m_psStackPointer += iArgc;

  return( 0 );
}
/*****************************************************************************/
int VMVirtualOpSys::HandlerDeQueue( int iArgc )
{
  m_poInterpreter->SetLastCall( "DeQueue" );

  VerifyRunLineArguments( iArgc, 1 );
  VerifyElementType( 0, DT_QUEUE );

  VMDataQueue*  poQueue = get_queue( &m_poVirtualChip->m_psStackPointer[ 0 ] );
  VMVariant     xResult;
  bool bResult = poQueue->Dequeue( xResult );
  if ( bResult )
  {
    m_poVirtualChip->m_psStackPointer[ iArgc ].ResetValue( true );
    m_poVirtualChip->m_psStackPointer[ iArgc ].v_type = xResult.v_type;
    m_poVirtualChip->m_psStackPointer[ iArgc ].v      = xResult.v;
  }
  else
  {
    set_nil( &m_poVirtualChip->m_psStackPointer[ iArgc ] );
  }

  xResult.v_type = 0;

  m_poVirtualChip->m_psStackPointer += iArgc;
  return( 0 );
}
/* End of function "HandlerEnQueue / HandlerDeQueue"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  "HandlerVectorSetAtIndex / HandlerVectorGetAtIndex"
                     "HandlerVectorAppendItem / HandlerVectorRemoveAtIndex"

       DESCRIPTION:  vector operations

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0
*/
int VMVirtualOpSys::HandlerVectorSetAtIndex( int iArgc )
{
  m_poInterpreter->SetLastCall( "VectorSetAtIndex" );

  int             iOffset;
  VMVariant       oToSet;
  VMDataVector*   poVector;

  VerifyRunLineArguments( iArgc, 3 );
  VerifyElementType( 2, DT_USERVECTOR );
  VerifyElementType( 1, DT_INTEGER );

  poVector = m_poVirtualChip->m_psStackPointer[ 2 ].v.v_uservector;
  iOffset  = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_integer;
  oToSet   = m_poVirtualChip->m_psStackPointer[ 0 ];

  poVector->InsertAtIndex( iOffset, oToSet );

  m_poVirtualChip->m_psStackPointer += iArgc;
  return( 0 );
}
/*****************************************************************************/
int VMVirtualOpSys::HandlerVectorGetAtIndex( int iArgc )
{
  m_poInterpreter->SetLastCall( "VectorGetAtIndex" );

  int             iOffset;
  VMVariant       oElement;
  VMDataVector*   poVector;

  VerifyRunLineArguments( iArgc, 2 );
  VerifyElementType( 1, DT_USERVECTOR );
  VerifyElementType( 0, DT_INTEGER );

  poVector = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_uservector;
  iOffset  = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_integer;

  bool bResult = poVector->GetAtIndex( iOffset, oElement );
  if ( bResult )
  {
    m_poVirtualChip->m_psStackPointer[ iArgc ].ResetValue( true );
    m_poVirtualChip->m_psStackPointer[ iArgc ].v_type = oElement.v_type;
    m_poVirtualChip->m_psStackPointer[ iArgc ].v      = oElement.v;    
  }
  else
  {
    set_nil( &m_poVirtualChip->m_psStackPointer[ iArgc ] );
  }

  oElement.v_type = 0;

  m_poVirtualChip->m_psStackPointer += iArgc;
  return( 0 );
}
/*****************************************************************************/
int VMVirtualOpSys::HandlerVectorAppendItem( int iArgc )
{
  m_poInterpreter->SetLastCall( "VectorAddItem" );

  VMVariant       oToSet;
  VMDataVector*   poVector;

  VerifyRunLineArguments( iArgc, 2 );
  VerifyElementType( 1, DT_USERVECTOR );

  poVector = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_uservector;
  oToSet   = m_poVirtualChip->m_psStackPointer[ 0 ];

  poVector->Append( oToSet );

  oToSet.v_type = 0;

  m_poVirtualChip->m_psStackPointer += iArgc;
  return( 0 );
}
/*****************************************************************************/
int VMVirtualOpSys::HandlerVectorRemoveAtIndex( int iArgc )
{
  m_poInterpreter->SetLastCall( "VectorDelAtIndex" );

  int             iOffset;
  VMDataVector*   poVector;
  VMVariant       xIgnored;

  VerifyRunLineArguments( iArgc, 2 );
  VerifyElementType( 1, DT_USERVECTOR );
  VerifyElementType( 0, DT_INTEGER );

  poVector = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_uservector;
  iOffset  = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_integer;

  bool bResult = poVector->RemoveAtIndex( iOffset, xIgnored );
  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], bResult );

  xIgnored.v_type = 0;
   
  m_poVirtualChip->m_psStackPointer += iArgc;
  return( 0 );
}
/* End of function "HandlerVectorSetAtIndex / HandlerVectorGetAtIndex"
                   "HandlerVectorAppendItem / HandlerVectorRemoveAtIndex"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  "HandlerByteArrayGetAtIndex   / HandlerByteArraySetAtIndex"
                     "HandlerByteArrayAppend       / HandlerByteArrayInsertAtIndex"
                     "HandlerByteArrayRemoveAtIndex"

       DESCRIPTION:  vector operations

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0
*/
int VMVirtualOpSys::HandlerByteArraySetAtIndex( int iArgc )
{
  m_poInterpreter->SetLastCall( "ByteArraySetAtIndex" );

  int             iOffset;
  unsigned char   chToSet;
  VMByteArray*    poBytes;

  VerifyRunLineArguments( iArgc, 3 );
  VerifyElementType( 2, DT_BYTEARRAY );
  VerifyElementType( 1, DT_INTEGER   );
  VerifyElementType( 0, DT_BYTE      );

  poBytes  = m_poVirtualChip->m_psStackPointer[ 2 ].v.v_bytearray;
  iOffset  = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_integer;
  chToSet  = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_byte;

  poBytes->SetAtGrow( iOffset, chToSet );

  m_poVirtualChip->m_psStackPointer += iArgc;
  return( 0 );
}
/*****************************************************************************/
int VMVirtualOpSys::HandlerByteArrayGetAtIndex( int iArgc )
{
  m_poInterpreter->SetLastCall( "ByteArrayGetAtIndex" );

  int          iOffset;
  VMByteArray* poBytes;

  VerifyRunLineArguments( iArgc, 2 );
  VerifyElementType( 1, DT_BYTEARRAY    );
  VerifyElementType( 0, DT_INTEGER      );

  poBytes  = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_bytearray;
  iOffset  = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_integer;

  BYTE      aByte = poBytes->GetAt( iOffset );
  VMVariant xByte;

  xByte.v_type = DT_BYTE;
  xByte.v.v_byte = aByte;

  m_poVirtualChip->m_psStackPointer[ iArgc ] = xByte;

  m_poVirtualChip->m_psStackPointer += iArgc;
  return( 0 );
}
/*****************************************************************************/
int VMVirtualOpSys::HandlerByteArrayAppend( int iArgc )
{
  m_poInterpreter->SetLastCall( "ByteArrayAppend" );

  VMByteArray* poBytes;

  VerifyRunLineArguments( iArgc, 2 );
  VerifyElementType( 1, DT_BYTEARRAY );
  poBytes = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_bytearray;

  if ( m_poVirtualChip->m_psStackPointer[ 0 ].v_type == DT_BYTE )
  {
    poBytes->Append( m_poVirtualChip->m_psStackPointer[ 0 ].v.v_byte );
  }
  else
  if ( m_poVirtualChip->m_psStackPointer[ 0 ].v_type == DT_BYTEARRAY )
  {
    poBytes->Append( *( m_poVirtualChip->m_psStackPointer[ 0 ].v.v_bytearray ) );
  }
  else
  if ( m_poVirtualChip->m_psStackPointer[ 0 ].v_type == DT_STRING )
  {
    long lSize = m_poVirtualChip->m_psStackPointer[0].v.v_string->str_size + 1;
    char* pchToAppend = new char[ lSize ];
    memset( pchToAppend, 0, lSize );
    GetCStyleString( pchToAppend, 
                     lSize, 
                     &m_poVirtualChip->m_psStackPointer[0] );
    poBytes->Append( pchToAppend, lSize - 1 );
  }
  if ( m_poVirtualChip->m_psStackPointer[ 0 ].v_type == DT_DWORD )
  {
    poBytes->Append( (const char*)(&( m_poVirtualChip->m_psStackPointer[ 0 ].v.v_dword )),
                     sizeof( DWORD ) );
  }

  m_poVirtualChip->m_psStackPointer += iArgc;
  return( 0 );
}
/*****************************************************************************/
int VMVirtualOpSys::HandlerByteArrayInsertAtIndex( int iArgc )
{
  m_poInterpreter->SetLastCall( "ByteArrayInsertAtIndex" );

  VMByteArray* poBytes;
  int          iOffset;

  VerifyRunLineArguments( iArgc, 3 );
  VerifyElementType( 2, DT_BYTEARRAY  );
  VerifyElementType( 1, DT_INTEGER    );
  poBytes = m_poVirtualChip->m_psStackPointer[ 2 ].v.v_bytearray;
  iOffset = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_integer;

  if ( m_poVirtualChip->m_psStackPointer[ 0 ].v_type == DT_BYTE )
  {
    poBytes->InsertAt( iOffset, m_poVirtualChip->m_psStackPointer[ 0 ].v.v_byte );
  }
  else
  if ( m_poVirtualChip->m_psStackPointer[ 0 ].v_type == DT_BYTEARRAY )
  {
    poBytes->InsertAt( iOffset, *( m_poVirtualChip->m_psStackPointer[ 0 ].v.v_bytearray ) );
  }
  else
  if ( m_poVirtualChip->m_psStackPointer[ 0 ].v_type == DT_STRING )
  {
    long lSize = m_poVirtualChip->m_psStackPointer[0].v.v_string->str_size + 1;
    char* pchToAppend = new char[ lSize ];
    memset( pchToAppend, 0, lSize );
    GetCStyleString( pchToAppend, 
                     lSize, 
                     &m_poVirtualChip->m_psStackPointer[0] );
    poBytes->InsertAt( iOffset, pchToAppend, lSize - 1 );
  }
  if ( m_poVirtualChip->m_psStackPointer[ 0 ].v_type == DT_DWORD )
  {
    poBytes->InsertAt( iOffset, 
                       (const char*)(&( m_poVirtualChip->m_psStackPointer[ 0 ].v.v_dword )),
                       sizeof( DWORD ) );
  }

  m_poVirtualChip->m_psStackPointer += iArgc;
  return( 0 );
}
/*****************************************************************************/
int VMVirtualOpSys::HandlerByteArrayRemoveAtIndex( int iArgc )
{
  m_poInterpreter->SetLastCall( "ByteArrayDelAtIndex" );

  int          iOffset;
  int          iCount;
  VMByteArray* poBytes;

  VerifyRunLineArguments( iArgc, 3 );
  VerifyElementType( 2, DT_BYTEARRAY  );
  VerifyElementType( 1, DT_INTEGER    );
  VerifyElementType( 0, DT_INTEGER    );

  poBytes  = m_poVirtualChip->m_psStackPointer[ 2 ].v.v_bytearray;
  iOffset  = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_integer;
  iCount   = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_integer;

  poBytes->RemoveAt( iOffset, iCount );
  m_poVirtualChip->m_psStackPointer += iArgc;
  return( 0 );
}
/* End of function "HandlerByteArrayGetAtIndex   / HandlerByteArraySetAtIndex"
                   "HandlerByteArrayAppend       / HandlerByteArrayInsertAtIndex"
                   "HandlerByteArrayRemoveAtIndex"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerCollectionClear

       DESCRIPTION:  General Collection Management Method

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerCollectionClear( int iArgc )
{
  VMDataStack*     poStack  = NULL;
  VMDataQueue*     poQueue  = NULL;
  VMHashTable*     poTable  = NULL;
  VMDataVector*    poVector = NULL;
  VMByteArray*     poBytes  = NULL;

  VerifyRunLineArguments( iArgc, 1 );
  switch ( m_poVirtualChip->m_psStackPointer->v_type ) 
  {
    case DT_STACK:
    {
      poStack = get_stack( m_poVirtualChip->m_psStackPointer );
      poStack->Clear();
      SetValue( &m_poVirtualChip->m_psStackPointer[1], true );
    }
    break;

    case DT_QUEUE:
    {
      poQueue = get_queue( m_poVirtualChip->m_psStackPointer );
      poQueue->Clear();
      SetValue( &m_poVirtualChip->m_psStackPointer[1], true );
    }
    break;

    case DT_HASHTABLE:
    {
      poTable = get_hashtable( m_poVirtualChip->m_psStackPointer );
      poTable->Erase();
      SetValue( &m_poVirtualChip->m_psStackPointer[1], true );
    }
    break;

    case DT_USERVECTOR:
    {
      poVector = get_uservector( m_poVirtualChip->m_psStackPointer );
      poVector->Clear();
      SetValue( &m_poVirtualChip->m_psStackPointer[1], true );
    }
    break;

    case DT_BYTEARRAY:
    {
      poBytes = get_bytearray( m_poVirtualChip->m_psStackPointer );
      poBytes->FreeAll();
      SetValue( &m_poVirtualChip->m_psStackPointer[1], true );
    }
    break;

      // mjs: put in dequeue, tree methods here

    default:
    {
      SetValue( &m_poVirtualChip->m_psStackPointer[1], false );
    }
    break;
  }
  ++m_poVirtualChip->m_psStackPointer;
  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerCollectionClear"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerMax

       DESCRIPTION:  finds the maximum number from a list

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0
*/
int VMVirtualOpSys::HandlerMax( int iArgc )
{
  m_poInterpreter->SetLastCall( "Max" );

  long         lMaximum = 0;
  unsigned int iLoop;

  VerifyRunLineArguments( iArgc, 1 );
  VerifyElementType( 1, DT_USERVECTOR );
  for ( iLoop = 0; 
        iLoop <= m_poVirtualChip->m_psStackPointer[0].v.v_uservector->GetCount(); 
        iLoop++ )
  {
    VMVariant xElement;
    m_poVirtualChip->m_psStackPointer[0].v.v_uservector->GetAtIndex( iLoop, xElement );
    VerifyElementType( xElement.v_type, DT_INTEGER );
    lMaximum = max( lMaximum, xElement.v.v_integer );
  }

  SetValue( &m_poVirtualChip->m_psStackPointer[iArgc], lMaximum );

  m_poVirtualChip->m_psStackPointer += iArgc;
  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerMax"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerMin

       DESCRIPTION:  finds the minimum number from a list

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0
*/
int VMVirtualOpSys::HandlerMin( int iArgc )
{
  m_poInterpreter->SetLastCall( "Min" );

  long         lMinimum = 0x7FFFFFFF;
  unsigned int iLoop;

  VerifyRunLineArguments( iArgc, 1 );
  VerifyElementType( 1, DT_USERVECTOR );
  for ( iLoop = 0; 
        iLoop <= m_poVirtualChip->m_psStackPointer[0].v.v_uservector->GetCount(); 
        iLoop++ )
  {
    VMVariant xElement;
    m_poVirtualChip->m_psStackPointer[0].v.v_uservector->GetAtIndex( iLoop, xElement );
    VerifyElementType( xElement.v_type, DT_INTEGER );
    lMinimum = min( lMinimum, xElement.v.v_integer );
  }

  SetValue( &m_poVirtualChip->m_psStackPointer[iArgc], lMinimum );

  m_poVirtualChip->m_psStackPointer += iArgc;
  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerMin"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerAverage

       DESCRIPTION:  finds the the average value from a list

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0
*/
int VMVirtualOpSys::HandlerAverage( int iArgc )
{
  m_poInterpreter->SetLastCall( "Average" );

  long         lSum = 0;
  unsigned int iLoop;
  long         lAvg = 0;

  VerifyRunLineArguments( iArgc, 1 );
  VerifyElementType( 1, DT_USERVECTOR );

  if ( m_poVirtualChip->m_psStackPointer[0].v.v_uservector->GetCount() == 0 )
  {
    SetValue( &m_poVirtualChip->m_psStackPointer[iArgc], lAvg );
  }
  else
  {
    for ( iLoop = 0; 
          iLoop <= m_poVirtualChip->m_psStackPointer[0].v.v_uservector->GetCount(); 
          iLoop++ )
    {
      VMVariant xElement;
      m_poVirtualChip->m_psStackPointer[0].v.v_uservector->GetAtIndex( iLoop, xElement );
      VerifyElementType( xElement.v_type, DT_INTEGER );
      lSum += xElement.v.v_integer;
    }
 
    lAvg = lSum / m_poVirtualChip->m_psStackPointer[0].v.v_uservector->GetCount();

    SetValue( &m_poVirtualChip->m_psStackPointer[iArgc], lAvg );
  }
  m_poVirtualChip->m_psStackPointer += iArgc;
  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerAverage"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerRandomInt

       DESCRIPTION:  returns a randomized integer to the caller

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerRandomInt( int iArgc )
{
  m_poInterpreter->SetLastCall( "RandomInt" );

  VerifyRunLineArguments( iArgc, 0 );
  srand( (unsigned)time( NULL ) );

  SetValue( &m_poVirtualChip->m_psStackPointer[iArgc], rand() );

  m_poVirtualChip->m_psStackPointer += iArgc;
  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerRandomInt"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerCreateSemaphore

       DESCRIPTION:  creates a kernel level semaphore object, or if the object
                     already exists, returns that handle

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerCreateSemaphore( int iArgc )
{
  m_poInterpreter->SetLastCall( "CreateSemaphore" );

  HANDLE               hSemaphore = NULL;
  SECURITY_ATTRIBUTES  sSecurity;
  char                 achSemaphoreName[35];

  VerifyRunLineArguments( iArgc, 3 );
  VerifyElementType( 2, DT_STRING );
  VerifyElementType( 1, DT_INTEGER );
  VerifyElementType( 0, DT_INTEGER );

  GetCStyleString( achSemaphoreName, 
                   sizeof( achSemaphoreName ), 
                   &m_poVirtualChip->m_psStackPointer[2] );

  long lInitialCount  = m_poVirtualChip->m_psStackPointer[1].v.v_integer;
  long lMaximumCount  = m_poVirtualChip->m_psStackPointer[0].v.v_integer;

  sSecurity.nLength              = sizeof( SECURITY_ATTRIBUTES );
  sSecurity.lpSecurityDescriptor = NULL;
  sSecurity.bInheritHandle       = TRUE;

  hSemaphore = CreateSemaphore( &sSecurity,
                                lInitialCount,
                                lMaximumCount,
                                achSemaphoreName );

  set_kernelhandle( &m_poVirtualChip->m_psStackPointer[iArgc], hSemaphore );
  m_poVirtualChip->m_psStackPointer += iArgc;
  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerCreateSemaphore"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerOpenSemaphore

       DESCRIPTION:  opens a semaphore (that is presumed to be already existing)
                     by name

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerOpenSemaphore( int iArgc )
{
  m_poInterpreter->SetLastCall( "OpenSemaphore" );

  char   achSemaphoreName[35];

  VerifyRunLineArguments( iArgc, 1 );
  VerifyElementType( 0, DT_STRING );

  GetCStyleString( achSemaphoreName, 
                   sizeof( achSemaphoreName ), 
                   &m_poVirtualChip->m_psStackPointer[0] );

  DWORD  dwAccess = SEMAPHORE_ALL_ACCESS | SEMAPHORE_MODIFY_STATE | SYNCHRONIZE;
  HANDLE hSemaphore = OpenSemaphore( dwAccess,
                                     FALSE,
                                     achSemaphoreName );

  set_kernelhandle( &m_poVirtualChip->m_psStackPointer[iArgc], hSemaphore );
  m_poVirtualChip->m_psStackPointer += iArgc;
  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerOpenSemaphore"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerCloseSemaphore

       DESCRIPTION:  releases a semaphore 

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerCloseSemaphore( int iArgc )
{
  m_poInterpreter->SetLastCall( "CloseSemaphore" );

  VerifyRunLineArguments( iArgc, 2 );
  VerifyElementType( 1, DT_KERNELHANDLE );
  VerifyElementType( 0, DT_INTEGER );

  HANDLE hSemaphoreID  = m_poVirtualChip->m_psStackPointer[1].v.v_kernelhandle; 
  long   lReleaseCount = m_poVirtualChip->m_psStackPointer[0].v.v_integer;
  long   lPreviousCount;

  bool bReturn = ReleaseSemaphore( hSemaphoreID,
                                   lReleaseCount,
                                   &lPreviousCount );

  SetValue( &m_poVirtualChip->m_psStackPointer[iArgc], bReturn );

  m_poVirtualChip->m_psStackPointer += iArgc;
  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerCloseSemaphore"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerCreateMutex

       DESCRIPTION:  creates a kernel level mutex object. If the object already
                     exists, then a handle to that object is returned.

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerCreateMutex( int iArgc )
{
  m_poInterpreter->SetLastCall( "CreateMutex" );

  HANDLE               hMutex = NULL;
  SECURITY_ATTRIBUTES  sSecurity;
  char                 achMutexName[35];

  VerifyRunLineArguments( iArgc, 2 );
  VerifyElementType( 1, DT_STRING );
  VerifyElementType( 0, DT_INTEGER );

  GetCStyleString( achMutexName, 
                   sizeof( achMutexName ), 
                   &m_poVirtualChip->m_psStackPointer[1] );

  long lInitiallyOwned = m_poVirtualChip->m_psStackPointer[0].v.v_integer;

  sSecurity.nLength              = sizeof( SECURITY_ATTRIBUTES );
  sSecurity.lpSecurityDescriptor = NULL;
  sSecurity.bInheritHandle       = TRUE;

  hMutex = CreateMutex( &sSecurity,
                        lInitiallyOwned,
                        achMutexName );

  set_kernelhandle( &m_poVirtualChip->m_psStackPointer[iArgc], hMutex );
  m_poVirtualChip->m_psStackPointer += iArgc;
  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerCreateMutex"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerOpenMutex

       DESCRIPTION:  attempts to take ownership of a mutex 

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerOpenMutex( int iArgc )
{
  m_poInterpreter->SetLastCall( "OpenMutex" );

  char   achMutexName[35];

  VerifyRunLineArguments( iArgc, 1 );
  VerifyElementType( 0, DT_STRING );

  GetCStyleString( achMutexName, 
                   sizeof( achMutexName ), 
                   &m_poVirtualChip->m_psStackPointer[0] );

  DWORD  dwAccess = MUTEX_ALL_ACCESS | SYNCHRONIZE;
  HANDLE hMutex   = OpenMutex( dwAccess,
                               FALSE,
                               achMutexName );

  set_kernelhandle( &m_poVirtualChip->m_psStackPointer[iArgc], hMutex );
  m_poVirtualChip->m_psStackPointer += iArgc;
  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerOpenMutex"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerAcquireMutex

       DESCRIPTION:  releases ownership of a mutex

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerAcquireMutex( int iArgc )
{
  m_poInterpreter->SetLastCall( "AcquireMutex" );

  long  lReturn = 0;
  DWORD dwReturn;

  VerifyRunLineArguments( iArgc, 2 );
  VerifyElementType( 1, DT_KERNELHANDLE );
  VerifyElementType( 0, DT_INTEGER );

  HANDLE hMutexID  = m_poVirtualChip->m_psStackPointer[1].v.v_kernelhandle;
  long  lTimeOut   = m_poVirtualChip->m_psStackPointer[0].v.v_integer;

  if ( 46346483 != lTimeOut )
  {
    dwReturn = WaitForSingleObject( hMutexID, (DWORD) lTimeOut );
  }
  else
  {
    dwReturn = WaitForSingleObject( hMutexID, INFINITE );
  }

  switch ( dwReturn )
  {
    case WAIT_ABANDONED:
    {
      // The mutex object that was not released by the thread 
      // that owned the mutex object before the owning thread 
      // terminated. Ownership of the mutex object is granted 
      // to the calling thread, and the mutex is set to nonsignaled. 
      //
      lReturn = 3;
    }
    break;

    case WAIT_OBJECT_0:
    {
      // The state of the specified object is signaled. 
      //
      lReturn = 2;
    }
    break;

    case WAIT_TIMEOUT:
    {
      // The time-out interval elapsed, and the object's state is nonsignaled.
      //
      lReturn = 1;
    }
    break;

    case WAIT_FAILED:
    {
      lReturn = 0;
    }
    break;
  }
  SetValue( &m_poVirtualChip->m_psStackPointer[iArgc], lReturn );

  m_poVirtualChip->m_psStackPointer += iArgc;
  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerAcquireMutex"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerReleaseMutex

       DESCRIPTION:  releases ownership of a mutex

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerReleaseMutex( int iArgc )
{
  m_poInterpreter->SetLastCall( "ReleaseMutex" );

  VerifyRunLineArguments( iArgc, 1 );
  VerifyElementType( 0, DT_KERNELHANDLE );

  HANDLE hMutexID  = m_poVirtualChip->m_psStackPointer[0].v.v_kernelhandle;

  bool bReturn = ReleaseMutex( hMutexID );

  SetValue( &m_poVirtualChip->m_psStackPointer[iArgc], bReturn );

  m_poVirtualChip->m_psStackPointer += iArgc;
  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerReleaseMutex"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerCreateEvent

       DESCRIPTION:  creates a kernel level event object

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerCreateEvent( int iArgc )
{
  m_poInterpreter->SetLastCall( "CreateEvent" );

  HANDLE               hEvent = NULL;
  SECURITY_ATTRIBUTES  sSecurity;
  char                 achEventName[35];

  VerifyRunLineArguments( iArgc, 3 );
  VerifyElementType( 2, DT_STRING );
  VerifyElementType( 1, DT_INTEGER );
  VerifyElementType( 0, DT_INTEGER );

  GetCStyleString( achEventName, 
                   sizeof( achEventName ), 
                   &m_poVirtualChip->m_psStackPointer[2] );

  long lManualReset  = m_poVirtualChip->m_psStackPointer[1].v.v_integer;
  long lInitialState = m_poVirtualChip->m_psStackPointer[0].v.v_integer;

  sSecurity.nLength              = sizeof( SECURITY_ATTRIBUTES );
  sSecurity.lpSecurityDescriptor = NULL;
  sSecurity.bInheritHandle       = TRUE;

  hEvent = CreateEvent( &sSecurity, (BOOL)lManualReset, (BOOL)lInitialState, achEventName );

  set_kernelhandle( &m_poVirtualChip->m_psStackPointer[iArgc], hEvent );
  m_poVirtualChip->m_psStackPointer += iArgc;
  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerCreateEvent"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerOpenEvent

       DESCRIPTION:  opens (gets a handled to) an event object

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerOpenEvent( int iArgc )
{
  m_poInterpreter->SetLastCall( "OpenEvent" );

  char   achEventName[35];

  VerifyRunLineArguments( iArgc, 1 );
  VerifyElementType( 0, DT_STRING );

  GetCStyleString( achEventName, 
                   sizeof( achEventName ), 
                   &m_poVirtualChip->m_psStackPointer[0] );

  DWORD  dwAccess = SEMAPHORE_ALL_ACCESS | EVENT_MODIFY_STATE | SYNCHRONIZE;
  HANDLE hEvent = OpenEvent( dwAccess,
                             FALSE,
                             achEventName );

  set_kernelhandle( &m_poVirtualChip->m_psStackPointer[iArgc], hEvent );
  m_poVirtualChip->m_psStackPointer += iArgc;
  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerOpenEvent"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerPulseEvent

       DESCRIPTION:  pulses an event object

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerPulseEvent( int iArgc )
{
  m_poInterpreter->SetLastCall( "PulseEvent" );

  VerifyRunLineArguments( iArgc, 1 );
  VerifyElementType( 0, DT_KERNELHANDLE );

  HANDLE hEventID  = m_poVirtualChip->m_psStackPointer[0].v.v_kernelhandle;

  bool bReturn = PulseEvent( hEventID );

  SetValue( &m_poVirtualChip->m_psStackPointer[iArgc], bReturn );

  m_poVirtualChip->m_psStackPointer += iArgc;
  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerPulseEvent"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerSetEvent

       DESCRIPTION:  sets an event object

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerSetEvent( int iArgc )
{
  m_poInterpreter->SetLastCall( "SetEvent" );

  VerifyRunLineArguments( iArgc, 1 );
  VerifyElementType( 0, DT_KERNELHANDLE );

  HANDLE hEventID  = m_poVirtualChip->m_psStackPointer[0].v.v_kernelhandle;

  bool bReturn = SetEvent( hEventID );

  SetValue( &m_poVirtualChip->m_psStackPointer[iArgc], bReturn );

  m_poVirtualChip->m_psStackPointer += iArgc;
  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerSetEvent"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerResetEvent

       DESCRIPTION:  resets an event

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerResetEvent( int iArgc )
{
  m_poInterpreter->SetLastCall( "ResetEvent" );

  VerifyRunLineArguments( iArgc, 1 );
  VerifyElementType( 0, DT_KERNELHANDLE );

  HANDLE hEventID = m_poVirtualChip->m_psStackPointer[0].v.v_kernelhandle;

  bool bReturn = ResetEvent( hEventID );

  SetValue( &m_poVirtualChip->m_psStackPointer[iArgc], bReturn );

  m_poVirtualChip->m_psStackPointer += iArgc;
  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerResetEvent"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerCloseHandle

       DESCRIPTION:  destroys a semaphore object from the kernels object space

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerCloseHandle( int iArgc )
{
  m_poInterpreter->SetLastCall( "CloseHandle" );

  bool   bReturn = FALSE;  // assume failure
  HANDLE hHandle = NULL;

  VerifyRunLineArguments( iArgc, 1 );

  if ( m_poVirtualChip->m_psStackPointer[0].v_type == DT_KERNELHANDLE )
  {
    hHandle  = m_poVirtualChip->m_psStackPointer[0].v.v_kernelhandle;
    bReturn  = TRUE;
  }
  else
  if ( m_poVirtualChip->m_psStackPointer[0].v_type == DT_HANDLE )
  {
    hHandle  = m_poVirtualChip->m_psStackPointer[0].v.v_handle;
    bReturn  = TRUE;
  }
  else
  if ( m_poVirtualChip->m_psStackPointer[0].v_type == DT_NTFILEHANDLE )
  {
    hHandle  = m_poVirtualChip->m_psStackPointer[0].v.v_handle;
    bReturn  = TRUE;
  }
 
  if ( bReturn )
  {
    bReturn = CloseHandle( hHandle );
  }

  SetValue( &m_poVirtualChip->m_psStackPointer[iArgc], bReturn );

  m_poVirtualChip->m_psStackPointer += iArgc;
  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerCloseHandle"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerWaitForSingleObject

       DESCRIPTION:  will wait for the specified object for the specified 
                     number of seconds

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerWaitForSingleObject( int iArgc )
{
  m_poInterpreter->SetLastCall( "WaitForSingleObject" );

  long  lReturn = 0;
  DWORD dwReturn;

  VerifyRunLineArguments( iArgc, 2 );
  VerifyElementType( 1, DT_KERNELHANDLE );
  VerifyElementType( 0, DT_INTEGER );

  HANDLE hObjectID  = m_poVirtualChip->m_psStackPointer[1].v.v_kernelhandle;
  long   lTimeOut   = m_poVirtualChip->m_psStackPointer[0].v.v_integer;
  if ( 46346483 != lTimeOut )
  {
    dwReturn = WaitForSingleObject( hObjectID, (DWORD) lTimeOut );
  }
  else
  {
    dwReturn = WaitForSingleObject( hObjectID, INFINITE );
  }

  switch ( dwReturn )
  {
    case WAIT_ABANDONED:
    {
      // The object that was not released by the thread that
      // owned the mutex object before the owning thread 
      // terminated. Ownership of the object is granted 
      // to the calling thread, and the object is set to 
      // nonsignaled. 
      //
      lReturn = 3;
    }
    break;

    case WAIT_OBJECT_0:
    {
      // The state of the specified object is signaled. 
      //
      lReturn = 2;
    }
    break;

    case WAIT_TIMEOUT:
    {
      // The time-out interval elapsed, and the object's state is nonsignaled.
      //
      lReturn = 1;
    }
    break;

    case WAIT_FAILED:
    {
      lReturn = 0;
    }
    break;
  }
  SetValue( &m_poVirtualChip->m_psStackPointer[iArgc], lReturn );

  m_poVirtualChip->m_psStackPointer += iArgc;
  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerWaitForSingleObject"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerWaitForMultipleObjects

       DESCRIPTION:  will wait for multiple objects for the specified number of
                     seconds

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerWaitForMultipleObjects( int iArgc )
{
  m_poInterpreter->SetLastCall( "WaitForMultipleObjects" );

  long   lReturn = 0;
  int    iLoop;
  BOOL   bCanContinue = TRUE;
  DWORD  dwResult;

  VerifyRunLineArguments( iArgc, 4 );
  VerifyElementType( 3, DT_INTEGER );
  VerifyElementType( 2, DT_INTEGER );
  VerifyElementType( 1, DT_INTEGER );
  VerifyElementType( 0, DT_USERVECTOR );

  long lWaitAll     = m_poVirtualChip->m_psStackPointer[3].v.v_integer;
  long lWaitTime    = m_poVirtualChip->m_psStackPointer[2].v.v_integer;
  long lHandleCount = m_poVirtualChip->m_psStackPointer[1].v.v_integer;


  // verify that the vector contains waitable handles in
  // the range of the collection that the user said to 
  // wait for
  //
  VMDataVector*    poVector = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_uservector;
  int              iCount   = poVector->GetCount();

  // mjs: new code
  //
  if ( iCount >= lHandleCount )
  {
    for( iLoop = 0; iLoop < lHandleCount; iLoop++ )
    {
      VMVariant xElement;
      m_poVirtualChip->m_psStackPointer[0].v.v_uservector->GetAtIndex( iLoop, xElement );
      if ( !( xElement.v_type == DT_KERNELHANDLE ) )
      {
        bCanContinue = FALSE;
      }   
    }
  }
  else
  {
    bCanContinue = FALSE;
  }

  if ( bCanContinue )
  {
    DWORD  dwWaitTime;
    HANDLE hWaitArray[64];

    for ( iLoop = 0; iLoop <= lHandleCount; iLoop++ )
    {
      VMVariant xElement;
      m_poVirtualChip->m_psStackPointer[0].v.v_uservector->GetAtIndex( iLoop, xElement );
      hWaitArray[iLoop] = xElement.v.v_kernelhandle;
    }

    if ( 46346483 != lWaitTime )
    {
      dwWaitTime = lWaitTime;
    }
    else
    {
      dwWaitTime = INFINITE;
    }

    dwResult = WaitForMultipleObjects( lHandleCount, 
                                       hWaitArray,
                                       (BOOL) lWaitAll, 
                                       dwWaitTime );
    if ( WAIT_FAILED == dwResult )
    {
      lReturn = 0;
    }
    else
    if ( ( WAIT_OBJECT_0 <= dwResult )
      && ( dwResult <= WAIT_OBJECT_0 + (iArgc - 2) ) )
    {
      // If lWaitAll is 1, the return value indicates that 
      // the state of all specified objects is signaled. 
      // If bWaitAll is FALSE, the return value minus WAIT_OBJECT_0 
      // indicates the array index of the object that satisfied the 
      // wait. If more than one object became signalled during the 
      // call, this is the array index of the signalled object with 
      // the smallest index value of all the signalled objects.
      //
      lReturn = dwResult - WAIT_OBJECT_0;
    }
    else
    if ( ( WAIT_ABANDONED_0 <= dwResult )
      && ( dwResult <= WAIT_ABANDONED_0 + (iArgc - 2) ) )
    {
      // If lWaitAll is 1, the return value indicates that 
      // the state of all specified objects is signaled and 
      // at least one of the objects is an abandoned mutex object. 
      // If lWaitAll is 0, the return value minus WAIT_ABANDONED_0 
      // indicates the lpHandles array index of an abandoned mutex 
      // object that satisfied the wait.
      //
      lReturn = 0 - ( dwResult - WAIT_ABANDONED_0 );
    }
    else
    if ( WAIT_TIMEOUT == dwResult )
    {
      // The time-out interval elapsed and the conditions specified 
      // by the bWaitAll parameter are not satisfied. 
      // 
      // send back some silly number to reflect this condition
      //
      lReturn = 9999;
    }
  }
   
  SetValue( &m_poVirtualChip->m_psStackPointer[iArgc], lReturn );

  m_poVirtualChip->m_psStackPointer += iArgc;
  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerWaitForMultipleObjects"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerStringBoundedBy

       DESCRIPTION:  returns a sub-string of a string that is bounded by a
                     pair of other strings

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerStringBoundedBy( int iArgc )
{
  m_poInterpreter->SetLastCall( "StringBoundedBy" );

  char* pchInput      = NULL;
  char* pchLowerBound = NULL;
  char* pchUpperBound = NULL;

  VerifyRunLineArguments( iArgc, 3 );
  VerifyElementType( 2, DT_STRING );
  VerifyElementType( 1, DT_STRING );
  VerifyElementType( 0, DT_STRING );

  pchInput      = m_poVirtualChip->m_psStackPointer[2].v.v_string->str_data;
  pchLowerBound = m_poVirtualChip->m_psStackPointer[1].v.v_string->str_data;
  pchUpperBound = m_poVirtualChip->m_psStackPointer[0].v.v_string->str_data;

  char* pchBegAt = strstr( pchInput, pchLowerBound );
  char* pchEndAt = strstr( pchInput, pchUpperBound );

  if ( NULL != pchBegAt && NULL != pchEndAt )
  {
    pchBegAt += strlen( pchLowerBound );

    if ( pchEndAt >= pchBegAt )
    {
      vmstring*  pchReturn = AllocateNewString( pchEndAt - pchBegAt + 1, true );
      memset( pchReturn->str_data, 0, pchEndAt - pchBegAt + 1 );
      strncpy( pchReturn->str_data, pchBegAt, pchEndAt - pchBegAt );
      SetValue( &m_poVirtualChip->m_psStackPointer[iArgc], pchReturn );
    }
    else
    {
      set_nil( &m_poVirtualChip->m_psStackPointer[iArgc] );
    }
  }
  else
  {
    set_nil( &m_poVirtualChip->m_psStackPointer[iArgc] );
  }
  m_poVirtualChip->m_psStackPointer += iArgc;
  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerStringBoundedBy"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerIntToString

       DESCRIPTION:  changes a string to an int

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerIntToString( int iArgc )
{
  m_poInterpreter->SetLastCall( "IntToString" );

  char achOutput[25];

  VerifyRunLineArguments( iArgc, 1 );
  VerifyElementType( 0, DT_INTEGER );

  long lInput  = m_poVirtualChip->m_psStackPointer[0].v.v_integer;
  ltoa( lInput, achOutput, 10 );

  vmstring* pchReturn = AllocateNewString( strlen( achOutput ) + 1, true );
  memset( pchReturn->str_data, 0, strlen( achOutput ) + 1 );
  strcpy( pchReturn->str_data, achOutput );
  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], pchReturn );
  m_poVirtualChip->m_psStackPointer += iArgc;
  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerIntToString"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerDoubleToString

       DESCRIPTION:  changes a string to an int

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerDoubleToString( int iArgc )
{
  m_poInterpreter->SetLastCall( "DoubleToString" );

  char achOutput[60];

  VerifyRunLineArguments( iArgc, 2 );
  VerifyElementType( 1, DT_DOUBLE  );
  VerifyElementType( 0, DT_INTEGER );

  double dblInput  = m_poVirtualChip->m_psStackPointer[1].v.v_double;

  int     iDecimalPointAt;
  int     iSign;
  char*   pchBuffer;
  int     iPrecision =  m_poVirtualChip->m_psStackPointer[0].v.v_integer;

  // from docs: Only digits are stored in the string. 
  //
  // The position of the decimal point and the sign of value
  // can be obtained from dec and sign after the call.
  //
  // The dec parameter points to an integer value giving the
  // position of the decimal point with respect to the 
  // beginning of the string. A 0 or negative integer value
  // indicates that the decimal point lies to the left of the
  // first digit. 
  //
  // The sign parameter points to an integer that indicates 
  // the sign of the converted number. If the integer value
  // is 0, the number is positive. Otherwise, the number 
  // is negative.
  //
  pchBuffer = _ecvt( dblInput, 
                     50, 
                     &iDecimalPointAt, 
                     &iSign );

  int  iIndex = 0;
  memset( achOutput, 0, 60 );
  if ( iSign != 0 )
  {
    // if negative, put in the sign
    //
    achOutput[ 0 ] = '-';
    iIndex++; 
  }
 
  if ( iDecimalPointAt <= 0 )
  {
    // if decimal is first, then go this way
    //
    achOutput[ iIndex ] = '.';
    iIndex++; 
    strcat( achOutput, pchBuffer );
  }
  else
  {
    // decimal point embedded somewhere in the number
    // copy the whole part of the number first
    //
    for ( int iLoop = 0; iLoop < iDecimalPointAt; iLoop++ )
    {
      achOutput[ iIndex ] = pchBuffer[ iLoop ];
      iIndex++;
    }
    // slap in the decimal point, then copy the rest 
    // of the buffer
    //
    achOutput[ iIndex ] = '.';
    strcat( achOutput, pchBuffer + iDecimalPointAt );
  }

  char* pchDecimal = strchr( achOutput, '.' );
  if ( NULL != pchDecimal )
  {
    *( pchDecimal + iPrecision + 1 ) = 0;
  }

  // trim off trailing zeroes
  //
  int iTop = strlen( achOutput );
  while ( ( iTop > 1 ) 
       && ( achOutput[ iTop ] == '0' )
       && ( achOutput[ iTop - 1 ] == '0' ) )
  {
    achOutput[ iTop ] = 0;
    iTop--;
  } 

  vmstring* pchReturn = AllocateNewString( strlen( achOutput ) + 1, true );
  memset( pchReturn->str_data, 0, strlen( achOutput ) + 1 );
  strcpy( pchReturn->str_data, achOutput );
  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], pchReturn );
  m_poVirtualChip->m_psStackPointer += iArgc;
  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerDoubleToString"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerStringToInt

       DESCRIPTION:  converts a string to an integer value

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerStringToInt( int iArgc )
{
  m_poInterpreter->SetLastCall( "StringToInt" );

  char* pchInput = NULL;

  VerifyRunLineArguments( iArgc, 1 );
  VerifyElementType( 0, DT_STRING );

  pchInput = m_poVirtualChip->m_psStackPointer[0].v.v_string->str_data;

  SetValue( &m_poVirtualChip->m_psStackPointer[iArgc], atol( pchInput ) );
  
  m_poVirtualChip->m_psStackPointer += iArgc;
  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerStringToInt"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerStringToDouble

       DESCRIPTION:  converts a string to an integer value

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerStringToDouble( int iArgc )
{
  m_poInterpreter->SetLastCall( "StringToDouble" );

  char* pchInput = NULL;

  VerifyRunLineArguments( iArgc, 1 );
  VerifyElementType( 0, DT_STRING );

  pchInput = m_poVirtualChip->m_psStackPointer[0].v.v_string->str_data;

  SetValue( &m_poVirtualChip->m_psStackPointer[iArgc], atof( pchInput ) );
  
  m_poVirtualChip->m_psStackPointer += iArgc;
  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerStringToDouble"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerFillString

       DESCRIPTION:  fills a string with a given character

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerFillString( int iArgc )
{
  m_poInterpreter->SetLastCall( "FillString" );

  char*  pchTarget;
  char*  pchFillChar;

  VerifyRunLineArguments( iArgc, 4 );

  VerifyElementType( 3, DT_STRING );
  VerifyElementType( 2, DT_INTEGER );
  VerifyElementType( 1, DT_INTEGER );
  VerifyElementType( 0, DT_STRING );

  unsigned int lTargetSize = m_poVirtualChip->m_psStackPointer[3].v.v_string->str_size;
  long         lStartAt    = m_poVirtualChip->m_psStackPointer[2].v.v_integer;
  unsigned int lSpanFor    = m_poVirtualChip->m_psStackPointer[1].v.v_integer;
  long         lFillSize   = m_poVirtualChip->m_psStackPointer[0].v.v_string->str_size;

  pchTarget   = m_poVirtualChip->m_psStackPointer[3].v.v_string->str_data;
  pchFillChar = m_poVirtualChip->m_psStackPointer[0].v.v_string->str_data;

  if ( lStartAt + lSpanFor < lTargetSize )
  {
    unsigned int iLoop;
    unsigned int jLoop;

    for ( iLoop = 0; iLoop <= lSpanFor; iLoop += jLoop )
    {
      for ( jLoop = 0; 
            ( ( jLoop < strlen( pchFillChar ) ) && ( ( iLoop + jLoop ) <= lSpanFor ) ); 
            jLoop++ )
      {
        *( pchTarget + lStartAt + iLoop + jLoop ) = *( pchFillChar + jLoop );
      }
    }
    lTargetSize = strlen( pchTarget );

    SetValue( &m_poVirtualChip->m_psStackPointer[iArgc],
              m_poVirtualChip->m_psStackPointer[3].v.v_string );
  }
  else
  {
    lTargetSize = lStartAt + lSpanFor + 1;
    vmstring* pchReturn = AllocateNewString( lTargetSize, true );
    memset( pchReturn->str_data, 0, lTargetSize );

    strcpy( pchReturn->str_data, 
            m_poVirtualChip->m_psStackPointer[3].v.v_string->str_data );

    pchTarget   = pchReturn->str_data;
    pchFillChar = m_poVirtualChip->m_psStackPointer[0].v.v_string->str_data;

    unsigned int iLoop;
    unsigned int jLoop;
    for ( iLoop = 0; iLoop <= lSpanFor; iLoop += jLoop )
    {
      for ( jLoop = 0; 
             ( ( jLoop < strlen( pchFillChar ) ) && ( ( iLoop + jLoop ) <= lSpanFor ) ); 
             jLoop++ )
      {
        *( pchTarget + lStartAt + iLoop + jLoop ) = *( pchFillChar + jLoop );
      }
    }
    lTargetSize = strlen( pchReturn->str_data );

    SetValue( &m_poVirtualChip->m_psStackPointer[iArgc], pchReturn );
  }

  m_poVirtualChip->m_psStackPointer += iArgc;
  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerFillString"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerIndexOf

       DESCRIPTION:  determines the first index at which a character sequence
                     appears in a string

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerIndexOf( int iArgc )
{
  m_poInterpreter->SetLastCall( "IndexOf" );

  char*  pchScanThis = NULL;
  char*  pchLookFor  = NULL;
  long   lResult;

  VerifyRunLineArguments( iArgc, 2 );
  VerifyElementType( 1, DT_STRING );
  VerifyElementType( 0, DT_STRING );

  pchScanThis = m_poVirtualChip->m_psStackPointer[1].v.v_string->str_data;
  pchLookFor  = m_poVirtualChip->m_psStackPointer[0].v.v_string->str_data;

  char* pchOffset = strstr( pchScanThis, pchLookFor );
  if ( NULL != pchOffset )
  {
    lResult = pchOffset - pchScanThis;
  }
  else
  {
    lResult = -1;
  }
  SetValue( &m_poVirtualChip->m_psStackPointer[iArgc], lResult );

  m_poVirtualChip->m_psStackPointer += iArgc;
  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerIndexOf"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerTrimString

       DESCRIPTION:  provides trim functionality for string objects

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerTrimString( int iArgc )
{
  m_poInterpreter->SetLastCall( "TrimString" );

  char*       pchTrimThis = NULL;
  char*       pchTrimCode = NULL;

  VerifyRunLineArguments( iArgc, 2 );
  VerifyElementType( 1, DT_STRING );
  VerifyElementType( 0, DT_STRING );

  pchTrimThis      = m_poVirtualChip->m_psStackPointer[1].v.v_string->str_data;
  long lTrimSize   = strlen( pchTrimThis );
  pchTrimCode      = m_poVirtualChip->m_psStackPointer[0].v.v_string->str_data;

  char* pchLeft = pchTrimThis;

  if ( pchTrimCode[ 0 ] == 'l' || pchTrimCode[ 0 ] == 'b' )
  { 
    while ( *pchLeft == ' ' )
    {
      pchLeft++;
    }
    strcpy( m_poVirtualChip->m_psStackPointer[ 1 ].v.v_string->str_data, pchLeft );
  }

  if ( pchTrimCode[ 0 ] == 'r' || pchTrimCode[ 0 ] == 'b' )
  {
    int iTop = strlen( m_poVirtualChip->m_psStackPointer[ 1 ].v.v_string->str_data ) - 1;
    for( int iLoop = iTop; iLoop >= 0; iLoop-- )
    {
      if ( isspace( m_poVirtualChip->m_psStackPointer[ 1 ].v.v_string->str_data[ iLoop ] ) )
      {
        m_poVirtualChip->m_psStackPointer[ 1 ].v.v_string->str_data[ iLoop ] = 0;
      }
      else
      {
        break;
      }
    }
  }

  SetValue( &m_poVirtualChip->m_psStackPointer[iArgc], 
            m_poVirtualChip->m_psStackPointer[ 1 ].v.v_string );

  m_poVirtualChip->m_psStackPointer += iArgc;
  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerTrimString"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerStringLength

       DESCRIPTION:  returns the length of the given string

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerStringLength( int iArgc )
{
  m_poInterpreter->SetLastCall( "StringLength" );

  VerifyRunLineArguments( iArgc, 1 );
  VerifyElementType( 0, DT_STRING );

  SetValue( &m_poVirtualChip->m_psStackPointer[iArgc], 
            (long)strlen( m_poVirtualChip->m_psStackPointer[0].v.v_string->str_data ) );

  m_poVirtualChip->m_psStackPointer += iArgc;
  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerStringLength"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerToLower

       DESCRIPTION:  converts the inbound string to lower case

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerToLower( int iArgc )
{
  m_poInterpreter->SetLastCall( "ToLower" );

  char* pchInput = NULL;

  VerifyRunLineArguments( iArgc, 1 );
  VerifyElementType( 0, DT_STRING );

  pchInput            = m_poVirtualChip->m_psStackPointer[0].v.v_string->str_data;
  unsigned long lSize = strlen( pchInput );

  for ( unsigned int iLoop = 0; iLoop < lSize; iLoop++ )
  {
    *(pchInput + iLoop ) = tolower( *(pchInput + iLoop ) );
  }
  
  SetValue( &m_poVirtualChip->m_psStackPointer[iArgc],
            m_poVirtualChip->m_psStackPointer[0].v.v_string );

  m_poVirtualChip->m_psStackPointer += iArgc;
  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerToLower"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerToUpper

       DESCRIPTION:  converts the inbound string to upper case

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerToUpper( int iArgc )
{
  m_poInterpreter->SetLastCall( "ToUpper" );

  char* pchInput = NULL;

  VerifyRunLineArguments( iArgc, 1 );
  VerifyElementType( 0, DT_STRING );

  pchInput            = m_poVirtualChip->m_psStackPointer[0].v.v_string->str_data;
  unsigned long lSize = strlen( pchInput );

  for ( unsigned int iLoop = 0; iLoop < lSize; iLoop++ )
  {
    *(pchInput + iLoop ) = toupper( *(pchInput + iLoop ) );
  }

  SetValue( &m_poVirtualChip->m_psStackPointer[iArgc],
            m_poVirtualChip->m_psStackPointer[0].v.v_string );

  m_poVirtualChip->m_psStackPointer += iArgc;
  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerToUpper"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerSubString

       DESCRIPTION:  returns a section of a string to the caller

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerSubString( int iArgc )
{
  m_poInterpreter->SetLastCall( "SubString" );

  char* pchInput  = NULL;

  VerifyRunLineArguments( iArgc, 3 );
  VerifyElementType( 2, DT_STRING );
  VerifyElementType( 1, DT_INTEGER );
  VerifyElementType( 0, DT_INTEGER );

  pchInput = m_poVirtualChip->m_psStackPointer[2].v.v_string->str_data;

  unsigned long ulStartAt  = m_poVirtualChip->m_psStackPointer[1].v.v_integer;
  unsigned long ulSpanFor  = m_poVirtualChip->m_psStackPointer[0].v.v_integer;

  vmstring*  pchReturn;
  if ( 0 < ulSpanFor )
  {
    pchReturn = AllocateNewString( ulSpanFor + 1, true );

    memset( pchReturn->str_data, 0, ulSpanFor + 1 );

    if ( ( ulStartAt + ulSpanFor ) < strlen( pchInput ) )
    {
      strncpy( pchReturn->str_data, 
               pchInput + ulStartAt, 
               ulSpanFor );
    }
    else
    if ( ( ulStartAt < strlen( pchInput ) ) && ( 0 < ulSpanFor - ulStartAt ) )
    {
      strncpy( pchReturn->str_data, 
               pchInput + ulStartAt, 
               strlen( pchInput ) - ulStartAt );
    }
  }
  else
  {
    pchReturn = AllocateNewString( 0, true );
  }

  SetValue( &m_poVirtualChip->m_psStackPointer[iArgc], pchReturn );

  m_poVirtualChip->m_psStackPointer += iArgc;
  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerSubString"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerStringGetAt

       DESCRIPTION:  gets the character at a specific position in a string

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerStringGetAt( int iArgc )
{
  m_poInterpreter->SetLastCall( "StringGetAt" );

  char* pchInput = NULL;
  char  achOutput[2];

  VerifyRunLineArguments( iArgc, 2 );
  VerifyElementType( 1, DT_STRING );

  ZeroMemory( achOutput, 2 );

  long lSize = m_poVirtualChip->m_psStackPointer[1].v.v_string->str_size + 2;
  pchInput = m_poVirtualChip->m_psStackPointer[1].v.v_string->str_data;

  unsigned long ulOffset  = m_poVirtualChip->m_psStackPointer[0].v.v_integer;

  if ( ( 0 <= ulOffset ) && ( ulOffset < strlen( pchInput ) ) )
  {
    *achOutput = *(pchInput + ulOffset );
  }

  vmstring* pchReturn = AllocateNewString( strlen( achOutput ), true );
  strcpy(  pchReturn->str_data, achOutput );
  SetValue( &m_poVirtualChip->m_psStackPointer[iArgc], pchReturn );

  m_poVirtualChip->m_psStackPointer += iArgc;
  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerStringGetAt"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerStringConcat

       DESCRIPTION:  concatenates 2 strings into 1

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerStringConcat( int iArgc )
{
  m_poInterpreter->SetLastCall( "StringConcat" );

  VerifyRunLineArguments( iArgc, 2 );
  VerifyElementType( 1, DT_STRING );
  VerifyElementType( 0, DT_STRING );

  unsigned int lSizeOne = m_poVirtualChip->m_psStackPointer[1].v.v_string->str_size;
  long         lSizeTwo = m_poVirtualChip->m_psStackPointer[0].v.v_string->str_size;

  if ( lSizeOne 
       > strlen( m_poVirtualChip->m_psStackPointer[1].v.v_string->str_data ) 
         + strlen( m_poVirtualChip->m_psStackPointer[0].v.v_string->str_data ) )
  {
    strcat( m_poVirtualChip->m_psStackPointer[1].v.v_string->str_data,
            m_poVirtualChip->m_psStackPointer[0].v.v_string->str_data );

    SetValue( &m_poVirtualChip->m_psStackPointer[iArgc],
              m_poVirtualChip->m_psStackPointer[1].v.v_string );
  }
  else
  {
    vmstring* pchReturn = AllocateNewString( lSizeOne + lSizeTwo + 1, true );
    strcpy( pchReturn->str_data,
            m_poVirtualChip->m_psStackPointer[1].v.v_string->str_data );
   
    strcat( pchReturn->str_data,
            m_poVirtualChip->m_psStackPointer[0].v.v_string->str_data );

    m_poVirtualChip->m_psStackPointer[1].v.v_string = pchReturn;

    SetValue( &m_poVirtualChip->m_psStackPointer[iArgc],
              pchReturn );
  }
  m_poVirtualChip->m_psStackPointer += iArgc;
  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerStringConcat"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerPutQuote

       DESCRIPTION:  slaps a quote onto the end of a string

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerPutQuote( int iArgc )
{
  m_poInterpreter->SetLastCall( "PutQuote" );

  VerifyRunLineArguments( iArgc, 1 );
  VerifyElementType( 0, DT_STRING );

  long lSize   = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_string->str_size;
  long lLength = strlen( m_poVirtualChip->m_psStackPointer[ 0 ].v.v_string->str_data );
  if ( lSize > lLength + 1 )
  {
    char* pchPutAt = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_string->str_data + lLength;
    *pchPutAt = '"';

    SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ],
              m_poVirtualChip->m_psStackPointer[ 0 ].v.v_string );
  }
  else
  {
    vmstring* pchReturn = AllocateNewString( lSize + 2, true );
    strcpy( pchReturn->str_data,
            m_poVirtualChip->m_psStackPointer[ 0 ].v.v_string->str_data );
   
    char* pchPutAt = pchReturn->str_data + lLength;
    *pchPutAt = '"';

    SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], pchReturn );
  }

  m_poVirtualChip->m_psStackPointer += iArgc;
  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerPutQuote"
/*****************************************************************************/


/*****************************************************************************/
/*

     FUNCTION NAME:  VMVirtualOpSys::HandlerPadLeft

       DESCRIPTION:  inserts a given number of spaces to the left of a given
                     string

             INPUT:  iArgc - count of arguments passed to this
            OUTPUT:  none

           RETURNS:  0
*/
int VMVirtualOpSys::HandlerPadLeft( int iArgc )
{
  m_poInterpreter->SetLastCall( "PadLeft" );

  VerifyRunLineArguments( iArgc, 2 );
  VerifyElementType( 1, DT_STRING );
  VerifyElementType( 0, DT_INTEGER );

  char* pchBase = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_string->str_data;

  long lSize = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_string->str_size;
  long lPad  = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_integer;
  long lLength = strlen( pchBase ) + 1;
  long lPaddedSize = lLength + lPad;

  if ( lSize > lPaddedSize + 1 )
  {
    for ( int iLoop = lLength; iLoop >= 0; iLoop-- )
    {
      pchBase[ iLoop + lPad ] = pchBase[ iLoop ]; 
    } 
    memset( pchBase, ' ', lPad );

    SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ],
              m_poVirtualChip->m_psStackPointer[ 0 ].v.v_string );
  }
  else
  {
    vmstring* pchReturn = AllocateNewString( lPaddedSize + 2, true );
    memset( pchReturn->str_data, ' ', lPad );
    strcat( pchReturn->str_data,
            m_poVirtualChip->m_psStackPointer[ 1 ].v.v_string->str_data );
   
    SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], pchReturn );
  }

  m_poVirtualChip->m_psStackPointer += iArgc;
  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerPadLeft"
/*****************************************************************************/


/*****************************************************************************/
/*

     FUNCTION NAME:  VMVirtualOpSys::HandlerPadRight

       DESCRIPTION:  adds a given number of spaces after the given string

             INPUT:  iArgc - count of arguments passed to this
            OUTPUT:  none

           RETURNS:  0
*/
int VMVirtualOpSys::HandlerPadRight( int iArgc )
{
  m_poInterpreter->SetLastCall( "PadRight" );

  VerifyRunLineArguments( iArgc, 2 );
  VerifyElementType( 1, DT_STRING );
  VerifyElementType( 0, DT_INTEGER );

  char* pchBase = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_string->str_data;

  long lSize = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_string->str_size;
  long lPad  = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_integer;
  long lLength = strlen( pchBase ) + 1;
  long lPaddedSize = lLength + lPad;

  if ( lSize > lPaddedSize + 1 )
  {
    memset( pchBase + lLength, ' ', lPad );

    SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ],
              m_poVirtualChip->m_psStackPointer[ 0 ].v.v_string );
  }
  else
  {
    vmstring* pchReturn = AllocateNewString( lPaddedSize + 2, true );
    strcpy( pchReturn->str_data,
            m_poVirtualChip->m_psStackPointer[ 1 ].v.v_string->str_data );
    memset( pchReturn->str_data + lLength - 1, ' ', lPad );
   
    SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], pchReturn );
  }

  m_poVirtualChip->m_psStackPointer += iArgc;
  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerPadRight"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerBoundedStringReplace

       DESCRIPTION:  Replaces a specified range of text with the new string
                     given

             INPUT:  iArgc - the number of arguments on the stack for this method
            OUTPUT:  none

           RETURNS:  0
*/
int VMVirtualOpSys::HandlerBoundedStringReplace( int iArgc )
{
  m_poInterpreter->SetLastCall( "BoundedStringReplace" );

  vmstring* pchReturn;
  char*     pchInputOne = NULL;
  char*     pchInputTwo = NULL;
  char*     pchOutput   = NULL;

  VerifyRunLineArguments( iArgc, 4 );
  VerifyElementType( 3, DT_STRING );
  VerifyElementType( 2, DT_INTEGER );
  VerifyElementType( 1, DT_INTEGER );
  VerifyElementType( 0, DT_STRING );

  unsigned int lSizeOne;
  lSizeOne    = m_poVirtualChip->m_psStackPointer[3].v.v_string->str_size;
  pchInputOne = m_poVirtualChip->m_psStackPointer[3].v.v_string->str_data;

  unsigned int lSizeTwo;
  lSizeTwo    = m_poVirtualChip->m_psStackPointer[0].v.v_string->str_size;
  pchInputTwo = m_poVirtualChip->m_psStackPointer[0].v.v_string->str_data;

  unsigned long ulStartAt = m_poVirtualChip->m_psStackPointer[2].v.v_integer;
  unsigned long ulStopAt  = m_poVirtualChip->m_psStackPointer[1].v.v_integer;

  // if the length of what is being "put in" is greater than what is
  // available in the buffer
  //
  if ( lSizeOne - strlen( pchInputOne ) < lSizeTwo )
  {
    // get a new buffer
    //
    pchReturn = AllocateNewString( lSizeOne + lSizeTwo + ( ulStopAt - ulStartAt ) + 1, true );
    pchOutput = pchReturn->str_data;
    memset( pchOutput, 0, lSizeOne + lSizeTwo + ( ulStopAt - ulStartAt ) + 1 );

    strncpy( pchOutput, pchInputOne, ulStartAt );
    strcat( pchOutput, pchInputTwo );

    long lAfterCopyBegin = ulStopAt;
    strcat( pchOutput, 
            pchInputOne + lAfterCopyBegin );
  }
  else
  {
    // work with the existing buffer
    //
    pchReturn = m_poVirtualChip->m_psStackPointer[3].v.v_string;
    pchOutput = pchInputOne;

    if ( lSizeTwo < ulStopAt - ulStartAt )
    {
      // put the new characters into the insert location
      //
      memcpy( pchOutput + ulStartAt, pchInputTwo, lSizeTwo );

      // slide the remainder of the original buffer to the left
      //
      memmove( pchOutput + ulStartAt + lSizeTwo,
               pchOutput + ulStopAt,
               lSizeOne - ulStopAt );
      *(pchOutput + lSizeOne - ( ulStopAt - ulStartAt ) - lSizeTwo) = 0;
    }
    else
    if ( lSizeTwo == ulStopAt - ulStartAt )
    {
      // simple, straight replacement
      //
      memcpy( &pchOutput[ ulStartAt ],
              pchInputTwo,
              lSizeTwo );
    }
    else
    if ( lSizeTwo > ulStopAt - ulStartAt )
    {
      // must slide buffer from ulStopAt to end 
      // to the right to make room for the new characters
      //
      int iRightToEnd = lSizeOne - ulStopAt;

      // take the characters starting at the right hand end point, 
      // and slide them to the right by enough characters to
      // make room for the inbound characters
      //
      memmove( pchOutput + ulStopAt + ( lSizeTwo - ( ulStopAt - ulStartAt ) ),
               pchOutput + ulStopAt,
               iRightToEnd );

      // move in the new characters
      //
      memcpy( pchOutput + ulStartAt,
              pchInputTwo,
              lSizeTwo );

    }
  }

  SetValue( &m_poVirtualChip->m_psStackPointer[iArgc], pchReturn );

  m_poVirtualChip->m_psStackPointer += iArgc;
  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerBoundedStringReplace"
/*****************************************************************************/


/*****************************************************************************/
/*

     FUNCTION NAME:  VMVirtualOpSys::HandlerTrimQuotes

       DESCRIPTION:  Will trim quotes from the ends of a string

             INPUT:  int iArgc  
            OUTPUT:  none

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerTrimQuotes( int iArgc )
{
  m_poInterpreter->SetLastCall( "TrimQuotes" );

  VerifyRunLineArguments( iArgc, 1 );
  VerifyElementType( 0, DT_STRING );

  long  lSize    = m_poVirtualChip->m_psStackPointer[0].v.v_string->str_size;
  char* pchInput = m_poVirtualChip->m_psStackPointer[0].v.v_string->str_data;

  char* pchQuote = strchr(pchInput, '"');

  if (pchQuote != NULL)
  {
    // trim the left with a memmove....
    //
    pchQuote++;
    lSize -= (pchQuote - pchInput);
    memmove( pchInput, pchQuote, lSize );
  }

  pchQuote = strchr(pchInput, '"');
  if (pchQuote != NULL)
  {
    *pchQuote = 0;
  }    

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], 
	          m_poVirtualChip->m_psStackPointer[0].v.v_string );  
  m_poVirtualChip->m_psStackPointer += iArgc;
  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerTrimQuotes"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerCopyString

       DESCRIPTION:  replaces a range of characters in a string with the contents
                     of another string

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerCopyString( int iArgc )
{
  m_poInterpreter->SetLastCall( "StringCopy" );

  vmstring* pchReturn;
  char*     pchOutput;
  char*     pchInput = NULL;

  VerifyRunLineArguments( iArgc, 1 );
  VerifyElementType( 0, DT_STRING );

  long lSize = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_string->str_size;
  pchInput   = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_string->str_data;


  pchReturn = AllocateNewString( lSize + 1, true );
  pchOutput = pchReturn->str_data;
  memset( pchOutput, 0, lSize + 1 );

  strcpy( pchOutput, pchInput );

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], pchReturn );

  m_poVirtualChip->m_psStackPointer += iArgc;
  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerCopyString"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerStringFindFirstDigitIndex

       DESCRIPTION:  finds the first occurance of any digit in a string

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerStringFindFirstDigitIndex( int iArgc )
{
  m_poInterpreter->SetLastCall( "StringFindFirstDigitIndex" );

  char*     pchCoreString = NULL;

  VerifyRunLineArguments( iArgc, 1 );
  VerifyElementType( 0, DT_STRING );

  pchCoreString = m_poVirtualChip->m_psStackPointer[0].v.v_string->str_data;

  int iTop   = strlen( pchCoreString );
  int iIndex = -1;
  for ( int iLoop = 0; iLoop < iTop; iLoop++ )
  {
    if ( '0' <= pchCoreString[ iLoop ] && '9' >= pchCoreString[ iLoop ] )
    {
      iIndex = iLoop;
      break;
    }
  }

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], iIndex );

  m_poVirtualChip->m_psStackPointer += iArgc;
  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerStringFindFirstDigitIndex"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerReplaceSubString

       DESCRIPTION:  replaces a range of characters in a string with the contents
                     of another string

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerReplaceSubString( int iArgc )
{
  m_poInterpreter->SetLastCall( "StringSwapOutSubString" );

  vmstring* pchReturn;
  char*     pchCoreString = NULL;
  char*     pchSwapOut    = NULL;
  char*     pchSwapIn     = NULL;
  char*     pchOutput     = NULL;

  VerifyRunLineArguments( iArgc, 3 );
  VerifyElementType( 2, DT_STRING );
  VerifyElementType( 1, DT_STRING );
  VerifyElementType( 0, DT_STRING );

  pchSwapOut    = m_poVirtualChip->m_psStackPointer[1].v.v_string->str_data;
  pchSwapIn     = m_poVirtualChip->m_psStackPointer[0].v.v_string->str_data;
  pchCoreString = m_poVirtualChip->m_psStackPointer[2].v.v_string->str_data;

  long lNewSize = strlen( pchSwapOut ) + strlen( pchSwapIn ) + strlen( pchCoreString );

  pchReturn = AllocateNewString( lNewSize + 4, true );
  pchOutput = pchReturn->str_data;
  memset( pchOutput, 0, lNewSize + 4 );

  char* pchSwapPoint = strstr( pchCoreString, pchSwapOut );

  if ( NULL != pchSwapPoint )
  {
    char* pchSwapPointEnd = pchSwapPoint + strlen( pchSwapOut );

    strncpy( pchOutput, pchCoreString, pchSwapPoint - pchCoreString );
    pchOutput[ pchSwapPoint - pchCoreString ] = 0;
    strcat( pchOutput, pchSwapIn );
    strcat( pchOutput, pchSwapPointEnd );
  }
  else
  {
    strcpy( pchOutput, pchCoreString );
  }

  SetValue( &m_poVirtualChip->m_psStackPointer[iArgc],
            pchReturn );

  m_poVirtualChip->m_psStackPointer += iArgc;
  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerReplaceSubString"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerStringReplace

       DESCRIPTION:  replaces a range of characters in a string with the contents
                     of another string

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerStringReplace( int iArgc )
{
  m_poInterpreter->SetLastCall( "StringReplace" );

  vmstring* pchReturn;
  char*     pchInputOne = NULL;
  char*     pchInputTwo = NULL;
  char*     pchOutput   = NULL;

  VerifyRunLineArguments( iArgc, 3 );
  VerifyElementType( 2, DT_STRING );
  VerifyElementType( 1, DT_INTEGER );
  VerifyElementType( 0, DT_STRING );

  unsigned int lSizeOne;
  lSizeOne    = m_poVirtualChip->m_psStackPointer[2].v.v_string->str_size;
  pchInputOne = m_poVirtualChip->m_psStackPointer[2].v.v_string->str_data;

  unsigned int lSizeTwo;
  lSizeTwo    = m_poVirtualChip->m_psStackPointer[0].v.v_string->str_size;
  pchInputTwo = m_poVirtualChip->m_psStackPointer[0].v.v_string->str_data;

  unsigned long ulStartAt  = m_poVirtualChip->m_psStackPointer[1].v.v_integer;

  // if what is being "put in" is larger than the buffer has space for
  //
  if ( lSizeOne - strlen( pchInputOne ) < lSizeTwo )
  {
    pchReturn = AllocateNewString( lSizeOne + lSizeTwo + 1, true );
    pchOutput = pchReturn->str_data;
    memset( pchOutput, 0, lSizeOne + lSizeTwo + 1 );
  }
  else
  {
    pchReturn = m_poVirtualChip->m_psStackPointer[2].v.v_string;
    pchOutput = pchInputOne;
  }

  strncpy( pchOutput, pchInputOne, ulStartAt );
  pchOutput[ ulStartAt ] = 0;
  strcat( pchOutput, pchInputTwo );
  strcat( pchOutput, pchInputOne + ulStartAt + strlen( pchInputTwo ) );

  SetValue( &m_poVirtualChip->m_psStackPointer[iArgc],
            pchReturn );

  m_poVirtualChip->m_psStackPointer += iArgc;
  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerStringReplace"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerStringCompare

       DESCRIPTION:  compares 2 strings....

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerStringCompare( int iArgc )
{
  m_poInterpreter->SetLastCall( "StringCompare" );

  char* pchString1 = NULL;
  char* pchString2 = NULL;

  VerifyRunLineArguments( iArgc, 2 );
  VerifyElementType( 1, DT_STRING );
  VerifyElementType( 0, DT_STRING );

  pchString1 = m_poVirtualChip->m_psStackPointer[1].v.v_string->str_data;
  pchString2 = m_poVirtualChip->m_psStackPointer[0].v.v_string->str_data;

  SetValue( &m_poVirtualChip->m_psStackPointer[iArgc], (int)strcmp( pchString1, pchString2 ) );

  m_poVirtualChip->m_psStackPointer += iArgc;
  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerStringCompare"
/*****************************************************************************/


/*****************************************************************************/
/*

     FUNCTION NAME:  VMVirtualOpSys::HandlerEcho

       DESCRIPTION:  generic print function

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerEcho( int iArgc )
{
  m_poInterpreter->SetLastCall( "Echo" );

  int n;
  for ( n = iArgc; --n >= 0; )
  {
    PrintOneArg( stdout, FALSE, &m_poVirtualChip->m_psStackPointer[ n ] );
  }

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], iArgc );
  m_poVirtualChip->m_psStackPointer += iArgc;

  return 0;
}
/* End of function "VMVirtualOpSys::HandlerEcho"
/*****************************************************************************/


/*****************************************************************************/
/*

     FUNCTION NAME:  VMVirtualOpSys::HandlerSleep

       DESCRIPTION:  puts the currently executing script to sleep

             INPUT:  iArgc - the stacked parameter count for htis method 
            OUTPUT:  none

           RETURNS:  0
*/
int VMVirtualOpSys::HandlerSleep( int iArgc )
{
  m_poInterpreter->SetLastCall( "Sleep" );

  VerifyRunLineArguments( iArgc, 1 );

  if ( m_poVirtualChip->m_psStackPointer[ 0 ].v_type == DT_INTEGER )
  {
    Sleep( m_poVirtualChip->m_psStackPointer[ 0 ].v.v_integer );
  }
  else
  if ( m_poVirtualChip->m_psStackPointer[ 0 ].v_type == DT_DWORD )
  {
    Sleep( m_poVirtualChip->m_psStackPointer[ 0 ].v.v_dword );
  }
 
  SetValue( &m_poVirtualChip->m_psStackPointer[iArgc], 1 );

  m_poVirtualChip->m_psStackPointer += iArgc;
  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerSleep"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerStringFormat

       DESCRIPTION:  performs sprintf like functionality

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerStringFormat( int iArgc )
{
  m_poInterpreter->SetLastCall( "StringFormat" );

  int        iNumPercents = 0;
  char*      pchFormatString;
  char       achOutputString[8096];
  char*      pcChar;
  int        iCurrentArgument = iArgc - 2;
  int        iCopyToPosition  = 0;
  char*      pChar;
  int        len;
  VMVARIANT* pxClass;
  char       achAM_PM[] = "AM";

  memset( achOutputString, 0, sizeof( achOutputString ) );

  if ( iArgc >= 1 )
  {
    VerifyElementType( iArgc - 1, DT_STRING );
    pchFormatString = m_poVirtualChip->m_psStackPointer[ iArgc - 1 ].v.v_string->str_data;
    pcChar          = pchFormatString;
   
    // count the number of arguments to expect from the call
    //
    do
    {
      if ( '%' == *pcChar ) 
      {
        if ( ( '%' != *(pcChar+1) ) && ( '%' != *(pcChar-1) ) )
        {
         iNumPercents++;
        }
      }
      pcChar++;
    } while ( *pcChar != '\0' );

    pcChar = pchFormatString;

    // target_buffer, "format string with n % symbols", args....
    // since number of args must equal number % symbols, then
    // the total number of input arguments must be :
    // iNumPercents + 1
    //
    if ( iArgc >= iNumPercents + 1 )
    {
      do
      {
        if ( '%' == *pcChar )
        {
          if ( '%' == *(pcChar + 1) )
          {
            pcChar++;
            achOutputString[iCopyToPosition] = *pcChar;
            iCopyToPosition++;
          }
          else
          {
            char  achToAppend[1024];
            char  achTemp[1024];
            switch( m_poVirtualChip->m_psStackPointer[iCurrentArgument].v_type )
            {
              case DT_NIL:
              {
                strcpy( achToAppend, "nil" );
              }
              break;

              case DT_CLASS:
              {
                GetCStyleString( achTemp, 
                                 sizeof( achTemp ), 
                                 clgetname( &m_poVirtualChip->m_psStackPointer[iCurrentArgument] ) );
                sprintf( achToAppend, "#<Class-%s>", achTemp );
              }
              break;

              case DT_OBJECT:
              {
                sprintf( achToAppend, 
                         "#<Object-%lx>", 
                         objaddr( &m_poVirtualChip->m_psStackPointer[iCurrentArgument] ) );
              }
              break;

              case DT_IOSTREAM:
              {
                sprintf( achToAppend, 
                         "#<Stream-%lx>", 
                          objaddr( &m_poVirtualChip->m_psStackPointer[iCurrentArgument] ) );
              }
              break;

              case DT_USERVECTOR:
              {
                sprintf( achToAppend, 
                         "#<Vector-%lx>", 
                         uservecaddr( &m_poVirtualChip->m_psStackPointer[iCurrentArgument] ) );
              }
              break;

              case DT_INTEGER:
              {
                sprintf( achToAppend, 
                         "%ld", 
                         m_poVirtualChip->m_psStackPointer[iCurrentArgument].v.v_integer );
              }
              break;

              case DT_STRING:
              {
                pChar  = strgetdata( &m_poVirtualChip->m_psStackPointer[iCurrentArgument] );
                len    = strgetsize( &m_poVirtualChip->m_psStackPointer[iCurrentArgument] );
                strncpy( achToAppend, pChar, len );
                achToAppend[len] = 0;
              }
              break;

              case DT_BYTECODE:
              {
                sprintf( achToAppend, 
                         "#<Bytecode-%lx>", 
                         vecaddr( &m_poVirtualChip->m_psStackPointer[iCurrentArgument] ) );
              }
              break;

              case DT_CODE:
              {
                sprintf( achToAppend, 
                         "#<Code-%lx>", 
                         m_poVirtualChip->m_psStackPointer[iCurrentArgument].v.v_code );
              }
              break;

              case DT_VAR:
              {
                pxClass = digetclass( degetdictionary( &m_poVirtualChip->m_psStackPointer[iCurrentArgument] ) );
                if ( !isnil( pxClass ) ) 
                {
                  GetCStyleString( achTemp, 
                                   sizeof( achTemp ), 
                                   clgetname( pxClass ) );
                  sprintf( achToAppend, 
                           "%s::", 
                           achTemp );
                 }
                 GetCStyleString( achTemp, 
                                  sizeof( achTemp ), 
                                  degetkey( &m_poVirtualChip->m_psStackPointer[iCurrentArgument] ) );
                 strcat( achToAppend, achTemp );
              }
              break;

              case DT_FILE:
              {
                sprintf( achToAppend, 
                         "#<File-%lx>", 
                         m_poVirtualChip->m_psStackPointer[iCurrentArgument].v.v_fp );
              }
              break;

              case DT_KERNELHANDLE:
              {
                sprintf( achToAppend, 
                         "#<KernelHandle-0x%08x>", 
                         m_poVirtualChip->m_psStackPointer[iCurrentArgument].v.v_kernelhandle );
              }
              break;

              case DT_FILEFINDHANDLE:
              case DT_NTFILEHANDLE:
              case DT_HANDLE:
              {
                sprintf( achToAppend, 
                         "#<Handle-0x%08x>", 
                         m_poVirtualChip->m_psStackPointer[iCurrentArgument].v.v_handle );
              }
              break;

              case DT_DWORD:
              {
                sprintf( achToAppend,
                         "%ld",
                         m_poVirtualChip->m_psStackPointer[iCurrentArgument].v.v_dword );
              }
              break;

              case DT_DOUBLE:
              {
                sprintf( achToAppend,
                         "% 10.2f",
                         m_poVirtualChip->m_psStackPointer[iCurrentArgument].v.v_double );
              }
              break;

              case DT_BYTE:
              {
                sprintf( achToAppend,
                         "%s",
                         ( m_poVirtualChip->m_psStackPointer[iCurrentArgument].v.v_byte != 0 ) ? "true" : "false" );
              }
              break;

              case DT_DATETIME:
              {
                SYSTEMTIME xTime = m_poVirtualChip->m_psStackPointer[iCurrentArgument].v.v_datetime; 

                if ( xTime.wHour > 12 )        // Set up extension.
                  strcpy( achAM_PM, "PM" );
                else
                  strcpy( achAM_PM, "AM" );

                sprintf( achToAppend, 
                         "%02u/%02u/%04u %02u:%02u:%02u %s",
                         xTime.wMonth,
                         xTime.wDay,
                         xTime.wYear,
                         xTime.wHour,
                         xTime.wMinute,
                         xTime.wSecond,
                         achAM_PM );
              }
              break;

              case DT_QUEUE:
              {
                sprintf( achToAppend, 
                         "#<Queue-0x%08x>-count:%d", 
                         &m_poVirtualChip->m_psStackPointer[iCurrentArgument].v.v_queue,
                          m_poVirtualChip->m_psStackPointer[iCurrentArgument].v.v_queue->GetCount() );
              }
              break;

              case DT_STACK:
              {
                sprintf( achToAppend, 
                         "#<Stack-0x%08x>-count:%d", 
                         &m_poVirtualChip->m_psStackPointer[iCurrentArgument].v.v_stack,
                          m_poVirtualChip->m_psStackPointer[iCurrentArgument].v.v_stack->GetCount() );
              }
              break;

              case DT_HASHTABLE:
              {
                sprintf( achToAppend, 
                         "#<Map-0x%08x>-count:%d", 
                         &m_poVirtualChip->m_psStackPointer[iCurrentArgument].v.v_hashtable,
                          m_poVirtualChip->m_psStackPointer[iCurrentArgument].v.v_hashtable->GetCount() );
              }
              break;

              case DT_CALCULATOR:
              {
                sprintf( achToAppend, 
                         "#<Calculator-0x%08x>", 
                         &m_poVirtualChip->m_psStackPointer[iCurrentArgument].v.v_calculator );
              }
              break;

              case DT_TOKENIZER:
              {
                sprintf( achToAppend, 
                         "#<Tokenizer-0x%08x>", 
                         &m_poVirtualChip->m_psStackPointer[iCurrentArgument].v.v_tokenizer );
              }
              break;

              case DT_BYTEARRAY:
              {
                VMCharByteArray oBytes( (const char*)m_poVirtualChip->m_psStackPointer[iCurrentArgument].v.v_bytearray->GetData() );
                sprintf( achToAppend, oBytes.AsString() );
              }
              break;

              case DT_ODBC:
              {
                sprintf( achToAppend, 
                         "#<Database-0x%08x>", 
                         &m_poVirtualChip->m_psStackPointer[iCurrentArgument].v.v_odbc );
              }
              break;

              case DT_REPORTPAGE:
              {
                sprintf( achToAppend, 
                         "#<PageObject-0x%08x>", 
                         &m_poVirtualChip->m_psStackPointer[iCurrentArgument].v.v_page );
              }
              break;

              case DT_REPORTPAGEREGION:
              {
                sprintf( achToAppend, 
                         "#<PageRegion-0x%08x>", 
                         &m_poVirtualChip->m_psStackPointer[iCurrentArgument].v.v_pageregion );
              }
              break;

              case DT_REPORTTABLE:
              {
                sprintf( achToAppend, 
                         "#<PageTable-0x%08x>", 
                         &m_poVirtualChip->m_psStackPointer[iCurrentArgument].v.v_pagetable );
              }
              break;

              case DT_COLOR:
              {
                sprintf( achToAppend, 
                         "RGB(%d,%d,%d)", 
                         GetRValue( m_poVirtualChip->m_psStackPointer[iCurrentArgument].v.v_color ),
                         GetGValue( m_poVirtualChip->m_psStackPointer[iCurrentArgument].v.v_color ),
                         GetBValue( m_poVirtualChip->m_psStackPointer[iCurrentArgument].v.v_color ) );
              }
              break;

              // mjs: thread pool new
              //
              case DT_THREAD_POOL:
              {
                sprintf( achToAppend, 
                         "#<ThreadPool-0x%08x>", 
                         &m_poVirtualChip->m_psStackPointer[iCurrentArgument].v.v_threadpool );
              }
              break;

              case DT_THREAD:
              {
                sprintf( achToAppend, 
                         "#<Thread-0x%08x>", 
                         &m_poVirtualChip->m_psStackPointer[iCurrentArgument].v.v_thread );
              }
              break;

              default:
              {
                 sprintf( achToAppend, 
                          "Undefined type: %d", valtype( &m_poVirtualChip->m_psStackPointer[iCurrentArgument] ) );
              }
              break;
            }
            strcat( achOutputString, achToAppend );
            iCopyToPosition += strlen( achToAppend );
            iCurrentArgument--;
          }
        }
        else
        {
          achOutputString[iCopyToPosition] = *pcChar;
          iCopyToPosition++;
        }
        pcChar++;
      } while ( *pcChar != '\0' );     
    }
  }

  vmstring* pchOutput = AllocateNewString( strlen( achOutputString ), true );
  strcpy( pchOutput->str_data, achOutputString );
  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], pchOutput );

  m_poVirtualChip->m_psStackPointer += iArgc;
  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerStringFormat"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerGetDate

       DESCRIPTION:  returns the current date time to the caller

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerGetDate( int iArgc )
{
  m_poInterpreter->SetLastCall( "GetDate" );

  VerifyRunLineArguments( iArgc, 0 );

  VMDateTime oNow = VMDateTime::CurrentTime();

  SYSTEMTIME xNow = oNow.GetTime();
  SetValue( &m_poVirtualChip->m_psStackPointer[iArgc], xNow );
  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerGetDate"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerDateToString

       DESCRIPTION:  performs a formatted printed output of a time object

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerDateToString( int iArgc )
{
  m_poInterpreter->SetLastCall( "DateToString" );

  SYSTEMTIME  xBase;
  VMString    oReturn;

  VerifyRunLineArguments( iArgc, 2 );
  VerifyElementType( 1, DT_STRING );
  VerifyElementType( 0, DT_DATETIME );
   
  xBase  = m_poVirtualChip->m_psStackPointer[0].v.v_datetime;

  VMDateTime  oTime( xBase );

  oReturn = oTime.Format( m_poVirtualChip->m_psStackPointer[ 1 ].v.v_string->str_data );

  vmstring*  pchRead = AllocateNewString( oReturn.GetLength(), true );
  strcpy( pchRead->str_data, (const char*) oReturn );
  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], pchRead );
  m_poVirtualChip->m_psStackPointer += iArgc;
  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerDateToString"
/*****************************************************************************/


/*****************************************************************************/
/*

     FUNCTION NAME:  VMVirtualOpSys::HandlerDateCompare

       DESCRIPTION:  compares two date values

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerDateCompare( int iArgc )
{
  m_poInterpreter->SetLastCall( "DateCompare" );

  VerifyRunLineArguments( iArgc, 2 );
  VerifyElementType( 1, DT_DATETIME );
  VerifyElementType( 0, DT_DATETIME );
   
  VMDateTime oLHS( m_poVirtualChip->m_psStackPointer[ 1 ].v.v_datetime );
  VMDateTime oRHS( m_poVirtualChip->m_psStackPointer[ 0 ].v.v_datetime );

  long lResult;

  if ( oLHS == oRHS )
  {
    lResult = 0;
  }
  else
  if ( oLHS < oRHS )
  {
    lResult = -1;
  }
  else
  if ( oLHS > oRHS )
  {
    lResult = 1;
  }

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], lResult );
  m_poVirtualChip->m_psStackPointer += iArgc;
  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerDateCompare"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerStringToDate

       DESCRIPTION:  performs a formatted printed output of a time object

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerStringToDate( int iArgc )
{
  m_poInterpreter->SetLastCall( "StringToDate" );

  SYSTEMTIME  xBase;
  bool        bIsGoodParse = true;

  // stamp a 'good time on this in case input does not parse
  //
  GetLocalTime( &xBase );

  VerifyRunLineArguments( iArgc, 1 );
  VerifyElementType( 0, DT_STRING );

  char* pchString = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_string->str_data;

  char* pchToken     = pchString;
  char* pchNextDelim = strchr( pchToken, '/' );

  if ( NULL != pchNextDelim )
  {
    *pchNextDelim = 0;
    xBase.wMonth = atoi( pchToken );
    *pchNextDelim = '/';
    pchToken = pchNextDelim + 1;
  }
  else
  {
    bIsGoodParse = false;
  }
    
  if ( true == bIsGoodParse )
  {
    char* pchNextDelim = strchr( pchToken, '/' );

    if ( NULL != pchNextDelim )
    {
      *pchNextDelim = 0;
      xBase.wDay = atoi( pchToken );
      *pchNextDelim = '/';
      pchToken = pchNextDelim + 1;
    }
    else
    {
      bIsGoodParse = false;
    }
  } 

  if ( true == bIsGoodParse )
  {
    char* pchNextDelim = strchr( pchToken, ' ' );

    if ( NULL != pchNextDelim )
    {
      *pchNextDelim = 0;
      xBase.wYear = atoi( pchToken );
      *pchNextDelim = ' ';
      pchToken = pchNextDelim + 1;
    }
    else
    {
      bIsGoodParse = false;
    }
  } 

  if ( true == bIsGoodParse )
  {
    char* pchNextDelim = strchr( pchToken, ':' );

    if ( NULL != pchNextDelim )
    {
      *pchNextDelim = 0;
      xBase.wHour = atoi( pchToken );
      *pchNextDelim = '/';
      pchToken = pchNextDelim + 1;
    }
    else
    {
      xBase.wHour = xBase.wMinute = xBase.wSecond = 0;
      bIsGoodParse = false;
    }
  } 

  if ( true == bIsGoodParse )
  {
    char* pchNextDelim = strchr( pchToken, ':' );

    if ( NULL != pchNextDelim )
    {
      *pchNextDelim = 0;
      xBase.wMinute = atoi( pchToken );
      *pchNextDelim = '/';
      pchToken = pchNextDelim + 1;
    }
    else
    {
      xBase.wMinute = xBase.wSecond = 0;
      bIsGoodParse = false;
    }
  } 

  if ( true == bIsGoodParse )
  {
    char achSeconds[ 3 ];
 
    strncpy( achSeconds, pchToken, 2 );
    achSeconds[ 2 ] = 0;

    xBase.wSecond = atoi( achSeconds );
  }
  else
  {
    xBase.wSecond = 0;
  } 

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], xBase );
  m_poVirtualChip->m_psStackPointer += iArgc;
  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerStringToDate"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerDateAdd

       DESCRIPTION:  adds a specific offset to a time_t object

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerDateAdd( int iArgc )
{
  m_poInterpreter->SetLastCall( "DateAdd" );

  SYSTEMTIME  xBase;
  long        lModBy;
  char*       pchModType;

  VerifyRunLineArguments( iArgc, 3 );
  VerifyElementType( 2, DT_STRING );
  VerifyElementType( 1, DT_DATETIME );
  VerifyElementType( 0, DT_INTEGER );
   
  xBase  = m_poVirtualChip->m_psStackPointer[1].v.v_datetime;
  lModBy = m_poVirtualChip->m_psStackPointer[0].v.v_integer;

  pchModType = m_poVirtualChip->m_psStackPointer[2].v.v_string->str_data;

  VMDateTime oBase( xBase );
   
  if ( !strcmp( pchModType, "dd" ) )
  {
    VMTimeOffset oOffset( lModBy, 0, 0, 0 );
    oBase += oOffset;
  }
  else
  if ( !strcmp( pchModType, "hh" ) ) 
  {
    VMTimeOffset oOffset( 0, lModBy, 0, 0 );
    oBase += oOffset;
  }
  else
  if ( !strcmp( pchModType, "mm" ) )
  {
    VMTimeOffset oOffset( 0, 0, lModBy, 0 );
    oBase += oOffset;
  }
  else
  if ( !strcmp( pchModType, "ss" ) ) 
  {
    VMTimeOffset oOffset( 0, 0, 0, lModBy );
    oBase += oOffset;
  }

  SYSTEMTIME xTime = oBase.GetTime();

  SetValue( &m_poVirtualChip->m_psStackPointer[iArgc], xTime );
  m_poVirtualChip->m_psStackPointer += iArgc;
  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerDateAdd"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerDateSub

       DESCRIPTION:  adds a specific offset to a time_t object

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerDateSub( int iArgc )
{
  m_poInterpreter->SetLastCall( "DateSub" );

  SYSTEMTIME  xBase;
  long        lModBy;
  char*       pchModType;

  VerifyRunLineArguments( iArgc, 3 );
  VerifyElementType( 2, DT_STRING );
  VerifyElementType( 1, DT_DATETIME );
  VerifyElementType( 0, DT_INTEGER );
   
  xBase  = m_poVirtualChip->m_psStackPointer[1].v.v_datetime;
  lModBy = m_poVirtualChip->m_psStackPointer[0].v.v_integer;

  pchModType = m_poVirtualChip->m_psStackPointer[2].v.v_string->str_data;

  VMDateTime oBase( xBase );
   
  if ( !strcmp( pchModType, "dd" ) )
  {
    VMTimeOffset oOffset( lModBy, 0, 0, 0 );
    oBase -= oOffset;
  }
  else
  if ( !strcmp( pchModType, "hh" ) ) 
  {
    VMTimeOffset oOffset( 0, lModBy, 0, 0 );
    oBase -= oOffset;
  }
  else
  if ( !strcmp( pchModType, "mm" ) )
  {
    VMTimeOffset oOffset( 0, 0, lModBy, 0 );
    oBase -= oOffset;
  }
  else
  if ( !strcmp( pchModType, "ss" ) ) 
  {
    VMTimeOffset oOffset( 0, 0, 0, lModBy );
    oBase -= oOffset;
  }

  SYSTEMTIME xTime = oBase.GetTime();

  SetValue( &m_poVirtualChip->m_psStackPointer[iArgc], xTime );
  m_poVirtualChip->m_psStackPointer += iArgc;
  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerDateSub"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerDateDiff

       DESCRIPTION:  returns the difference between two different date/time 
                     variables

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerDateDiff( int iArgc )
{
  m_poInterpreter->SetLastCall( "DateDiff" );

  char*       pchModType;
  SYSTEMTIME  xBaseOne;
  SYSTEMTIME  xBaseTwo;
  int         iReturn;

  VerifyRunLineArguments( iArgc, 3 );
  VerifyElementType( 2, DT_STRING );
  VerifyElementType( 1, DT_DATETIME );
  VerifyElementType( 0, DT_DATETIME );
   
  xBaseOne = m_poVirtualChip->m_psStackPointer[0].v.v_datetime;
  xBaseTwo = m_poVirtualChip->m_psStackPointer[1].v.v_datetime;

  VMDateTime  oBaseOne( xBaseOne );
  VMDateTime  oBaseTwo( xBaseTwo );

  pchModType = m_poVirtualChip->m_psStackPointer[2].v.v_string->str_data;

  VMTimeOffset oDiff = oBaseOne.GetTimeSpan( oBaseTwo );

  if ( !strcmp( pchModType, "yy" ) )
  {
    iReturn = oDiff.GetDays() / 365;
  }
  else
  if ( !strcmp( pchModType, "dd" ) )
  {
    iReturn = oDiff.GetDays();
  }
  else
  if ( !strcmp( pchModType, "hh" ) ) 
  {
    iReturn = oDiff.GetTotalHours();
  }
  else
  if ( !strcmp( pchModType, "mm" ) )
  {
    iReturn = oDiff.GetTotalMinutes();
  }
  else
  if ( !strcmp( pchModType, "ss" ) ) 
  {
    iReturn = oDiff.GetTotalSeconds();
  }

  SetValue( &m_poVirtualChip->m_psStackPointer[iArgc], iReturn );

  m_poVirtualChip->m_psStackPointer += iArgc;
  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerDateDiff"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerDatePart

       DESCRIPTION:  returns a specific component from a date object

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerDatePart( int iArgc )
{
  m_poInterpreter->SetLastCall( "DatePart" );

  SYSTEMTIME  xBase;
  char*       pchModType;
  long        lReturn = 0;

  VerifyRunLineArguments( iArgc, 2 );
  VerifyElementType( 1, DT_STRING );
  VerifyElementType( 0, DT_DATETIME );
   
  xBase  = m_poVirtualChip->m_psStackPointer[0].v.v_datetime;

  pchModType = m_poVirtualChip->m_psStackPointer[1].v.v_string->str_data;

  VMDateTime oBase( xBase );

  if ( !strcmp( pchModType, "yy" ) )
  {
    lReturn = oBase.GetYear();
  }
  else
  if ( !strcmp( pchModType, "mm" ) )
  {
    lReturn = oBase.GetMonth();
  }
  else
  if ( !strcmp( pchModType, "dw" ) )
  {
    lReturn = oBase.GetDayOfWeek();
  }
  else
  if ( !strcmp( pchModType, "dd" ) )
  {
    lReturn = oBase.GetDay();
  }
  else
  if ( !strcmp( pchModType, "hh" ) ) 
  {
    lReturn = oBase.GetHour();
  }
  else
  if ( !strcmp( pchModType, "MM" ) )
  {
    lReturn = oBase.GetMinute();
  }
  else
  if ( !strcmp( pchModType, "ss" ) ) 
  {
    lReturn = oBase.GetSecond();
  }

  SetValue( &m_poVirtualChip->m_psStackPointer[iArgc], lReturn );

  m_poVirtualChip->m_psStackPointer += iArgc;
  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerDatePart"
/*****************************************************************************/


/*****************************************************************************/
/*

     FUNCTION NAME:  VMVirtualOpSys::HandlerDateSetHourPart

       DESCRIPTION:  sets the H portions of the date to the value provided

             INPUT:  iArgc - number of arguments passed to this
            OUTPUT:  none

           RETURNS:  zero
*/
int VMVirtualOpSys::HandlerDateSetHourPart( int iArgc )
{
  m_poInterpreter->SetLastCall( "DateSetHourPart" );

  SYSTEMTIME xBase;

  VerifyRunLineArguments( iArgc, 2 );
  VerifyElementType( 1, DT_DATETIME );
  VerifyElementType( 0, DT_INTEGER );
   
  xBase       = m_poVirtualChip->m_psStackPointer[1].v.v_datetime;
  xBase.wHour = static_cast< WORD >( m_poVirtualChip->m_psStackPointer[0].v.v_integer );

  SetValue( &m_poVirtualChip->m_psStackPointer[iArgc], xBase );

  m_poVirtualChip->m_psStackPointer += iArgc;
  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerDateSetHourPart"
/*****************************************************************************/


/*****************************************************************************/
/*

     FUNCTION NAME:  VMVirtualOpSys::HandlerDateSetMinsPart

       DESCRIPTION:  sets the M portions of the date to the value provided

             INPUT:  iArgc - number of arguments passed to this
            OUTPUT:  none

           RETURNS:  zero
*/
int VMVirtualOpSys::HandlerDateSetMinsPart( int iArgc )
{
  m_poInterpreter->SetLastCall( "DateSetMinsPart" );

  SYSTEMTIME xBase;

  VerifyRunLineArguments( iArgc, 2 );
  VerifyElementType( 1, DT_DATETIME );
  VerifyElementType( 0, DT_INTEGER );
   
  xBase         = m_poVirtualChip->m_psStackPointer[1].v.v_datetime;
  xBase.wMinute = static_cast< WORD >( m_poVirtualChip->m_psStackPointer[0].v.v_integer );

  SetValue( &m_poVirtualChip->m_psStackPointer[iArgc], xBase );

  m_poVirtualChip->m_psStackPointer += iArgc;
  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerDateSetMinsPart"
/*****************************************************************************/


/*****************************************************************************/
/*

     FUNCTION NAME:  VMVirtualOpSys::HandlerDateSetSecsPart

       DESCRIPTION:  sets the S portions of the date to the value provided

             INPUT:  iArgc - number of arguments passed to this
            OUTPUT:  none

           RETURNS:  zero
*/
int VMVirtualOpSys::HandlerDateSetSecsPart( int iArgc )
{
  m_poInterpreter->SetLastCall( "DateSetSecsPart" );

  SYSTEMTIME xBase;

  VerifyRunLineArguments( iArgc, 2 );
  VerifyElementType( 1, DT_DATETIME );
  VerifyElementType( 0, DT_INTEGER );
   
  xBase         = m_poVirtualChip->m_psStackPointer[1].v.v_datetime;
  xBase.wSecond = static_cast< WORD >( m_poVirtualChip->m_psStackPointer[0].v.v_integer );

  SetValue( &m_poVirtualChip->m_psStackPointer[iArgc], xBase );

  m_poVirtualChip->m_psStackPointer += iArgc;
  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerDateSetSecsPart"
/*****************************************************************************/


/*****************************************************************************/
/*

     FUNCTION NAME:  VMVirtualOpSys::HandlerDateSetHMS

       DESCRIPTION:  sets the H,M,S portions of the date to the values provided

             INPUT:  iArgc - number of arguments passed to this
            OUTPUT:  none

           RETURNS:  zero
*/
int VMVirtualOpSys::HandlerDateSetHMS( int iArgc )
{
  m_poInterpreter->SetLastCall( "DateSetHMS" );

  SYSTEMTIME xBase;

  VerifyRunLineArguments( iArgc, 4 );
  VerifyElementType( 3, DT_DATETIME );
  VerifyElementType( 2, DT_INTEGER );
  VerifyElementType( 1, DT_INTEGER );
  VerifyElementType( 0, DT_INTEGER );
   
  xBase         = m_poVirtualChip->m_psStackPointer[3].v.v_datetime;
  xBase.wHour   = static_cast< WORD >( m_poVirtualChip->m_psStackPointer[2].v.v_integer );
  xBase.wMinute = static_cast< WORD >( m_poVirtualChip->m_psStackPointer[1].v.v_integer );
  xBase.wSecond = static_cast< WORD >( m_poVirtualChip->m_psStackPointer[0].v.v_integer );

  SetValue( &m_poVirtualChip->m_psStackPointer[iArgc], xBase );

  m_poVirtualChip->m_psStackPointer += iArgc;
  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerDateSetHMS"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerGetArgument

       DESCRIPTION:  get an argument from the argument list

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerGetArgument( int iArgc )
{
  m_poInterpreter->SetLastCall( "GetProperty" );

  int i;

  VerifyRunLineArguments( iArgc, 1 );

  if ( DT_INTEGER == m_poVirtualChip->m_psStackPointer[ 0 ].v_type )
  {
    i = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_integer;

    if ( i >= 0 && i < m_iArgc ) 
    {
      SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], 
                AllocateNewString( strlen( m_pchArgv[ i ] ), true ) );
    }
    else
    {
      set_nil( &m_poVirtualChip->m_psStackPointer[ iArgc ] );
    }
  }
  else 
  if ( DT_STRING == m_poVirtualChip->m_psStackPointer[ 0 ].v_type )
  {
    char*  pchArgKey = m_poVirtualChip->m_psStackPointer[0].v.v_string->str_data;

    if ( m_oCmdLine.IsEnabled( pchArgKey ) )
    {
      std::string oValue = m_oCmdLine.GetValue( pchArgKey );
      vmstring*  pchReturn = AllocateNewString( oValue.length(), true );
      strcpy( pchReturn->str_data, oValue.c_str() );
      SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], 
                pchReturn );
    }
    else
    {
      set_nil( &m_poVirtualChip->m_psStackPointer[ iArgc ] );
    }
  }
  else
  {
    set_nil( &m_poVirtualChip->m_psStackPointer[ iArgc ] );
  }
  ++m_poVirtualChip->m_psStackPointer;
  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerGetArgument"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerRunExtension

       DESCRIPTION:  Does the work required to call an extenstion dll

             INPUT:  iArgc - the number of arguments passed to this
            OUTPUT:  none

           RETURNS:  0
*/
int VMVirtualOpSys::HandlerRunExtension( int iArgc )
{
  m_poInterpreter->SetLastCall( "RunExtension" );

  const char*  pchDllName;
  int          iMsg;
  int          iCmd;
  int          iParam;
  VMVariant*   pvData;
  
  VerifyRunLineArguments( iArgc, 5 );
  VerifyElementType( 4, DT_STRING );
  VerifyElementType( 3, DT_INTEGER );
  VerifyElementType( 2, DT_INTEGER );
  VerifyElementType( 1, DT_INTEGER );

  pchDllName = m_poVirtualChip->m_psStackPointer[ 4 ].v.v_string->str_data;
  iMsg       = m_poVirtualChip->m_psStackPointer[ 3 ].v.v_integer;
  iCmd       = m_poVirtualChip->m_psStackPointer[ 2 ].v.v_integer;
  iParam     = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_integer;

  switch ( m_poVirtualChip->m_psStackPointer[ 0 ].v_type )
  {
    case DT_NTFILEHANDLE:
    case DT_HANDLE:
    case DT_KERNELHANDLE:
    case DT_INTEGER:
    case DT_DWORD:
    case DT_DOUBLE:
    case DT_BYTE:
    case DT_STRING:
    {
      pvData = &m_poVirtualChip->m_psStackPointer[ 0 ];
    }
    break;

    default:
      pvData = NULL;
    break;
  }

  VMExtDllManager oDll( pchDllName ); 
  oDll.Init();
  int iResult = oDll.RunCmd( iMsg, iCmd, iParam, pvData );
  oDll.Cleanup();

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], iResult );
  m_poVirtualChip->m_psStackPointer += iArgc;

  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerRunExtension"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerStartProcessNoWait

       DESCRIPTION:  starts (but does not wait for) a process

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerStartProcessNoWait( int iArgc )
{
  m_poInterpreter->SetLastCall( "ProcStartNoWait" );

  int  iReturn;

  VerifyRunLineArguments( iArgc, 1 );
  VerifyElementType( 0, DT_STRING );

  VMProcessRunner  oProcess;
  char*            pchProcPath = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_string->str_data;
  iReturn = oProcess.StartProcessNoWait( pchProcPath );

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], iReturn );

  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerStartProcessNoWait"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerStartCheckedProcess

       DESCRIPTION:  starts a process and captures all output written to stdout
                     by that process to a log file

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerStartCheckedProcess( int iArgc )
{
  m_poInterpreter->SetLastCall( "ProcStartErrorCheck" );

  int  iReturn;

  VerifyRunLineArguments( iArgc, 2 );
  VerifyElementType( 1, DT_STRING );
  VerifyElementType( 0, DT_USERVECTOR );

  VMDataVector*    poVector = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_uservector;
  int              iCount   = poVector->GetCount();

  PROCESS_OUTPUT   oResults;
  VMProcessRunner  oProcess;
  char*            pchProcPath = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_string->str_data;
  iReturn = oProcess.StartAndWaitForProcess( pchProcPath, oResults, m_poInterpreter->m_poDebugger );

  bool bResults = true;
  PROCESS_OUTPUT_ITER oIter;
  for( oIter  = oResults.begin();
       oIter != oResults.end();
       oIter++ )
  {
    // for each output line in the results
    //
    char* pchOutLine = (char*)(*oIter).c_str();
    m_poInterpreter->EchoToObserver( (char*)pchOutLine );

    int iTop = strlen( pchOutLine );
    for ( int iShiftLoop = 0; iShiftLoop < iTop; iShiftLoop++ )
    {
      *(pchOutLine + iShiftLoop) = toupper( *(pchOutLine + iShiftLoop) ); 
    }

    VMVariant       oElement;
    for ( int iLoop = 0; iLoop < iCount; iLoop++ )
    {
      // for each entry in the error-text-compare set
      //
      if ( poVector->GetAtIndex( iLoop, oElement ) )
      {
        if ( oElement.v_type == DT_STRING )
        {
          // if error-text found in the output line, then
          // set false, but if already error'd out, then do not
          // perform the comparison
          //
          if ( ( bResults == true  )
            && ( NULL != strstr( pchOutLine, oElement.v.v_string->str_data ) ) )
          {
            m_poInterpreter->EchoToObserver( ">>>> ERROR STRING MATCH!!!! " );
            m_poInterpreter->EchoToObserver( oElement.v.v_string->str_data );
            bResults = false;
          }
        }
      }
    }
  }
  oResults.clear();

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], bResults );

  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerStartCheckedProcess"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerStartProcessGetHandle

       DESCRIPTION:  starts a process, and returns a handle to the process that
                     was created...

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerStartProcessGetHandle( int iArgc )
{
  char*   pchRunPath;
  char*   pchArgs;
  HANDLE  hProcess;

  VerifyRunLineArguments( iArgc, 2 );
  VerifyElementType( 1, DT_STRING );
  VerifyElementType( 0, DT_STRING );

  pchRunPath = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_string->str_data;
  pchArgs    = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_string->str_data;

  VMProcessRunner  oProcess;
  hProcess = oProcess.StartProcessGetHandle( pchRunPath, pchArgs );

  // send back the return code
  //
  set_kernelhandle( &m_poVirtualChip->m_psStackPointer[iArgc], hProcess );
  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerStartProcessGetHandle"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerStartLoggedProcess

       DESCRIPTION:  starts a process and captures all output written to stdout
                     by that process to a log file

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerStartLoggedProcess( int iArgc )
{
  char* pchRunPath;
  char* pchLogFile;
  int   iReturn;

  VerifyRunLineArguments( iArgc, 2 );
  VerifyElementType( 1, DT_STRING );
  VerifyElementType( 0, DT_STRING );

  pchRunPath = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_string->str_data;
  pchLogFile = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_string->str_data;

  PROCESS_OUTPUT   oResults;
  VMProcessRunner  oProcess;
  VMPathMaker      oPath;
  bool             bCanContinue = true;
  iReturn = oProcess.StartAndWaitForProcess( pchRunPath, oResults );

  oPath.CreateFilePath( pchLogFile );

  HANDLE  hFile = CreateFile( pchLogFile, 
                              GENERIC_WRITE | GENERIC_READ,
                              0,
                              NULL,
                              CREATE_ALWAYS,
                              FILE_ATTRIBUTE_NORMAL,
                              NULL ); 

  if ( INVALID_HANDLE_VALUE == hFile )
  {
    CloseHandle( hFile );
    bCanContinue = FALSE;
  }

  if ( bCanContinue )
  {
    PROCESS_OUTPUT_ITER oIter;
    for( oIter  = oResults.begin();
         oIter != oResults.end() && bCanContinue;
         oIter++ )
    {
      // for each output line in the results
      //
      const char* pchOutLine = (*oIter).c_str();

      SetFilePointer( hFile, 0, 0, FILE_END );

      DWORD dwBytesWritten;
      if ( WriteFile( hFile,
                     pchOutLine,
                     strlen( pchOutLine ),
                     &dwBytesWritten,
                     NULL ) )
      {
        if ( strlen( pchOutLine ) != dwBytesWritten )
        {
          CloseHandle( hFile );
          bCanContinue = false;
        }
      }
    }
    CloseHandle( hFile );
  }
  oResults.clear();

  // send back the return code
  //
  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], iReturn );

  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerStartLoggedProcess"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerCreateDirectory

       DESCRIPTION:  creates a directory ( or a path )

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerCreateDirectory( int iArgc )
{
  m_poInterpreter->SetLastCall( "CreateDirectory" );

  BOOL   bResult;

  VerifyRunLineArguments( iArgc, 1);
  VerifyElementType( 0, DT_STRING );


  char* pchPath = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_string->str_data;

  VMPathMaker oCreator;
  bResult = oCreator.CreatePath( pchPath );

  // send back the return code
  //
  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], bResult );

  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerCreateDirectory"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerSetDirectory

       DESCRIPTION:  sets the instances current directory

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerSetDirectory( int iArgc )
{
  m_poInterpreter->SetLastCall( "SetDirectory" );

  BOOL  bReturn;

  VerifyRunLineArguments( iArgc, 1 );
  VerifyElementType( 0, DT_STRING );

  bReturn = SetCurrentDirectory( m_poVirtualChip->m_psStackPointer[ 0 ].v.v_string->str_data );

  // send back the return code
  //
  SetValue( &m_poVirtualChip->m_psStackPointer[iArgc], bReturn );

  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerSetDirectory"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerGetDirectory

       DESCRIPTION:  sets the instances current directory

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerGetDirectory( int iArgc )
{
  m_poInterpreter->SetLastCall( "GetDirectory" );

  char  achCurPath[MAX_PATH+1];
  BOOL  bReturn;

  VerifyRunLineArguments( iArgc, 0 );

  bReturn = GetCurrentDirectory( MAX_PATH, achCurPath );

  // send back the return code
  //
  vmstring* pchCurDir = AllocateNewString( strlen( achCurPath ), true );
  strcpy( pchCurDir->str_data, achCurPath );
  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], pchCurDir );

  m_poVirtualChip->m_psStackPointer += iArgc;

  return 0;
}
/* End of function "VMVirtualOpSys::HandlerGetDirectory"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerPathExists

       DESCRIPTION:  verifies that the path input is valid ( exists )

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerPathExists( int iArgc )
{
  m_poInterpreter->SetLastCall( "PathExists" );

  char  achCurPath[MAX_PATH+1];
  BOOL  bReturn = FALSE;

  VerifyRunLineArguments( iArgc, 1 );
  VerifyElementType( 0, DT_STRING );

  if ( 0 != GetCurrentDirectory( MAX_PATH, achCurPath ) )
  {
    bReturn = SetCurrentDirectory( m_poVirtualChip->m_psStackPointer[ 0 ].v.v_string->str_data );
    SetCurrentDirectory( achCurPath );
  }

  // send back the return code
  //
  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], bReturn );

  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerPathExists"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerCompareDirs

       DESCRIPTION:  calculates a sum of bytes for each directory given, and
                     returns the T/F result of comparing the two directories.

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerCompareDirs( int iArgc )
{
  m_poInterpreter->SetLastCall( "CompareDirs" );

  BOOL   bResult = FALSE;

  VerifyRunLineArguments( iArgc, 2);
  VerifyElementType( 1, DT_STRING );
  VerifyElementType( 0, DT_STRING );

  VMCompareDirs  oCompareDirs;

  bResult = oCompareDirs.Compare( m_poVirtualChip->m_psStackPointer[ 0 ].v.v_string->str_data, 
                                  m_poVirtualChip->m_psStackPointer[ 1 ].v.v_string->str_data );

  // send back the return code
  //
  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], bResult );

  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerCompareDirs"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerCopyFile

       DESCRIPTION:  performs a full on API driven "Safe copy" of a file.
                     Can perform either a buffered or non-buffered copy based
                     on the size of the file.

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0
*/
int VMVirtualOpSys::HandlerCopyFile( int iArgc )
{
  m_poInterpreter->SetLastCall( "CopyFile" );

  HANDLE hSourceFile      = NULL;
  HANDLE hTargetFile      = NULL;
  DWORD  dwSizeSourceFile = 0L;
  DWORD  dwSizeTargetFile = 0L;
  DWORD  dwBytesRead      = 0;
  DWORD  dwBytesWritten   = 0L;
  BOOL   bSafeToDelete    = FALSE;
  BOOL   bCanContinue     = TRUE; // assume success

  VerifyRunLineArguments( iArgc, 2);
  VerifyElementType( 1, DT_STRING );
  VerifyElementType( 0, DT_STRING );

  hSourceFile = CreateFile( m_poVirtualChip->m_psStackPointer[ 1 ].v.v_string->str_data, 
                            GENERIC_WRITE | GENERIC_READ,
                            0,  // exclusive access
                            NULL,
                            OPEN_EXISTING,
                            FILE_ATTRIBUTE_NORMAL,
                            NULL ); 
  if ( INVALID_HANDLE_VALUE == hSourceFile )
  {
    CloseHandle( hSourceFile );
    bCanContinue = FALSE;
  }

  if ( bCanContinue )
  {
    if ( 0xFFFFFFFF == ( dwSizeSourceFile = GetFileSize( hSourceFile, NULL ) ) )
    {
      CloseHandle( hSourceFile );
      bCanContinue = FALSE;
    }
  } 

  if ( bCanContinue )
  { 
    // if nothing to copy, clean up and get out
    //
    if ( 0 == dwSizeSourceFile )
    {
       CloseHandle( hSourceFile );
       bCanContinue = FALSE;
    }
  }

  if ( bCanContinue )
  {
    hTargetFile = CreateFile( m_poVirtualChip->m_psStackPointer[ 0 ].v.v_string->str_data, 
                              GENERIC_WRITE | GENERIC_READ,
                              0,  // exclusive access
                              NULL,
                              CREATE_ALWAYS,
                              FILE_ATTRIBUTE_NORMAL,
                              NULL ); 
    if ( INVALID_HANDLE_VALUE == hTargetFile )
    {
      CloseHandle( hSourceFile );
      CloseHandle( hTargetFile );
      bCanContinue = FALSE;
    }
  }

  if ( bCanContinue )
  {
    if ( 0xFFFFFFFF == ( dwSizeTargetFile = GetFileSize( hTargetFile, NULL ) ) )
    {
      CloseHandle( hSourceFile );
      CloseHandle( hTargetFile );
      bCanContinue = FALSE;
    }
  } 

  if ( bCanContinue )
  { 
    // if copying to existing file, must set file pointer to BOF
    //
    if ( 0 < dwSizeTargetFile )
    {
      SetFilePointer( hTargetFile, 0, 0, FILE_BEGIN );
    }
    else
    {
      bSafeToDelete = TRUE;
    }
  
    if ( (DWORD)1000000 > dwSizeSourceFile )
    { 
      // unbuffered version for smaller files. 
      // does copy in a single read-write call-pair
      // 
      char*  pchServerData = NULL;
      pchServerData = new char [dwSizeSourceFile]; 

      if ( ReadFile( hSourceFile, 
                     pchServerData,
                     dwSizeSourceFile,
                     &dwBytesRead,
                     NULL ) )
      {
        if ( WriteFile( hTargetFile,
                        pchServerData,
                        dwSizeSourceFile,
                        &dwBytesWritten,
                        NULL ) )
        {
          delete [] pchServerData;

          CloseHandle( hTargetFile );
          CloseHandle( hSourceFile );

          if ( dwBytesRead != dwBytesWritten )
          {
            if ( bSafeToDelete )
            {
              DeleteFile( m_poVirtualChip->m_psStackPointer[ 0 ].v.v_string->str_data );
            }
            bCanContinue = FALSE;
          }
        }
        else
        {
          delete [] pchServerData;
 
          CloseHandle( hSourceFile );
          CloseHandle( hTargetFile );
          if ( bSafeToDelete )
          {
            DeleteFile( m_poVirtualChip->m_psStackPointer[ 0 ].v.v_string->str_data );
          }
          bCanContinue = FALSE;
        }
      }
      else
      {
        CloseHandle( hSourceFile );
        CloseHandle( hTargetFile );
        if ( bSafeToDelete )
        {
           DeleteFile( m_poVirtualChip->m_psStackPointer[ 0 ].v.v_string->str_data );
        }
        bCanContinue = FALSE;
      }
    }
    else
    {  
      // buffered version for larger files
      //
      const DWORD dwBufSize = 64000;
      DWORD dwTotalRead = 0;
      char  pchServerData[dwBufSize]; 

      while ( dwTotalRead < dwSizeSourceFile )
      {
        ZeroMemory( pchServerData, dwBufSize );
        if ( ReadFile( hSourceFile, 
                       pchServerData,
                       dwBufSize,
                       &dwBytesRead,
                       NULL ) )
        {
          dwTotalRead += dwBytesRead;

          if ( WriteFile( hTargetFile,
                          pchServerData,
                          dwBytesRead,
                          &dwBytesWritten,
                          NULL ) )
          {
            if ( dwBytesRead != dwBytesWritten )
            {
              CloseHandle( hSourceFile );
              CloseHandle( hTargetFile );
              if ( bSafeToDelete )
              {
                DeleteFile( m_poVirtualChip->m_psStackPointer[ 0 ].v.v_string->str_data );
              }
              bCanContinue = FALSE;
              break;
            }
            else
            {
              continue;
            }
          }
          else
          {
            CloseHandle( hSourceFile );
            CloseHandle( hTargetFile );
            if ( bSafeToDelete )
            {
              DeleteFile( m_poVirtualChip->m_psStackPointer[ 0 ].v.v_string->str_data );
            }
            bCanContinue = FALSE;
            break;
          }
        }
        else
        {
          CloseHandle( hSourceFile );
          CloseHandle( hTargetFile );
          if ( bSafeToDelete )
          {
            DeleteFile( m_poVirtualChip->m_psStackPointer[ 0 ].v.v_string->str_data );
          }
          bCanContinue = FALSE;
          break;
        }
      }
      CloseHandle( hSourceFile );
      CloseHandle( hTargetFile );
    }
  }
  // send back the return code
  //
  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], bCanContinue );

  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerCopyFile"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerMoveTree

       DESCRIPTION:  moves a directory ( and its contents ) to a second path

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerMoveTree( int iArgc )
{
  m_poInterpreter->SetLastCall( "MoveTree" );

  char* pchSource;
  char* pchTarget;
  char* pchBackup;
  char  achCurrent[MAX_PATH];

  VerifyRunLineArguments( iArgc, 3 );
  VerifyElementType( 2, DT_STRING );
  VerifyElementType( 1, DT_STRING );
  VerifyElementType( 0, DT_STRING );

  pchSource = m_poVirtualChip->m_psStackPointer[ 2 ].v.v_string->str_data;
  pchTarget = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_string->str_data; 
  pchBackup = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_string->str_data;

  GetCurrentDirectory( MAX_PATH - 1, achCurrent );
  VMCopyTree   oTreeCopy;
  oTreeCopy.Copy( pchSource,     // root of where files will come from
                  pchTarget,     // root of where files will be copied
                  achCurrent,    // root of current directory
                  pchBackup,     // root of where prev versions of files will go
                  TRUE );        // indicates the source will be deleted
                                  // after the copy
  // send back the return code
  //
  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], oTreeCopy.m_iStatus );

  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerMoveTree"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerRemoveDirectory

       DESCRIPTION:  attempts to remove the specified directory.

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerRemoveDirectory( int iArgc )
{
  m_poInterpreter->SetLastCall( "RemoveDirectory" );

  VerifyRunLineArguments( iArgc, 1 );
  VerifyElementType( 0, DT_STRING );

  BOOL bReturn = RemoveDirectory( m_poVirtualChip->m_psStackPointer[ 0 ].v.v_string->str_data );

  // send back the return code
  //
  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], bReturn );

  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerRemoveDirectory"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerRemoveTree

       DESCRIPTION:  removes an entire directory tree 

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerRemoveTree( int iArgc )
{
  m_poInterpreter->SetLastCall( "RemoveTree" );

  VMString   oTemp;
  DWORD      dwReturn;

  VerifyRunLineArguments( iArgc, 1 );
  VerifyElementType( 0, DT_STRING );

  // kick off a recursive scan of the root directory to delete
  //
  VMDirScanner oDirScanner( m_poVirtualChip->m_psStackPointer[0].v.v_string->str_data, 
                            "*.*", 
                            TRUE );

  if ( ERROR_SUCCESS == ( dwReturn = oDirScanner.GetLastErrorCode() ) )
  {
    // now delete the files found by the scanner
    //
    oTemp = oDirScanner.GetFirstFile();	
    const char* pchFile = oTemp.Buffer();
    while ( strlen( pchFile ) )
    {
      DeleteFile( pchFile );
      oTemp   = oDirScanner.GetNextFile();
      pchFile = oTemp.Buffer();
    }

    // now delete the directories found by the scanner
    //
    oTemp = oDirScanner.GetLastDirectory();	
    const char* pchDir = oTemp.Buffer();
    while ( strlen( pchDir ) )
    {
      RemoveDirectory( pchDir );
      oTemp  = oDirScanner.GetPrevDirectory();
      pchDir = oTemp.Buffer();
    }
  }

  // send back the return code
  //
  SetValue( &m_poVirtualChip->m_psStackPointer[iArgc], dwReturn );

  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerRemoveTree"
/*****************************************************************************/

 
/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerCopyTree

       DESCRIPTION:  copies a directory ( and its contents ) to a second 
                     location

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerCopyTree( int iArgc )
{
  m_poInterpreter->SetLastCall( "CopyTree" );

  char* pchSource;
  char* pchTarget;
  char* pchBackup;
  char  achCurrent[MAX_PATH];

  VerifyRunLineArguments( iArgc, 3 );
  VerifyElementType( 2, DT_STRING );
  VerifyElementType( 1, DT_STRING );
  VerifyElementType( 0, DT_STRING );

  pchSource = m_poVirtualChip->m_psStackPointer[ 2 ].v.v_string->str_data;
  pchTarget = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_string->str_data; 
  pchBackup = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_string->str_data;

  GetCurrentDirectory( MAX_PATH - 1, achCurrent );
  VMCopyTree   oTreeCopy;
  oTreeCopy.Copy( pchSource,     // root of where files will come from
                  pchTarget,     // root of where files will be copied
                  achCurrent,    // root of current directory
                  pchBackup,     // root of where prev versions of files will go
                  FALSE );       // indicates the source will NOT be deleted
                                 // after the copy
  // send back the return code
  //
  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], oTreeCopy.m_iStatus );

  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerCopyTree"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerRenameFile

       DESCRIPTION:  attempts to rename a file

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerRenameFile( int iArgc )
{
  m_poInterpreter->SetLastCall( "RenameDirectory" );

  VerifyRunLineArguments( iArgc, 2 );
  VerifyElementType( 1, DT_STRING );
  VerifyElementType( 0, DT_STRING );

  BOOL bReturn = rename( m_poVirtualChip->m_psStackPointer[ 1 ].v.v_string->str_data, 
                         m_poVirtualChip->m_psStackPointer[ 0 ].v.v_string->str_data );

  // silly rename function returns 0 if worked, so flip the bit
  //
  if ( !bReturn ) 
  {
    bReturn = TRUE;
  }
  else
  {
    bReturn = FALSE;
  }

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], bReturn );

  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerRenameFile"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerLogOnNetDrive

       DESCRIPTION:  logs on to a network drive

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerLogOnNetDrive( int iArgc )
{
  m_poInterpreter->SetLastCall( "ConnectNetDrive" );

  char*  pchServerShare;
  char*  pchUID;
  char*  pchPWD;
  char*  pchDrive;

  VerifyRunLineArguments( iArgc, 3 );
  VerifyElementType( 2, DT_STRING );
  VerifyElementType( 1, DT_STRING );
  VerifyElementType( 0, DT_STRING );

  pchServerShare = m_poVirtualChip->m_psStackPointer[ 2 ].v.v_string->str_data;
  pchUID         = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_string->str_data; 
  pchPWD         = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_string->str_data;

  VMNetworkDrive oNetDrive;
  if ( oNetDrive.Connect( pchServerShare, pchUID, pchPWD ) )
  {
    pchDrive = oNetDrive.GetDriveLetter();
  }
  else
  {
    pchDrive = "Error";
  }

  // send the return value back to the caller
  //
  vmstring* pchNetDrive = AllocateNewString( strlen( pchDrive ), true );
  strcpy( pchNetDrive->str_data, pchDrive );
  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], pchNetDrive );

  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerLogOnNetDrive"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerLogOffNetDrive

       DESCRIPTION:  disconnects from the drive letter given

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerLogOffNetDrive( int iArgc )
{
  m_poInterpreter->SetLastCall( "LogOffNetDrive" );

  char*  pchDrive;

  VerifyRunLineArguments( iArgc, 1 );
  VerifyElementType( 0, DT_STRING );

  pchDrive = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_string->str_data;

  VMNetworkDrive oNetDrive;
  oNetDrive.DisconnectNetworkDrive( *pchDrive );

  // send back the return code
  //
  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], 0 );

  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerLogOffNetDrive"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerGetEnvironmentVar

       DESCRIPTION:  caller can request an environment variable by name

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerGetEnvironmentVar( int iArgc )
{
  m_poInterpreter->SetLastCall( "GetEnvironmentFile" );

  VMString oOutput;
  char*    pchVarToGet;

  VerifyRunLineArguments( iArgc, 1 );
  VerifyElementType( 0, DT_STRING );

  pchVarToGet = m_poVirtualChip->m_psStackPointer[0].v.v_string->str_data;

  VMEnvironmentVariables  oEnvironment;
  oEnvironment.GetValueDirect( pchVarToGet, oOutput );

  // send back the return code
  //
  vmstring* pchValue = AllocateNewString( oOutput.GetLength(), true );
  strcpy( pchValue->str_data, (const char*)oOutput );
  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], pchValue );

  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerGetEnvironmentVar"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerSetEnvironmentVar

       DESCRIPTION:  allows a caller to make an entry into the OS environment

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerSetEnvironmentVar( int iArgc )
{
  m_poInterpreter->SetLastCall( "SetEnvironmentVar" );

  char*  pchVarName;
  char*  pchVarValue;
  int    iReturn;

  VerifyRunLineArguments( iArgc, 2 );
  VerifyElementType( 1, DT_STRING );
  VerifyElementType( 0, DT_STRING );

  pchVarName  = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_string->str_data;
  pchVarValue = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_string->str_data;

  VMEnvironmentVariables  oEnvironment;
  oEnvironment.Initialize();
	
  iReturn = oEnvironment.SetValue( pchVarName, pchVarValue, TRUE, FALSE );

  // send back the return code
  //
  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], iReturn );

  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerSetEnvironmentVar"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerAddToEnvironmentVar

       DESCRIPTION:  appends the given string to the environment variable 
                     specified

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerAddToEnvironmentVar( int iArgc )
{
  m_poInterpreter->SetLastCall( "AppendEnvironmentVar" );

  char*  pchVarName;
  char*  pchVarValue;
  int    iReturn;

  VerifyRunLineArguments( iArgc, 2 );
  VerifyElementType( 1, DT_STRING );
  VerifyElementType( 0, DT_STRING );

  pchVarName  = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_string->str_data;
  pchVarValue = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_string->str_data;

  VMString oOutput;
  VMEnvironmentVariables  oEnvironment;
  oEnvironment.Initialize();
  oEnvironment.GetValueDirect( pchVarName, oOutput );

  oOutput += pchVarValue;	
  iReturn = oEnvironment.SetValue( pchVarName, oOutput.Buffer(), TRUE, FALSE );

  oEnvironment.GetValueDirect( pchVarName, oOutput );

  // send back the return code
  //
  vmstring* pchValue = AllocateNewString( oOutput.GetLength(), true );
  strcpy( pchValue->str_data, (const char*)oOutput );
  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], pchValue );

  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerAddToEnvironmentVar"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerDelEnvironmentVar

       DESCRIPTION:  removes all traces of an environment variable from the 
                     system registry

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerDelEnvironmentVar( int iArgc )
{
  m_poInterpreter->SetLastCall( "DelEnvironmentVar" );

  char* pchVarName;
  int   iReturn;

  VerifyRunLineArguments( iArgc, 1 );
  VerifyElementType( 0, DT_STRING );

  pchVarName = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_string->str_data;

  VMEnvironmentVariables  oEnvironment;
	iReturn = oEnvironment.RemoveKey( pchVarName, TRUE );

  // send back the return code
  //
  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], iReturn );

  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerDelEnvironmentVar"
/*****************************************************************************/


/*****************************************************************************/
/*

     FUNCTION NAME:  VMVirtualOpSys::HandlerPageSetLandscapeMode

       DESCRIPTION:  sets the printer to landscape mode

             INPUT:  iArgc - count of script params passed to this
            OUTPUT:  none

           RETURNS:  zero
*/
int VMVirtualOpSys::HandlerPageSetLandscapeMode( int iArgc )
{
  m_poInterpreter->SetLastCall( "PageSetLandscapeMode" );

  VerifyRunLineArguments( iArgc, 1 );
  VerifyElementType( 0, DT_REPORTPAGE );

  if ( NULL == m_poPageInitInfo )
  {
    // treat a missing page context as a fatal error
    //
    char achMsg[255];
    sprintf( achMsg, "HandlerNewPage Did Not Find Page Creation Parameters." );

    VMException* pThrow = new VMException(  __FILE__, __LINE__, achMsg );
    throw pThrow;
  }
  m_poVirtualChip->m_psStackPointer[ 0 ].v.v_page->SetPrinterMode( m_poPageInitInfo->m_poPageCDC, 
                                                                   DMORIENT_LANDSCAPE );

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], true );
  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerPageSetLandscapeMode"
/*****************************************************************************/


/*****************************************************************************/
/*

     FUNCTION NAME:  VMVirtualOpSys::HandlerPageSetPortraitMode

       DESCRIPTION:  sets printer to portrait mode

             INPUT:  iArgc - count of script params passed to this
            OUTPUT:  none

           RETURNS:  zero
*/
int VMVirtualOpSys::HandlerPageSetPortraitMode( int iArgc )
{
  m_poInterpreter->SetLastCall( "PageSetPortraitMode" );

  VerifyRunLineArguments( iArgc, 1 );
  VerifyElementType( 0, DT_REPORTPAGE );

  if ( NULL == m_poPageInitInfo )
  {
    // treat a missing page context as a fatal error
    //
    char achMsg[255];
    sprintf( achMsg, "HandlerNewPage Did Not Find Page Creation Parameters." );

    VMException* pThrow = new VMException(  __FILE__, __LINE__, achMsg );
    throw pThrow;
  }
  m_poVirtualChip->m_psStackPointer[ 0 ].v.v_page->SetPrinterMode( m_poPageInitInfo->m_poPageCDC, 
                                                                   DMORIENT_PORTRAIT );

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], true );
  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerPageSetPortraitMode"
/*****************************************************************************/


/*****************************************************************************/
/*

     FUNCTION NAME:  VMVirtualOpSys::HandlerPageSetFont

       DESCRIPTION:  sets the default font for a report page

             INPUT:  iArgc - count of script params passed to this
            OUTPUT:  none

           RETURNS:  zero
*/
int VMVirtualOpSys::HandlerPageSetFont( int iArgc )
{
  m_poInterpreter->SetLastCall( "PageSetFont" );

  VerifyRunLineArguments( iArgc, 2 );
  VerifyElementType( 1, DT_REPORTPAGE );
  VerifyElementType( 0, DT_STRING );

  m_poVirtualChip->m_psStackPointer[ 1 ].v.v_page->SetFont( m_poVirtualChip->m_psStackPointer[ 0 ].v.v_string->str_data );

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], true );
  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerPageSetFont"
/*****************************************************************************/


/*****************************************************************************/
/*

     FUNCTION NAME:  VMVirtualOpSys::HandlerPageSetFontSize

       DESCRIPTION:  sets the default font size for a report page

             INPUT:  iArgc - count of script params passed to this
            OUTPUT:  none

           RETURNS:  zero
*/
int VMVirtualOpSys::HandlerPageSetFontSize( int iArgc )
{
  m_poInterpreter->SetLastCall( "PageSetFontSize" );

  VerifyRunLineArguments( iArgc, 2 );
  VerifyElementType( 1, DT_REPORTPAGE );
  VerifyElementType( 0, DT_INTEGER );

  m_poVirtualChip->m_psStackPointer[ 1 ].v.v_page->SetFontSize( m_poVirtualChip->m_psStackPointer[ 0 ].v.v_integer );

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], true );
  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerPageSetFontSize"
/*****************************************************************************/


/*****************************************************************************/
/*

     FUNCTION NAME:  VMVirtualOpSys::HandlerPageSetRightMargin

       DESCRIPTION:  sets the right margin for a report page

             INPUT:  iArgc - count of script params passed to this
            OUTPUT:  none

           RETURNS:  zero
*/
int VMVirtualOpSys::HandlerPageSetRightMargin( int iArgc )
{
  m_poInterpreter->SetLastCall( "PageSetRightMargin" );

  VerifyRunLineArguments( iArgc, 2 );
  VerifyElementType( 1, DT_REPORTPAGE );
  VerifyElementType( 0, DT_DOUBLE );

  m_poVirtualChip->m_psStackPointer[ 1 ].v.v_page->SetRightMargin( m_poVirtualChip->m_psStackPointer[ 0 ].v.v_double );

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], true );
  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerPageSetRightMargin"
/*****************************************************************************/


/*****************************************************************************/
/*

     FUNCTION NAME:  VMVirtualOpSys::HandlerPageSetBottomMargin

       DESCRIPTION:  sets the bottom margin for a report page

             INPUT:  iArgc - count of script params passed to this
            OUTPUT:  none

           RETURNS:  zero
*/
int VMVirtualOpSys::HandlerPageSetBottomMargin( int iArgc )
{
  m_poInterpreter->SetLastCall( "PageSetBottomMargin" );

  VerifyRunLineArguments( iArgc, 2 );
  VerifyElementType( 1, DT_REPORTPAGE );
  VerifyElementType( 0, DT_DOUBLE );

  m_poVirtualChip->m_psStackPointer[ 1 ].v.v_page->SetBottomMargin( m_poVirtualChip->m_psStackPointer[ 0 ].v.v_double );

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], true );
  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerPageSetBottomMargin"
/*****************************************************************************/


/*****************************************************************************/
/*

     FUNCTION NAME:  VMVirtualOpSys::HandlerPagePrintTextColumn

       DESCRIPTION:  draws a column of text into a page

             INPUT:  iArgc - count of script params passed to this
            OUTPUT:  none

           RETURNS:  zero
*/
int VMVirtualOpSys::HandlerPagePrintTextColumn( int iArgc )
{
  m_poInterpreter->SetLastCall( "PagePrintTextColumn" );

  if ( iArgc == 8 )
  {
    VerifyElementType( 7, DT_REPORTPAGE );
    VerifyElementType( 6, DT_DOUBLE  );
    VerifyElementType( 5, DT_DOUBLE  );
    VerifyElementType( 4, DT_DOUBLE  );
    VerifyElementType( 3, DT_DOUBLE  );
    VerifyElementType( 2, DT_INTEGER );
    VerifyElementType( 1, DT_INTEGER );
    VerifyElementType( 0, DT_STRING  );

    VMPage* poPage    = m_poVirtualChip->m_psStackPointer[ 7 ].v.v_page;

    double  dblTop    = m_poVirtualChip->m_psStackPointer[ 6 ].v.v_double; 
    double  dblLeft   = m_poVirtualChip->m_psStackPointer[ 5 ].v.v_double;
    double  dblBottom = m_poVirtualChip->m_psStackPointer[ 4 ].v.v_double;
    double  dblRight  = m_poVirtualChip->m_psStackPointer[ 3 ].v.v_double;
    int     iFlags    = m_poVirtualChip->m_psStackPointer[ 2 ].v.v_integer;
    int     iSize     = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_integer;
  
    char*   pchText   = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_string->str_data;

    poPage->PrintColumn( dblTop, dblLeft, dblBottom, dblRight, iFlags, iSize, pchText );
  }
  else
  if ( iArgc == 9 )
  {
    VerifyElementType( 8, DT_REPORTPAGE );
    VerifyElementType( 7, DT_REPORTPAGEREGION );
    VerifyElementType( 6, DT_DOUBLE  );
    VerifyElementType( 5, DT_DOUBLE  );
    VerifyElementType( 4, DT_DOUBLE  );
    VerifyElementType( 3, DT_DOUBLE  );
    VerifyElementType( 2, DT_INTEGER );
    VerifyElementType( 1, DT_INTEGER );
    VerifyElementType( 0, DT_STRING  );

    VMPage* poPage          = m_poVirtualChip->m_psStackPointer[ 8 ].v.v_page;
    VMPrintRegion* poRegion = m_poVirtualChip->m_psStackPointer[ 7 ].v.v_pageregion;

    double  dblTop    = m_poVirtualChip->m_psStackPointer[ 6 ].v.v_double; 
    double  dblLeft   = m_poVirtualChip->m_psStackPointer[ 5 ].v.v_double;
    double  dblBottom = m_poVirtualChip->m_psStackPointer[ 4 ].v.v_double;
    double  dblRight  = m_poVirtualChip->m_psStackPointer[ 3 ].v.v_double;
    int     iFlags    = m_poVirtualChip->m_psStackPointer[ 2 ].v.v_integer;
    int     iSize     = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_integer;
  
    char*   pchText   = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_string->str_data;

    poPage->PrintColumn( poRegion, dblTop, dblLeft, dblBottom, dblRight, iFlags, iSize, pchText );
  }

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], true );
  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerPagePrintTextColumn"
/*****************************************************************************/


/*****************************************************************************/
/*

     FUNCTION NAME:  VMVirtualOpSys::HandlerPageSetColor

       DESCRIPTION:  sets the default page color

             INPUT:  iArgc - count of script params passed to this
            OUTPUT:  none

           RETURNS:  zero
*/
int VMVirtualOpSys::HandlerPageSetColor( int iArgc )
{
  m_poInterpreter->SetLastCall( "PageSetColor" );

  if ( iArgc == 2 )
  {
    VerifyElementType( 1, DT_REPORTPAGE );
    VerifyElementType( 0, DT_COLOR  );

    VMPage* poPage    = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_page;
    COLORREF  xColor  = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_color;

    poPage->SetColor( xColor );
  }
  else
  if ( iArgc == 4 )
  {
    VerifyElementType( 3, DT_REPORTPAGE );
    VerifyElementType( 2, DT_INTEGER );
    VerifyElementType( 1, DT_INTEGER );
    VerifyElementType( 0, DT_INTEGER );

    VMPage* poPage = m_poVirtualChip->m_psStackPointer[ 3 ].v.v_page;

    int     iRed   = m_poVirtualChip->m_psStackPointer[ 2 ].v.v_integer;
    int     iGreen = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_integer;
    int     iBlue  = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_integer;
  
    poPage->SetColor( RGB( iRed, iGreen, iBlue ) );
  }

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], true );
  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerPageSetColor"
/*****************************************************************************/


/*****************************************************************************/
/*

     FUNCTION NAME:  VMVirtualOpSys::HandlerPageSetBackColor

       DESCRIPTION:  sets the default page color

             INPUT:  iArgc - count of script params passed to this
            OUTPUT:  none

           RETURNS:  zero
*/
int VMVirtualOpSys::HandlerPageSetBackColor( int iArgc )
{
  m_poInterpreter->SetLastCall( "PageSetBackColor" );

  if ( iArgc == 2 )
  {
    VerifyElementType( 1, DT_REPORTPAGE );
    VerifyElementType( 0, DT_COLOR  );

    VMPage* poPage    = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_page;
    COLORREF  xColor  = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_color;

    poPage->SetBackColor( xColor );
  }
  else
  if ( iArgc == 4 )
  {
    VerifyElementType( 3, DT_REPORTPAGE );
    VerifyElementType( 2, DT_INTEGER );
    VerifyElementType( 1, DT_INTEGER );
    VerifyElementType( 0, DT_INTEGER );

    VMPage* poPage = m_poVirtualChip->m_psStackPointer[ 3 ].v.v_page;

    int     iRed   = m_poVirtualChip->m_psStackPointer[ 2 ].v.v_integer;
    int     iGreen = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_integer;
    int     iBlue  = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_integer;
  
    poPage->SetBackColor( RGB( iRed, iGreen, iBlue ) );
  }

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], true );
  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerPageSetBackColor"
/*****************************************************************************/


/*****************************************************************************/
/*

     FUNCTION NAME:  VMVirtualOpSys::HandlerPagePrintBitMap

       DESCRIPTION:  prints a bitmap into a report page

             INPUT:  iArgc - count of script params passed to this
            OUTPUT:  none

           RETURNS:  zero
*/
int VMVirtualOpSys::HandlerPagePrintBitMap( int iArgc )
{
  m_poInterpreter->SetLastCall( "PagePrintBitmap" );

  VerifyRunLineArguments( iArgc, 6 );
  VerifyElementType( 5, DT_REPORTPAGE );
  VerifyElementType( 4, DT_DOUBLE  );
  VerifyElementType( 3, DT_DOUBLE  );
  VerifyElementType( 2, DT_DOUBLE  );
  VerifyElementType( 1, DT_DOUBLE  );
  VerifyElementType( 0, DT_STRING  );

  VMPage* poPage    = m_poVirtualChip->m_psStackPointer[ 5 ].v.v_page;

  double  dblTop    = m_poVirtualChip->m_psStackPointer[ 4 ].v.v_double; 
  double  dblLeft   = m_poVirtualChip->m_psStackPointer[ 3 ].v.v_double;
  double  dblBottom = m_poVirtualChip->m_psStackPointer[ 2 ].v.v_double;
  double  dblRight  = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_double;
  
  char*   pchFile   = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_string->str_data;

  poPage->PrintBitMap( dblTop, dblLeft, dblBottom, dblRight, pchFile );

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], true );
  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerPagePrintBitMap"
/*****************************************************************************/


/*****************************************************************************/
/*

     FUNCTION NAME:  VMVirtualOpSys::HandlerPageGetNextLogicalColumn

       DESCRIPTION:  gets the next logical column location for a page context

             INPUT:  iArgc - count of script params passed to this
            OUTPUT:  none

           RETURNS:  zero
*/
int VMVirtualOpSys::HandlerPageGetNextLogicalColumn( int iArgc )
{
  m_poInterpreter->SetLastCall( "PageGetNextLogicalColumn" );

  VerifyRunLineArguments( iArgc, 1 );
  VerifyElementType( 0, DT_REPORTPAGE );

  VMPage* poPage    = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_page;

  double dblResult = poPage->GetNextLogicalColumn();

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], dblResult );

  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerPageGetNextLogicalColumn"
/*****************************************************************************/


/*****************************************************************************/
/*

     FUNCTION NAME:  VMVirtualOpSys::HandlerPageDrawBox

       DESCRIPTION:  draws a box into a report page

             INPUT:  iArgc - count of script params passed to this
            OUTPUT:  none

           RETURNS:  zero
*/
int VMVirtualOpSys::HandlerPageDrawBox( int iArgc )
{
  m_poInterpreter->SetLastCall( "PageDrawBox" );

  VMPage* poPage = NULL;
  double  dblTop; 
  double  dblLeft;
  double  dblBottom;
  double  dblRight;
  double  dblLineSize = 1;
  UINT    iFillFlag = FILL_NONE;
  UINT    iPenFlag  = PEN_SOLID;

  if ( iArgc == 8 )
  {
    VerifyElementType( 7, DT_REPORTPAGE );
    VerifyElementType( 6, DT_DOUBLE  );
    VerifyElementType( 5, DT_DOUBLE  );
    VerifyElementType( 4, DT_DOUBLE  );
    VerifyElementType( 3, DT_DOUBLE  );
    VerifyElementType( 2, DT_DOUBLE  );
    VerifyElementType( 1, DT_INTEGER );
    VerifyElementType( 0, DT_INTEGER );

    VMPage* poPage = m_poVirtualChip->m_psStackPointer[ 7 ].v.v_page;

    dblTop      = m_poVirtualChip->m_psStackPointer[ 6 ].v.v_double; 
    dblLeft     = m_poVirtualChip->m_psStackPointer[ 5 ].v.v_double;
    dblBottom   = m_poVirtualChip->m_psStackPointer[ 4 ].v.v_double;
    dblRight    = m_poVirtualChip->m_psStackPointer[ 3 ].v.v_double;
    dblLineSize = m_poVirtualChip->m_psStackPointer[ 2 ].v.v_double;

    iFillFlag   = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_integer;
    iPenFlag    = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_integer;
  
    poPage->Box( static_cast< int >( dblTop      ), 
                 static_cast< int >( dblLeft     ), 
                 static_cast< int >( dblBottom   ), 
                 static_cast< int >( dblRight    ), 
                 static_cast< int >( dblLineSize ), 
                 iFillFlag, 
                 iPenFlag );	// 2b|!2b==?
  }
  else
  if ( iArgc == 7 )
  {
    VerifyElementType( 6, DT_REPORTPAGE );
    VerifyElementType( 5, DT_DOUBLE  );
    VerifyElementType( 4, DT_DOUBLE  );
    VerifyElementType( 3, DT_DOUBLE  );
    VerifyElementType( 2, DT_DOUBLE  );
    VerifyElementType( 1, DT_DOUBLE  );
    VerifyElementType( 0, DT_INTEGER );

    VMPage* poPage = m_poVirtualChip->m_psStackPointer[ 6 ].v.v_page;

    dblTop      = m_poVirtualChip->m_psStackPointer[ 5 ].v.v_double; 
    dblLeft     = m_poVirtualChip->m_psStackPointer[ 4 ].v.v_double;
    dblBottom   = m_poVirtualChip->m_psStackPointer[ 3 ].v.v_double;
    dblRight    = m_poVirtualChip->m_psStackPointer[ 2 ].v.v_double;
    dblLineSize = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_double;

    iFillFlag   = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_integer;
  
    poPage->Box( static_cast< int >( dblTop      ), 
                 static_cast< int >( dblLeft     ), 
                 static_cast< int >( dblBottom   ), 
                 static_cast< int >( dblRight    ), 
                 static_cast< int >( dblLineSize ), 
                 iFillFlag, 
                 iPenFlag );	// 2b|!2b==?
  }
  else
  if ( iArgc == 6 )
  {
    VerifyElementType( 5, DT_REPORTPAGE );
    VerifyElementType( 4, DT_DOUBLE  );
    VerifyElementType( 3, DT_DOUBLE  );
    VerifyElementType( 2, DT_DOUBLE  );
    VerifyElementType( 1, DT_DOUBLE  );
    VerifyElementType( 0, DT_DOUBLE  );

    VMPage* poPage = m_poVirtualChip->m_psStackPointer[ 5 ].v.v_page;

    dblTop      = m_poVirtualChip->m_psStackPointer[ 4 ].v.v_double; 
    dblLeft     = m_poVirtualChip->m_psStackPointer[ 3 ].v.v_double;
    dblBottom   = m_poVirtualChip->m_psStackPointer[ 2 ].v.v_double;
    dblRight    = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_double;
    dblLineSize = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_double;
  
    poPage->Box( static_cast< int >( dblTop      ), 
                 static_cast< int >( dblLeft     ), 
                 static_cast< int >( dblBottom   ), 
                 static_cast< int >( dblRight    ), 
                 static_cast< int >( dblLineSize ), 
                 iFillFlag, 
                 iPenFlag );	// 2b|!2b==?
  }

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], true );
  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerPageDrawBox"
/*****************************************************************************/


/*****************************************************************************/
/*

     FUNCTION NAME:  VMVirtualOpSys::HandlerPageDrawCheckBox

       DESCRIPTION:  draws a checkbox into a report page

             INPUT:  iArgc - count of script params passed to this
            OUTPUT:  none

           RETURNS:  zero
*/
int VMVirtualOpSys::HandlerPageDrawCheckBox( int iArgc )
{
  m_poInterpreter->SetLastCall( "PageDrawCheckBox" );

  VMPage* poPage = NULL;
  char*   pchCaption;
  BOOL    bChecked;
  double  dblTop; 
  double  dblLeft;
  int     iFontSize;
  int     iDirection = LABEL_RIGHT;
  int     iLineSize  = 2;
  UINT    iFillFlag  = FILL_NONE;
  UINT    iTextFlag  = TEXT_NORMAL | TEXT_NOCLIP | TEXT_SINGLELINE;

  if ( iArgc == 10 )
  {
    VerifyElementType( 9, DT_REPORTPAGE );
    VerifyElementType( 8, DT_STRING  );
    VerifyElementType( 7, DT_BYTE    );
    VerifyElementType( 6, DT_DOUBLE  );
    VerifyElementType( 5, DT_DOUBLE  );
    VerifyElementType( 4, DT_INTEGER );
    VerifyElementType( 3, DT_INTEGER );
    VerifyElementType( 2, DT_INTEGER );
    VerifyElementType( 1, DT_INTEGER );
    VerifyElementType( 0, DT_INTEGER );
   
    VMPage* poPage = m_poVirtualChip->m_psStackPointer[ 9 ].v.v_page;

    pchCaption = m_poVirtualChip->m_psStackPointer[ 8 ].v.v_string->str_data; 
    bChecked   = m_poVirtualChip->m_psStackPointer[ 7 ].v.v_byte;
    dblTop     = m_poVirtualChip->m_psStackPointer[ 6 ].v.v_double;
    dblLeft    = m_poVirtualChip->m_psStackPointer[ 5 ].v.v_double;
    iFontSize  = m_poVirtualChip->m_psStackPointer[ 4 ].v.v_integer;
    iDirection = m_poVirtualChip->m_psStackPointer[ 3 ].v.v_integer;
    iLineSize  = m_poVirtualChip->m_psStackPointer[ 2 ].v.v_integer;
    iFillFlag  = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_integer;
    iTextFlag  = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_integer;
  
    poPage->CheckBox( pchCaption, bChecked, dblTop, dblLeft, iFontSize, iDirection, iLineSize, iFillFlag, iTextFlag );
  }
  else
  if ( iArgc == 9 )
  {
    VerifyElementType( 8, DT_REPORTPAGE );
    VerifyElementType( 7, DT_STRING  );
    VerifyElementType( 6, DT_BYTE    );
    VerifyElementType( 5, DT_DOUBLE  );
    VerifyElementType( 4, DT_DOUBLE  );
    VerifyElementType( 3, DT_INTEGER );
    VerifyElementType( 2, DT_INTEGER );
    VerifyElementType( 1, DT_INTEGER );
    VerifyElementType( 0, DT_INTEGER );
   
    VMPage* poPage = m_poVirtualChip->m_psStackPointer[ 8 ].v.v_page;

    pchCaption = m_poVirtualChip->m_psStackPointer[ 7 ].v.v_string->str_data; 
    bChecked   = m_poVirtualChip->m_psStackPointer[ 6 ].v.v_byte;
    dblTop     = m_poVirtualChip->m_psStackPointer[ 5 ].v.v_double;
    dblLeft    = m_poVirtualChip->m_psStackPointer[ 4 ].v.v_double;
    iFontSize  = m_poVirtualChip->m_psStackPointer[ 3 ].v.v_integer;
    iDirection = m_poVirtualChip->m_psStackPointer[ 2 ].v.v_integer;
    iLineSize  = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_integer;
    iFillFlag  = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_integer;
  
    poPage->CheckBox( pchCaption, bChecked, dblTop, dblLeft, iFontSize, iDirection, iLineSize, iFillFlag, iTextFlag );
  }
  else
  if ( iArgc == 8 )
  {
    VerifyElementType( 7, DT_REPORTPAGE );
    VerifyElementType( 6, DT_STRING  );
    VerifyElementType( 5, DT_BYTE    );
    VerifyElementType( 4, DT_DOUBLE  );
    VerifyElementType( 3, DT_DOUBLE  );
    VerifyElementType( 2, DT_INTEGER );
    VerifyElementType( 1, DT_INTEGER );
    VerifyElementType( 0, DT_INTEGER );
   
    VMPage* poPage = m_poVirtualChip->m_psStackPointer[ 7 ].v.v_page;

    pchCaption = m_poVirtualChip->m_psStackPointer[ 6 ].v.v_string->str_data; 
    bChecked   = m_poVirtualChip->m_psStackPointer[ 5 ].v.v_byte;
    dblTop     = m_poVirtualChip->m_psStackPointer[ 4 ].v.v_double;
    dblLeft    = m_poVirtualChip->m_psStackPointer[ 3 ].v.v_double;
    iFontSize  = m_poVirtualChip->m_psStackPointer[ 2 ].v.v_integer;
    iDirection = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_integer;
    iLineSize  = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_integer;
  
    poPage->CheckBox( pchCaption, bChecked, dblTop, dblLeft, iFontSize, iDirection, iLineSize, iFillFlag, iTextFlag );
  }
  else
  if ( iArgc == 7 )
  {
    VerifyElementType( 6, DT_REPORTPAGE );
    VerifyElementType( 5, DT_STRING  );
    VerifyElementType( 4, DT_BYTE    );
    VerifyElementType( 3, DT_DOUBLE  );
    VerifyElementType( 2, DT_DOUBLE  );
    VerifyElementType( 1, DT_INTEGER );
    VerifyElementType( 0, DT_INTEGER );
   
    VMPage* poPage = m_poVirtualChip->m_psStackPointer[ 6 ].v.v_page;

    pchCaption = m_poVirtualChip->m_psStackPointer[ 5 ].v.v_string->str_data; 
    bChecked   = m_poVirtualChip->m_psStackPointer[ 4 ].v.v_byte;
    dblTop     = m_poVirtualChip->m_psStackPointer[ 3 ].v.v_double;
    dblLeft    = m_poVirtualChip->m_psStackPointer[ 2 ].v.v_double;
    iFontSize  = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_integer;
    iDirection = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_integer;
  
    poPage->CheckBox( pchCaption, bChecked, dblTop, dblLeft, iFontSize, iDirection, iLineSize, iFillFlag, iTextFlag );
  }

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], true );
  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerPageDrawCheckBox"
/*****************************************************************************/


/*****************************************************************************/
/*

     FUNCTION NAME:  VMVirtualOpSys::HandlerPagePrintRotatedText

       DESCRIPTION:  prints rotated text into a page context

             INPUT:  iArgc - count of script params passed to this
            OUTPUT:  none

           RETURNS:  zero
*/
int VMVirtualOpSys::HandlerPagePrintRotatedText( int iArgc )
{
  m_poInterpreter->SetLastCall( "PagePrintRotatedText" );

  VMPage* poPage = NULL;
  double  dblTop; 
  double  dblLeft;
  double  dblBottom;
  double  dblRight;
  UINT    iFlags;
  UINT    iPointSize;
  char*   pchText;
  int     iAngle;

  VerifyRunLineArguments( iArgc, 9 );
  VerifyElementType( 8, DT_REPORTPAGE );
  VerifyElementType( 7, DT_DOUBLE  );
  VerifyElementType( 6, DT_DOUBLE  );
  VerifyElementType( 5, DT_DOUBLE  );
  VerifyElementType( 4, DT_DOUBLE  );
  VerifyElementType( 3, DT_INTEGER );
  VerifyElementType( 2, DT_INTEGER );
  VerifyElementType( 1, DT_STRING  );
  VerifyElementType( 0, DT_INTEGER );

  poPage      = m_poVirtualChip->m_psStackPointer[ 8 ].v.v_page;

  dblTop      = m_poVirtualChip->m_psStackPointer[ 7 ].v.v_double; 
  dblLeft     = m_poVirtualChip->m_psStackPointer[ 6 ].v.v_double;
  dblBottom   = m_poVirtualChip->m_psStackPointer[ 5 ].v.v_double;
  dblRight    = m_poVirtualChip->m_psStackPointer[ 4 ].v.v_double;
  iFlags      = m_poVirtualChip->m_psStackPointer[ 3 ].v.v_integer;
  iPointSize  = m_poVirtualChip->m_psStackPointer[ 2 ].v.v_integer;
  pchText     = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_string->str_data;
  iAngle      = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_integer;
  
  poPage->PrintRotatedText( dblTop, dblLeft, dblBottom, dblRight, iFlags, iPointSize, pchText, iAngle );

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], true );
  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerPagePrintRotatedText"
/*****************************************************************************/


/*****************************************************************************/
/*

     FUNCTION NAME:  VMVirtualOpSys::HandlerRegionDrawCheckBox

       DESCRIPTION:  draws a checkbox into a region

             INPUT:  iArgc - count of script params passed to this
            OUTPUT:  none

           RETURNS:  zero
*/
int  VMVirtualOpSys::HandlerRegionDrawCheckBox( int iArgc )
{
  m_poInterpreter->SetLastCall( "PageRegionDrawCheckBox" );

  VMPage*        poPage = NULL;
  VMPrintRegion* poRegion; 
  char*          pchCaption;
  BOOL           bChecked; 
  double         dblTop; 
  double         dblLeft; 
  int            iFontSize; 
  int            iDirection = LABEL_RIGHT;
  int            iLineSize  = 1;
  UINT           iFillFlags = FILL_NONE;
  UINT           iTextFlags = TEXT_NORMAL | TEXT_NOCLIP | TEXT_SINGLELINE;

  if ( iArgc == 11 )
  {
    VerifyElementType( 10, DT_REPORTPAGE );
    VerifyElementType( 9, DT_REPORTPAGEREGION );
    VerifyElementType( 8, DT_STRING  );
    VerifyElementType( 7, DT_BYTE    );
    VerifyElementType( 6, DT_DOUBLE  );
    VerifyElementType( 5, DT_DOUBLE  );
    VerifyElementType( 4, DT_INTEGER );
    VerifyElementType( 3, DT_INTEGER );
    VerifyElementType( 2, DT_INTEGER );
    VerifyElementType( 1, DT_INTEGER );
    VerifyElementType( 0, DT_INTEGER );
   
    poPage     = m_poVirtualChip->m_psStackPointer[ 10 ].v.v_page;
    poRegion   = m_poVirtualChip->m_psStackPointer[ 9 ].v.v_pageregion;
    pchCaption = m_poVirtualChip->m_psStackPointer[ 8 ].v.v_string->str_data; 
    bChecked   = m_poVirtualChip->m_psStackPointer[ 7 ].v.v_byte;
    dblTop     = m_poVirtualChip->m_psStackPointer[ 6 ].v.v_double;
    dblLeft    = m_poVirtualChip->m_psStackPointer[ 5 ].v.v_double;
    iFontSize  = m_poVirtualChip->m_psStackPointer[ 4 ].v.v_integer;
    iDirection = m_poVirtualChip->m_psStackPointer[ 3 ].v.v_integer;
    iLineSize  = m_poVirtualChip->m_psStackPointer[ 2 ].v.v_integer;
    iFillFlags = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_integer;
    iTextFlags = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_integer;
  
    poPage->CheckBox( poRegion, pchCaption, bChecked, dblTop, dblLeft, iFontSize, iDirection, iLineSize, iFillFlags, iTextFlags );
  }
  else
  if ( iArgc == 10 )
  {
    VerifyElementType( 9, DT_REPORTPAGE );
    VerifyElementType( 8, DT_REPORTPAGEREGION );
    VerifyElementType( 7, DT_STRING  );
    VerifyElementType( 6, DT_BYTE    );
    VerifyElementType( 5, DT_DOUBLE  );
    VerifyElementType( 4, DT_DOUBLE  );
    VerifyElementType( 3, DT_INTEGER );
    VerifyElementType( 2, DT_INTEGER );
    VerifyElementType( 1, DT_INTEGER );
    VerifyElementType( 0, DT_INTEGER );
   
    poPage     = m_poVirtualChip->m_psStackPointer[ 9 ].v.v_page;
    poRegion   = m_poVirtualChip->m_psStackPointer[ 8 ].v.v_pageregion;
    pchCaption = m_poVirtualChip->m_psStackPointer[ 7 ].v.v_string->str_data; 
    bChecked   = m_poVirtualChip->m_psStackPointer[ 6 ].v.v_byte;
    dblTop     = m_poVirtualChip->m_psStackPointer[ 5 ].v.v_double;
    dblLeft    = m_poVirtualChip->m_psStackPointer[ 4 ].v.v_double;
    iFontSize  = m_poVirtualChip->m_psStackPointer[ 3 ].v.v_integer;
    iDirection = m_poVirtualChip->m_psStackPointer[ 2 ].v.v_integer;
    iLineSize  = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_integer;
    iFillFlags = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_integer;
  
    poPage->CheckBox( poRegion, pchCaption, bChecked, dblTop, dblLeft, iFontSize, iDirection, iLineSize, iFillFlags, iTextFlags );
  }
  else
  if ( iArgc == 9 )
  {
    VerifyElementType( 8, DT_REPORTPAGE );
    VerifyElementType( 7, DT_REPORTPAGEREGION );
    VerifyElementType( 6, DT_STRING  );
    VerifyElementType( 5, DT_BYTE    );
    VerifyElementType( 4, DT_DOUBLE  );
    VerifyElementType( 3, DT_DOUBLE  );
    VerifyElementType( 2, DT_INTEGER );
    VerifyElementType( 1, DT_INTEGER );
    VerifyElementType( 0, DT_INTEGER );
   
    poPage     = m_poVirtualChip->m_psStackPointer[ 8 ].v.v_page;
    poRegion   = m_poVirtualChip->m_psStackPointer[ 7 ].v.v_pageregion;
    pchCaption = m_poVirtualChip->m_psStackPointer[ 6 ].v.v_string->str_data; 
    bChecked   = m_poVirtualChip->m_psStackPointer[ 5 ].v.v_byte;
    dblTop     = m_poVirtualChip->m_psStackPointer[ 4 ].v.v_double;
    dblLeft    = m_poVirtualChip->m_psStackPointer[ 3 ].v.v_double;
    iFontSize  = m_poVirtualChip->m_psStackPointer[ 2 ].v.v_integer;
    iDirection = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_integer;
    iLineSize  = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_integer;
  
    poPage->CheckBox( poRegion, pchCaption, bChecked, dblTop, dblLeft, iFontSize, iDirection, iLineSize, iFillFlags, iTextFlags );
  }
  else
  if ( iArgc == 8 )
  {
    VerifyElementType( 7, DT_REPORTPAGE );
    VerifyElementType( 6, DT_REPORTPAGEREGION );
    VerifyElementType( 5, DT_STRING  );
    VerifyElementType( 4, DT_BYTE    );
    VerifyElementType( 3, DT_DOUBLE  );
    VerifyElementType( 2, DT_DOUBLE  );
    VerifyElementType( 1, DT_INTEGER );
    VerifyElementType( 0, DT_INTEGER );
   
    poPage     = m_poVirtualChip->m_psStackPointer[ 7 ].v.v_page;
    poRegion   = m_poVirtualChip->m_psStackPointer[ 6 ].v.v_pageregion;
    pchCaption = m_poVirtualChip->m_psStackPointer[ 5 ].v.v_string->str_data; 
    bChecked   = m_poVirtualChip->m_psStackPointer[ 4 ].v.v_byte;
    dblTop     = m_poVirtualChip->m_psStackPointer[ 3 ].v.v_double;
    dblLeft    = m_poVirtualChip->m_psStackPointer[ 2 ].v.v_double;
    iFontSize  = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_integer;
    iDirection = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_integer;
  
    poPage->CheckBox( poRegion, pchCaption, bChecked, dblTop, dblLeft, iFontSize, iDirection, iLineSize, iFillFlags, iTextFlags );
  }

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], true );
  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerRegionDrawCheckBox"
/*****************************************************************************/


/*****************************************************************************/
/*

     FUNCTION NAME:  VMVirtualOpSys::HandlerPageCreateRegion

       DESCRIPTION:  create a page region

             INPUT:  iArgc - count of script params passed to this
            OUTPUT:  none

           RETURNS:  zero
*/
int VMVirtualOpSys::HandlerPageCreateRegion( int iArgc )
{
  m_poInterpreter->SetLastCall( "PageCreateRegion" );

  VMPage* poPage = NULL;
  double  dblTop; 
  double  dblLeft;
  double  dblBottom;
  double  dblRight;
  UINT    iFill = FILL_NONE;

  if ( iArgc == 5 )
  {
    VerifyElementType( 4, DT_REPORTPAGE );
    VerifyElementType( 3, DT_DOUBLE  );
    VerifyElementType( 2, DT_DOUBLE  );
    VerifyElementType( 1, DT_DOUBLE  );
    VerifyElementType( 0, DT_DOUBLE  );

    poPage      = m_poVirtualChip->m_psStackPointer[ 4 ].v.v_page;
    dblTop      = m_poVirtualChip->m_psStackPointer[ 3 ].v.v_double; 
    dblLeft     = m_poVirtualChip->m_psStackPointer[ 2 ].v.v_double;
    dblBottom   = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_double;
    dblRight    = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_double;
  
    VMPrintRegion* poResult = poPage->CreateRegion( dblTop, dblLeft, dblBottom, dblRight, iFill );
/*
    VMTrackedAllocs* poAlloc = new VMTrackedAllocs;
    poAlloc->v.v_pageregion  = poResult;
    poAlloc->v_type          = DT_REPORTPAGEREGION;
    m_oTrackedAllocs.push_back( poAlloc );
*/
    set_pageregion( &m_poVirtualChip->m_psStackPointer[iArgc], poResult );
  }
  else
  if ( iArgc == 6 )
  {
    VerifyElementType( 5, DT_REPORTPAGE );
    VerifyElementType( 4, DT_DOUBLE  );
    VerifyElementType( 3, DT_DOUBLE  );
    VerifyElementType( 2, DT_DOUBLE  );
    VerifyElementType( 1, DT_DOUBLE  );
    VerifyElementType( 0, DT_INTEGER  );

    poPage      = m_poVirtualChip->m_psStackPointer[ 5 ].v.v_page;
    dblTop      = m_poVirtualChip->m_psStackPointer[ 4 ].v.v_double; 
    dblLeft     = m_poVirtualChip->m_psStackPointer[ 3 ].v.v_double;
    dblBottom   = m_poVirtualChip->m_psStackPointer[ 2 ].v.v_double;
    dblRight    = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_double;
    iFill       = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_integer;
  
    VMPrintRegion* poResult = poPage->CreateRegion( dblTop, dblLeft, dblBottom, dblRight, iFill );
/*
    VMTrackedAllocs* poAlloc = new VMTrackedAllocs;
    poAlloc->v.v_pageregion  = poResult;
    poAlloc->v_type          = DT_REPORTPAGEREGION;
    m_oTrackedAllocs.push_back( poAlloc );
*/
    set_pageregion( &m_poVirtualChip->m_psStackPointer[iArgc], poResult );
  }

  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerPageCreateRegion"
/*****************************************************************************/


/*****************************************************************************/
/*

     FUNCTION NAME:  VMVirtualOpSys::HandlerPageCreateSubRegion

       DESCRIPTION:  creates a region bounded by another page region

             INPUT:  iArgc - count of script params passed to this
            OUTPUT:  none

           RETURNS:  zero
*/
int VMVirtualOpSys::HandlerPageCreateSubRegion( int iArgc )
{
  m_poInterpreter->SetLastCall( "PageCreateSubRegion" );

  VMPage*        poPage = NULL;
  VMPrintRegion* poParent; 
  double  dblTop; 
  double  dblLeft;
  double  dblBottom;
  double  dblRight;
  int     iFill = FILL_NONE;

  if ( iArgc == 6 )
  {
    VerifyElementType( 5, DT_REPORTPAGE );
    VerifyElementType( 4, DT_REPORTPAGEREGION );
    VerifyElementType( 3, DT_DOUBLE  );
    VerifyElementType( 2, DT_DOUBLE  );
    VerifyElementType( 1, DT_DOUBLE  );
    VerifyElementType( 0, DT_DOUBLE  );

    poPage      = m_poVirtualChip->m_psStackPointer[ 5 ].v.v_page;
    poParent    = m_poVirtualChip->m_psStackPointer[ 4 ].v.v_pageregion;
    dblTop      = m_poVirtualChip->m_psStackPointer[ 3 ].v.v_double; 
    dblLeft     = m_poVirtualChip->m_psStackPointer[ 2 ].v.v_double;
    dblBottom   = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_double;
    dblRight    = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_double;
  
    VMPrintRegion* poResult = poPage->CreateSubRegion( poParent, dblTop, dblLeft, dblBottom, dblRight, iFill );
/*
    VMTrackedAllocs* poAlloc = new VMTrackedAllocs;
    poAlloc->v.v_pageregion  = poResult;
    poAlloc->v_type          = DT_REPORTPAGEREGION;
    m_oTrackedAllocs.push_back( poAlloc );
*/
    set_pageregion( &m_poVirtualChip->m_psStackPointer[iArgc], poResult );
  }
  else
  if ( iArgc == 7 )
  {
    VerifyElementType( 6, DT_REPORTPAGE );
    VerifyElementType( 5, DT_REPORTPAGEREGION );
    VerifyElementType( 4, DT_DOUBLE  );
    VerifyElementType( 3, DT_DOUBLE  );
    VerifyElementType( 2, DT_DOUBLE  );
    VerifyElementType( 1, DT_DOUBLE  );
    VerifyElementType( 0, DT_INTEGER );

    poPage      = m_poVirtualChip->m_psStackPointer[ 6 ].v.v_page;
    poParent    = m_poVirtualChip->m_psStackPointer[ 5 ].v.v_pageregion;
    dblTop      = m_poVirtualChip->m_psStackPointer[ 4 ].v.v_double; 
    dblLeft     = m_poVirtualChip->m_psStackPointer[ 3 ].v.v_double;
    dblBottom   = m_poVirtualChip->m_psStackPointer[ 2 ].v.v_double;
    dblRight    = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_double;
    iFill       = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_integer;
  
    VMPrintRegion* poResult = poPage->CreateSubRegion( poParent, dblTop, dblLeft, dblBottom, dblRight, iFill );
/*
    VMTrackedAllocs* poAlloc = new VMTrackedAllocs;
    poAlloc->v.v_pageregion  = poResult;
    poAlloc->v_type          = DT_REPORTPAGEREGION;
    m_oTrackedAllocs.push_back( poAlloc );
*/
    set_pageregion( &m_poVirtualChip->m_psStackPointer[iArgc], poResult );
  }

  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerPageCreateSubRegion"
/*****************************************************************************/


/*****************************************************************************/
/*

     FUNCTION NAME:  VMVirtualOpSys::HandlerPagePrintText

       DESCRIPTION:  prints text into a report page

             INPUT:  iArgc - count of script params passed to this
            OUTPUT:  none

           RETURNS:  zero
*/
int VMVirtualOpSys::HandlerPagePrintText( int iArgc )
{
  m_poInterpreter->SetLastCall( "PagePrintText" );

  VMPage* poPage = NULL;
  double  dblTop; 
  double  dblLeft;
  UINT    iFlags;
  UINT    iPointSize;
  char*   pchText;

  VerifyRunLineArguments( iArgc, 6 );
  VerifyElementType( 5, DT_REPORTPAGE );
  VerifyElementType( 4, DT_DOUBLE  );
  VerifyElementType( 3, DT_DOUBLE  );
  VerifyElementType( 2, DT_INTEGER );
  VerifyElementType( 1, DT_INTEGER );
  VerifyElementType( 0, DT_STRING  );

  poPage      = m_poVirtualChip->m_psStackPointer[ 5 ].v.v_page;
  dblTop      = m_poVirtualChip->m_psStackPointer[ 4 ].v.v_double; 
  dblLeft     = m_poVirtualChip->m_psStackPointer[ 3 ].v.v_double;
  iFlags      = m_poVirtualChip->m_psStackPointer[ 2 ].v.v_integer;
  iPointSize  = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_integer;
  pchText     = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_string->str_data;
  
  double dblResult;
  dblResult = poPage->Print( dblTop, dblLeft, iFlags, iPointSize, pchText );

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], dblResult );
  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerPagePrintText"
/*****************************************************************************/


/*****************************************************************************/
/*

     FUNCTION NAME:  VMVirtualOpSys::HandlerRegionDrawBorder

       DESCRIPTION:  draws a border around a page region

             INPUT:  iArgc - count of script params passed to this
            OUTPUT:  none

           RETURNS:  zero
*/
int VMVirtualOpSys::HandlerRegionDrawBorder( int iArgc )
{
  m_poInterpreter->SetLastCall( "RegionDrawBorder" );

  VerifyRunLineArguments( iArgc, 1 );
  VerifyElementType( 0, DT_REPORTPAGEREGION );

  m_poVirtualChip->m_psStackPointer[ 0 ].v.v_pageregion->DrawBorder();

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], true );
  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerRegionDrawBorder"
/*****************************************************************************/


/*****************************************************************************/
/*

     FUNCTION NAME:  VMVirtualOpSys::HandlerRegionDrawTitle

       DESCRIPTION:  draws a title box onto a page region

             INPUT:  iArgc - count of script params passed to this
            OUTPUT:  none

           RETURNS:  zero
*/
int VMVirtualOpSys::HandlerRegionDrawTitle( int iArgc )
{
  m_poInterpreter->SetLastCall( "RegionDrawTitle" );

  VMPrintRegion* poRegion;
  char*          pchText;
  int            iPointSize = 8;
  UINT           iTextFlags = TEXT_BOLD | TEXT_CENTER | TEXT_RECT;
  UINT           iFillFlags = FILL_NONE;

  if ( iArgc == 5 )
  {
    VerifyElementType( 4, DT_REPORTPAGEREGION );
    VerifyElementType( 3, DT_STRING  );
    VerifyElementType( 2, DT_INTEGER  );
    VerifyElementType( 1, DT_INTEGER );
    VerifyElementType( 0, DT_INTEGER );

    poRegion    = m_poVirtualChip->m_psStackPointer[ 4 ].v.v_pageregion; 
    pchText     = m_poVirtualChip->m_psStackPointer[ 3 ].v.v_string->str_data;
    iPointSize  = m_poVirtualChip->m_psStackPointer[ 2 ].v.v_integer;
    iTextFlags  = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_integer;
    iFillFlags  = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_integer;

    poRegion->DrawTitle( pchText, iPointSize, iTextFlags, iFillFlags );
  }
  else
  if ( iArgc == 4 )
  {
    VerifyElementType( 3, DT_REPORTPAGEREGION );
    VerifyElementType( 2, DT_STRING  );
    VerifyElementType( 1, DT_INTEGER  );
    VerifyElementType( 0, DT_INTEGER );

    poRegion    = m_poVirtualChip->m_psStackPointer[ 3 ].v.v_pageregion; 
    pchText     = m_poVirtualChip->m_psStackPointer[ 2 ].v.v_string->str_data;
    iPointSize  = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_integer;
    iTextFlags  = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_integer;

    poRegion->DrawTitle( pchText, iPointSize, iTextFlags, iFillFlags );
  }
  else
  if ( iArgc == 3 )
  {
    VerifyElementType( 2, DT_REPORTPAGEREGION );
    VerifyElementType( 1, DT_STRING  );
    VerifyElementType( 0, DT_INTEGER  );

    poRegion    = m_poVirtualChip->m_psStackPointer[ 2 ].v.v_pageregion; 
    pchText     = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_string->str_data;
    iPointSize  = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_integer;

    poRegion->DrawTitle( pchText, iPointSize, iTextFlags, iFillFlags );
  }
  else
  if ( iArgc == 2 )
  {
    VerifyElementType( 1, DT_REPORTPAGEREGION );
    VerifyElementType( 0, DT_STRING  );

    poRegion    = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_pageregion; 
    pchText     = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_string->str_data;

    poRegion->DrawTitle( pchText, iPointSize, iTextFlags, iFillFlags );
  }

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], true );
  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerRegionDrawTitle"
/*****************************************************************************/


/*****************************************************************************/
/*

     FUNCTION NAME:  VMVirtualOpSys::HandlerPageSetLineSpacing

       DESCRIPTION:  sets the default line spacing for a report page

             INPUT:  iArgc - count of script params passed to this
            OUTPUT:  none

           RETURNS:  zero
*/
int VMVirtualOpSys::HandlerPageSetLineSpacing( int iArgc )
{
  m_poInterpreter->SetLastCall( "PageSetLineSpacing" );

  VMPage* poPage = NULL;
  double  dblSpace; 

  VerifyRunLineArguments( iArgc, 2 );
  VerifyElementType( 1, DT_REPORTPAGE );
  VerifyElementType( 0, DT_DOUBLE  );

  poPage   = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_page;
  dblSpace = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_double; 
  
  poPage->SetLineSpacing( dblSpace );

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], true );
  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerPageSetLineSpacing"
/*****************************************************************************/


/*****************************************************************************/
/*

     FUNCTION NAME:  VMVirtualOpSys::HandlerPagePrintToRegion

       DESCRIPTION:  prints text into a page region

             INPUT:  iArgc - count of script params passed to this
            OUTPUT:  none

           RETURNS:  zero
*/
int VMVirtualOpSys::HandlerPagePrintToRegion( int iArgc )
{
  m_poInterpreter->SetLastCall( "PagePrintToRegion" );

  VMPage*        poPage = NULL;
  VMPrintRegion* poRegion; 
  double         dblTop;
  double         dblLeft;
  UINT           iTextFlags;
  int            iPointSize;
  char*          pchText;

  VerifyRunLineArguments( iArgc, 7 );
  VerifyElementType( 6, DT_REPORTPAGE );
  VerifyElementType( 5, DT_REPORTPAGEREGION );
  VerifyElementType( 4, DT_DOUBLE  );
  VerifyElementType( 3, DT_DOUBLE  );
  VerifyElementType( 2, DT_INTEGER );
  VerifyElementType( 1, DT_INTEGER );
  VerifyElementType( 0, DT_STRING  );

  poPage      = m_poVirtualChip->m_psStackPointer[ 6 ].v.v_page; 
  poRegion    = m_poVirtualChip->m_psStackPointer[ 5 ].v.v_pageregion; 
  dblTop      = m_poVirtualChip->m_psStackPointer[ 4 ].v.v_double;
  dblLeft     = m_poVirtualChip->m_psStackPointer[ 3 ].v.v_double;
  iTextFlags  = m_poVirtualChip->m_psStackPointer[ 2 ].v.v_integer;
  iPointSize  = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_integer;
  pchText     = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_string->str_data;
  
  double dblRow = poPage->Print( poRegion, dblTop, dblLeft, iTextFlags, iPointSize, pchText );

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], dblRow );
  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerPagePrintToRegion"
/*****************************************************************************/


/*****************************************************************************/
/*

     FUNCTION NAME:  VMVirtualOpSys::HandlerPageDrawLine

       DESCRIPTION:  draws a line into a page

             INPUT:  iArgc - count of script params passed to this
            OUTPUT:  none

           RETURNS:  zero
*/
int VMVirtualOpSys::HandlerPageDrawLine( int iArgc )
{
  m_poInterpreter->SetLastCall( "PageDrawLine" );

  VMPage*        poPage = NULL;
  double         dblTop;
  double         dblLeft;
  double         dblBottom;
  double         dblRight;
  int            iLineSize  = 1;
  UINT           iPenFlags  = PEN_SOLID;;

  if ( iArgc == 7 )
  {
    VerifyElementType( 6, DT_REPORTPAGE );
    VerifyElementType( 5, DT_DOUBLE   );
    VerifyElementType( 4, DT_DOUBLE   );
    VerifyElementType( 3, DT_DOUBLE   );
    VerifyElementType( 2, DT_DOUBLE   );
    VerifyElementType( 1, DT_INTEGER  );
    VerifyElementType( 0, DT_INTEGER  );

    poPage      = m_poVirtualChip->m_psStackPointer[ 6 ].v.v_page; 
    dblTop      = m_poVirtualChip->m_psStackPointer[ 5 ].v.v_double; 
    dblLeft     = m_poVirtualChip->m_psStackPointer[ 4 ].v.v_double;
    dblBottom   = m_poVirtualChip->m_psStackPointer[ 3 ].v.v_double;
    dblRight    = m_poVirtualChip->m_psStackPointer[ 2 ].v.v_double;
    iLineSize   = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_integer;
    iPenFlags   = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_integer;

    poPage->Line( dblTop, dblLeft, dblBottom, dblRight, iLineSize, iPenFlags );
  }
  else
  if ( iArgc == 6 )
  {
    VerifyElementType( 5, DT_REPORTPAGE );
    VerifyElementType( 4, DT_DOUBLE   );
    VerifyElementType( 3, DT_DOUBLE   );
    VerifyElementType( 2, DT_DOUBLE   );
    VerifyElementType( 1, DT_DOUBLE   );
    VerifyElementType( 0, DT_INTEGER  );

    poPage      = m_poVirtualChip->m_psStackPointer[ 5 ].v.v_page; 
    dblTop      = m_poVirtualChip->m_psStackPointer[ 4 ].v.v_double; 
    dblLeft     = m_poVirtualChip->m_psStackPointer[ 3 ].v.v_double;
    dblBottom   = m_poVirtualChip->m_psStackPointer[ 2 ].v.v_double;
    dblRight    = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_double;
    iLineSize   = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_integer;

    poPage->Line( dblTop, dblLeft, dblBottom, dblRight, iLineSize, iPenFlags );
  }
  else
  if ( iArgc == 5 )
  {
    VerifyElementType( 4, DT_REPORTPAGE );
    VerifyElementType( 3, DT_DOUBLE   );
    VerifyElementType( 2, DT_DOUBLE   );
    VerifyElementType( 1, DT_DOUBLE   );
    VerifyElementType( 0, DT_DOUBLE   );

    poPage      = m_poVirtualChip->m_psStackPointer[ 4 ].v.v_page; 
    dblTop      = m_poVirtualChip->m_psStackPointer[ 3 ].v.v_double; 
    dblLeft     = m_poVirtualChip->m_psStackPointer[ 2 ].v.v_double;
    dblBottom   = m_poVirtualChip->m_psStackPointer[ 2 ].v.v_double;
    dblRight    = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_double;

    poPage->Line( dblTop, dblLeft, dblBottom, dblRight, iLineSize, iPenFlags );
  }

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], true );
  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerPageDrawLine"
/*****************************************************************************/


/*****************************************************************************/
/*

     FUNCTION NAME:  VMVirtualOpSys::HandlerPageDrawLineInRegion

       DESCRIPTION:  draws a line into a page region

             INPUT:  iArgc - count of script params passed to this
            OUTPUT:  none

           RETURNS:  zero
*/
int VMVirtualOpSys::HandlerPageDrawLineInRegion( int iArgc )
{
  m_poInterpreter->SetLastCall( "PageDrawLineInRegion" );

  VMPage*        poPage = NULL;
  VMPrintRegion* poRegion;
  double         dblTop;
  double         dblLeft;
  double         dblBottom;
  double         dblRight;
  int            iLineSize  = 1;
  UINT           iPenFlags  = PEN_SOLID;;

  if ( iArgc == 8 )
  {
    VerifyElementType( 7, DT_REPORTPAGE );
    VerifyElementType( 6, DT_REPORTPAGEREGION );
    VerifyElementType( 5, DT_DOUBLE   );
    VerifyElementType( 4, DT_DOUBLE   );
    VerifyElementType( 3, DT_DOUBLE   );
    VerifyElementType( 2, DT_DOUBLE   );
    VerifyElementType( 1, DT_INTEGER  );
    VerifyElementType( 0, DT_INTEGER  );

    poPage      = m_poVirtualChip->m_psStackPointer[ 7 ].v.v_page; 
    poRegion    = m_poVirtualChip->m_psStackPointer[ 6 ].v.v_pageregion; 
    dblTop      = m_poVirtualChip->m_psStackPointer[ 5 ].v.v_double; 
    dblLeft     = m_poVirtualChip->m_psStackPointer[ 4 ].v.v_double;
    dblBottom   = m_poVirtualChip->m_psStackPointer[ 3 ].v.v_double;
    dblRight    = m_poVirtualChip->m_psStackPointer[ 2 ].v.v_double;
    iLineSize   = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_integer;
    iPenFlags   = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_integer;

    poPage->Line( poRegion, dblTop, dblLeft, dblBottom, dblRight, iLineSize, iPenFlags );
  }
  else
  if ( iArgc == 7 )
  {
    VerifyElementType( 6, DT_REPORTPAGE );
    VerifyElementType( 5, DT_REPORTPAGEREGION );
    VerifyElementType( 4, DT_DOUBLE   );
    VerifyElementType( 3, DT_DOUBLE   );
    VerifyElementType( 2, DT_DOUBLE   );
    VerifyElementType( 1, DT_DOUBLE   );
    VerifyElementType( 0, DT_INTEGER  );

    poPage      = m_poVirtualChip->m_psStackPointer[ 6 ].v.v_page; 
    poRegion    = m_poVirtualChip->m_psStackPointer[ 5 ].v.v_pageregion; 
    dblTop      = m_poVirtualChip->m_psStackPointer[ 4 ].v.v_double; 
    dblLeft     = m_poVirtualChip->m_psStackPointer[ 3 ].v.v_double;
    dblBottom   = m_poVirtualChip->m_psStackPointer[ 2 ].v.v_double;
    dblRight    = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_double;
    iLineSize   = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_integer;

    poPage->Line( poRegion, dblTop, dblLeft, dblBottom, dblRight, iLineSize, iPenFlags );
  }
  else
  if ( iArgc == 6 )
  {
    VerifyElementType( 5, DT_REPORTPAGE );
    VerifyElementType( 4, DT_REPORTPAGEREGION );
    VerifyElementType( 3, DT_DOUBLE   );
    VerifyElementType( 2, DT_DOUBLE   );
    VerifyElementType( 1, DT_DOUBLE   );
    VerifyElementType( 0, DT_DOUBLE   );

    poPage      = m_poVirtualChip->m_psStackPointer[ 5 ].v.v_page; 
    poRegion    = m_poVirtualChip->m_psStackPointer[ 4 ].v.v_pageregion; 
    dblTop      = m_poVirtualChip->m_psStackPointer[ 3 ].v.v_double; 
    dblLeft     = m_poVirtualChip->m_psStackPointer[ 2 ].v.v_double;
    dblBottom   = m_poVirtualChip->m_psStackPointer[ 2 ].v.v_double;
    dblRight    = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_double;

    poPage->Line( poRegion, dblTop, dblLeft, dblBottom, dblRight, iLineSize, iPenFlags );
  }

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], true );
  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerPageDrawLineInRegion"
/*****************************************************************************/


/*****************************************************************************/
/*

     FUNCTION NAME:  VMVirtualOpSys::HandlerTableSetPointSize

       DESCRIPTION:  sets the default point size for a report table

             INPUT:  iArgc - count of script params passed to this
            OUTPUT:  none

           RETURNS:  zero
*/
int VMVirtualOpSys::HandlerTableSetPointSize( int iArgc )
{
  m_poInterpreter->SetLastCall( "TableSetPointSize" );

  TABLEHEADER* poTable = NULL;
  int          iSize; 

  VerifyRunLineArguments( iArgc, 2 );
  VerifyElementType( 1, DT_REPORTTABLE );
  VerifyElementType( 0, DT_INTEGER  );

  poTable = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_pagetable;
  iSize   = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_integer; 

  poTable->PointSize = iSize;
  
  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], true );
  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerTableSetPointSize"
/*****************************************************************************/


/*****************************************************************************/
/*

     FUNCTION NAME:  VMVirtualOpSys::HandlerTableSetLineSize

       DESCRIPTION:  sets the linesize for a report table

             INPUT:  iArgc - count of script params passed to this
            OUTPUT:  none

           RETURNS:  zero
*/
int VMVirtualOpSys::HandlerTableSetLineSize( int iArgc )
{
  m_poInterpreter->SetLastCall( "TableSetLineSize" );

  TABLEHEADER* poTable = NULL;
  int          iSize; 

  VerifyRunLineArguments( iArgc, 2 );
  VerifyElementType( 1, DT_REPORTTABLE );
  VerifyElementType( 0, DT_INTEGER  );

  poTable = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_pagetable;
  iSize   = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_integer; 

  poTable->LineSize = iSize;
  
  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], true );
  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerTableSetLineSize"
/*****************************************************************************/


/*****************************************************************************/
/*

     FUNCTION NAME:  VMVirtualOpSys::HandlerTableSetUsesInches

       DESCRIPTION:  toggles inches measurement mode for a report table

             INPUT:  iArgc - count of script params passed to this
            OUTPUT:  none

           RETURNS:  zero
*/
int VMVirtualOpSys::HandlerTableSetUsesInches( int iArgc )
{
  m_poInterpreter->SetLastCall( "TableSetUsesInches" );

  TABLEHEADER* poTable = NULL;
  bool         bFlag; 

  VerifyRunLineArguments( iArgc, 2 );
  VerifyElementType( 1, DT_REPORTTABLE );
  VerifyElementType( 0, DT_BYTE  );

  poTable = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_pagetable;
  bFlag   = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_byte; 

  poTable->UseInches = bFlag;
  
  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], true );
  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerTableSetUsesInches"
/*****************************************************************************/


/*****************************************************************************/
/*

     FUNCTION NAME:  VMVirtualOpSys::HandlerTableSetAutoSize

       DESCRIPTION:  sets the auto-size attribute for a report table

             INPUT:  iArgc - count of script params passed to this
            OUTPUT:  none

           RETURNS:  zero
*/
int VMVirtualOpSys::HandlerTableSetAutoSize( int iArgc )
{
  m_poInterpreter->SetLastCall( "PageSetAutoSize" );

  TABLEHEADER* poTable = NULL;
  bool         bFlag; 

  VerifyRunLineArguments( iArgc, 2 );
  VerifyElementType( 1, DT_REPORTTABLE );
  VerifyElementType( 0, DT_BYTE  );

  poTable = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_pagetable;
  bFlag   = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_byte; 

  poTable->AutoSize = bFlag;

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], true );
  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerTableSetAutoSize"
/*****************************************************************************/


/*****************************************************************************/
/*

     FUNCTION NAME:  VMVirtualOpSys::HandlerTableSetHasBorder

       DESCRIPTION:  toggles the border state for a report table

             INPUT:  iArgc - count of script params passed to this
            OUTPUT:  none

           RETURNS:  zero
*/
int VMVirtualOpSys::HandlerTableSetHasBorder( int iArgc )
{
  m_poInterpreter->SetLastCall( "TableSetHasBorder" );

  TABLEHEADER* poTable = NULL;
  bool         bFlag; 

  VerifyRunLineArguments( iArgc, 2 );
  VerifyElementType( 1, DT_REPORTTABLE );
  VerifyElementType( 0, DT_BYTE  );

  poTable = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_pagetable;
  bFlag   = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_byte; 

  poTable->Border = bFlag;

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], true );
  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerTableSetHasBorder"
/*****************************************************************************/


/*****************************************************************************/
/*

     FUNCTION NAME:  VMVirtualOpSys::HandlerTableSetFillFlag

       DESCRIPTION:  sets the fill value for a report table

             INPUT:  iArgc - count of script params passed to this
            OUTPUT:  none

           RETURNS:  zero
*/
int VMVirtualOpSys::HandlerTableSetFillFlag( int iArgc )
{
  m_poInterpreter->SetLastCall( "TableSetFillFlag" );

  TABLEHEADER* poTable = NULL;
  int          iFill; 

  VerifyRunLineArguments( iArgc, 2 );
  VerifyElementType( 1, DT_REPORTTABLE );
  VerifyElementType( 0, DT_INTEGER  );

  poTable = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_pagetable;
  iFill   = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_integer; 

  poTable->FillFlag = iFill;
  
  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], true );
  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerTableSetFillFlag"
/*****************************************************************************/


/*****************************************************************************/
/*

     FUNCTION NAME:  VMVirtualOpSys::HandlerTableSetColumnCount

       DESCRIPTION:  sets the number of columns in a report table

             INPUT:  iArgc - count of script params passed to this
            OUTPUT:  none

           RETURNS:  zero
*/
int VMVirtualOpSys::HandlerTableSetColumnCount( int iArgc )
{
  m_poInterpreter->SetLastCall( "TableSetColumnCount" );

  TABLEHEADER* poTable = NULL;
  int          iCount; 

  VerifyRunLineArguments( iArgc, 2 );
  VerifyElementType( 1, DT_REPORTTABLE );
  VerifyElementType( 0, DT_INTEGER  );

  poTable = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_pagetable;
  iCount  = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_integer; 

  poTable->NumColumns = iCount;
  
  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], true );
  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerTableSetColumnCount"
/*****************************************************************************/


/*****************************************************************************/
/*

     FUNCTION NAME:  VMVirtualOpSys::HandlerTableSetRowCount

       DESCRIPTION:  sets the number of rows in a table

             INPUT:  iArgc - count of script params passed to this
            OUTPUT:  none

           RETURNS:  zero
*/
int VMVirtualOpSys::HandlerTableSetRowCount( int iArgc )
{
  m_poInterpreter->SetLastCall( "TableSetRowCount" );

  TABLEHEADER* poTable = NULL;
  int          iCount; 

  VerifyRunLineArguments( iArgc, 2 );
  VerifyElementType( 1, DT_REPORTTABLE );
  VerifyElementType( 0, DT_INTEGER  );

  poTable = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_pagetable;
  iCount   = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_integer; 

  poTable->NumRows = iCount;
  
  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], true );
  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerTableSetRowCount"
/*****************************************************************************/


/*****************************************************************************/
/*

     FUNCTION NAME:  VMVirtualOpSys::HandlerTableSetOrigin

       DESCRIPTION:  sets the top/left point for a report table

             INPUT:  iArgc - count of script params passed to this
            OUTPUT:  none

           RETURNS:  zero
*/
int VMVirtualOpSys::HandlerTableSetOrigin( int iArgc )
{
  m_poInterpreter->SetLastCall( "TableSetOrigin" );

  TABLEHEADER* poTable = NULL;
  double       dblX;
  double       dblY; 

  VerifyRunLineArguments( iArgc, 3 );
  VerifyElementType( 2, DT_REPORTTABLE );
  VerifyElementType( 1, DT_DOUBLE  );
  VerifyElementType( 0, DT_DOUBLE  );

  poTable = m_poVirtualChip->m_psStackPointer[ 2 ].v.v_pagetable;
  dblX    = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_double; 
  dblY    = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_double; 

  poTable->StartCol = dblX;
  poTable->StartRow = dblY;

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], true );
  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerTableSetOrigin"
/*****************************************************************************/


/*****************************************************************************/
/*

     FUNCTION NAME:  VMVirtualOpSys::HandlerTableSetRightMargin

       DESCRIPTION:  sets the right margin for a report table

             INPUT:  iArgc - count of script params passed to this
            OUTPUT:  none

           RETURNS:  zero
*/
int VMVirtualOpSys::HandlerTableSetRightMargin( int iArgc )
{
  m_poInterpreter->SetLastCall( "TableSetRightMargin" );

  TABLEHEADER* poTable = NULL;
  double       dblRight;

  VerifyRunLineArguments( iArgc, 2 );
  VerifyElementType( 1, DT_REPORTTABLE );
  VerifyElementType( 0, DT_DOUBLE  );

  poTable  = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_pagetable;
  dblRight = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_double; 

  poTable->EndCol = dblRight;

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], true );
  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerTableSetRightMargin"
/*****************************************************************************/


/*****************************************************************************/
/*

     FUNCTION NAME:  VMVirtualOpSys::HandlerTableAddColumn

       DESCRIPTION:  adds a column definition to a report table

             INPUT:  iArgc - count of script params passed to this
            OUTPUT:  none

           RETURNS:  zero
*/
int VMVirtualOpSys::HandlerTableAddColumn( int iArgc )
{
  m_poInterpreter->SetLastCall( "TableAddColumn" );

  TABLEHEADER* poTable = NULL;
  int          iIndex;
  double       dblWidth;
  char*        pchText;
  UINT         iFill = FILL_NONE;

  if ( iArgc ==  4 )
  {
    VerifyElementType( 3, DT_REPORTTABLE );
    VerifyElementType( 2, DT_INTEGER  );
    VerifyElementType( 1, DT_DOUBLE   );
    VerifyElementType( 0, DT_STRING   );

    poTable  = m_poVirtualChip->m_psStackPointer[ 3 ].v.v_pagetable;
    iIndex   = m_poVirtualChip->m_psStackPointer[ 2 ].v.v_integer;
    dblWidth = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_double;
    pchText  = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_string->str_data;

    poTable->ColDesc[ iIndex ].Init( dblWidth, pchText, iFill );
  }
  if ( iArgc ==  5 )
  {
    VerifyElementType( 4, DT_REPORTTABLE );
    VerifyElementType( 3, DT_INTEGER  );
    VerifyElementType( 2, DT_DOUBLE   );
    VerifyElementType( 1, DT_STRING   );
    VerifyElementType( 0, DT_INTEGER  );

    poTable  = m_poVirtualChip->m_psStackPointer[ 4 ].v.v_pagetable;
    iIndex   = m_poVirtualChip->m_psStackPointer[ 3 ].v.v_integer;
    dblWidth = m_poVirtualChip->m_psStackPointer[ 2 ].v.v_double;
    pchText  = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_string->str_data;
    iFill    = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_integer;  // mjs change here

    poTable->ColDesc[ iIndex ].Init( dblWidth, pchText, iFill );
  }
 
  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], true );
  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerTableAddColumn"
/*****************************************************************************/


/*****************************************************************************/
/*

     FUNCTION NAME:  VMVirtualOpSys::HandlerPageAddTable

       DESCRIPTION:  causes a table to print into a page

             INPUT:  iArgc - count of script params passed to this
            OUTPUT:  none

           RETURNS:  zero
*/
int VMVirtualOpSys::HandlerPageAddTable( int iArgc )
{
  m_poInterpreter->SetLastCall( "PageAddTable" );

  VMPage*      poPage  = NULL;
  TABLEHEADER* poTable = NULL;

  VerifyRunLineArguments( iArgc, 2 );
  VerifyElementType( 1, DT_REPORTPAGE );
  VerifyElementType( 0, DT_REPORTTABLE );

  poPage   = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_page;
  poTable  = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_pagetable;

  poPage->Table( poTable );

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], true );
  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerPageAddTable"
/*****************************************************************************/


/*****************************************************************************/
/*

     FUNCTION NAME:  VMVirtualOpSys::HandlerTableGetBottom

       DESCRIPTION:  determines the bottom coordinate of a report table

             INPUT:  iArgc - count of script params passed to this
            OUTPUT:  none

           RETURNS:  zero
*/
int VMVirtualOpSys::HandlerTableGetBottom( int iArgc )
{
  m_poInterpreter->SetLastCall( "TableGetBottom" );

  TABLEHEADER* poTable = NULL;
  double       dblResult;
  
  VerifyRunLineArguments( iArgc, 1 );
  VerifyElementType( 0, DT_REPORTTABLE );

  poTable   = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_pagetable;
  dblResult = poTable->EndRow;

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], dblResult );
  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerTableGetBottom"
/*****************************************************************************/


/*****************************************************************************/
/*

     FUNCTION NAME:  VMVirtualOpSys::HandlerTablePrintIntoCell

       DESCRIPTION:  places text into a specific cell in a report table

             INPUT:  iArgc - count of script params passed to this
            OUTPUT:  none

           RETURNS:  zero
*/
int VMVirtualOpSys::HandlerTablePrintIntoCell( int iArgc )
{
  m_poInterpreter->SetLastCall( "TablePrintIntoCell" );

  VMPage*      poPage  = NULL;
  TABLEHEADER* poTable = NULL;
  int          iRow;
  int          iCol;
  int          iSize;
  int          iFlags;
  char*        pchText;

  VerifyRunLineArguments( iArgc, 7 );
  VerifyElementType( 6, DT_REPORTPAGE );
  VerifyElementType( 5, DT_REPORTTABLE );
  VerifyElementType( 4, DT_INTEGER     );
  VerifyElementType( 3, DT_INTEGER     );
  VerifyElementType( 2, DT_INTEGER     );
  VerifyElementType( 1, DT_INTEGER     );
  VerifyElementType( 0, DT_STRING      );

  poPage   = m_poVirtualChip->m_psStackPointer[ 6 ].v.v_page;
  poTable  = m_poVirtualChip->m_psStackPointer[ 5 ].v.v_pagetable;
  iRow     = m_poVirtualChip->m_psStackPointer[ 4 ].v.v_integer;
  iCol     = m_poVirtualChip->m_psStackPointer[ 3 ].v.v_integer;
  iSize    = m_poVirtualChip->m_psStackPointer[ 2 ].v.v_integer;
  iFlags   = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_integer;
  pchText  = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_string->str_data;

  poPage->Print( poTable, iRow, iCol, iSize, iFlags, pchText );

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], true );
  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerTablePrintIntoCell"
/*****************************************************************************/


/*****************************************************************************/
/*

     FUNCTION NAME:  VMVirtualOpSys::HandlerDBOpen

       DESCRIPTION:  opens a connection to a dbms

             INPUT:  iArgc - count of arguments passed to function
            OUTPUT:  none

           RETURNS:  zero
*/
int VMVirtualOpSys::HandlerDBOpen( int iArgc )
{
  m_poInterpreter->SetLastCall( "DBOpen" );

  VerifyRunLineArguments( iArgc, 5 );
  VerifyElementType( 4, DT_ODBC   );
  VerifyElementType( 3, DT_STRING );
  VerifyElementType( 2, DT_STRING );
  VerifyElementType( 1, DT_STRING );
  VerifyElementType( 0, DT_STRING );

  VMODBC* poDB   = m_poVirtualChip->m_psStackPointer[ 4 ].v.v_odbc;
  char*   pchDSN = m_poVirtualChip->m_psStackPointer[ 3 ].v.v_string->str_data;
  char*   pchUID = m_poVirtualChip->m_psStackPointer[ 2 ].v.v_string->str_data;
  char*   pchPWD = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_string->str_data;
  char*   pchDB  = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_string->str_data;

  char    achLogon[ 256 ];
  sprintf( achLogon, 
           "DSN=%s;UID=%s;PWD=%s;DB=%s;",
           pchDSN, pchUID, pchPWD, pchDB );

  bool bResult = poDB->OpenEx( achLogon, VMODBCConnection::noOdbcDialog );
  
  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], bResult );
  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerDBOpen"
/*****************************************************************************/


/*****************************************************************************/
/*

     FUNCTION NAME:  VMVirtualOpSys::HandlerDBClose

       DESCRIPTION:  closes a db connection

             INPUT:  iArgc - count of arguments passed to function
            OUTPUT:  none

           RETURNS:  zero
*/
int VMVirtualOpSys::HandlerDBClose( int iArgc )
{
  m_poInterpreter->SetLastCall( "DBClose" );

  VerifyRunLineArguments( iArgc, 1 );
  VerifyElementType( 0, DT_ODBC );

  VMODBC* poDB  = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_odbc;
  poDB->Close();

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], true );
  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerDBClose"
/*****************************************************************************/


/*****************************************************************************/
/*

     FUNCTION NAME:  VMVirtualOpSys::HandlerDBIsOpen

       DESCRIPTION:  

             INPUT:  iArgc - count of arguments passed to function
            OUTPUT:  none

           RETURNS:  zero
*/
int VMVirtualOpSys::HandlerDBIsOpen( int iArgc )
{
  m_poInterpreter->SetLastCall( "DBIsOpen" );

  VerifyRunLineArguments( iArgc, 1 );
  VerifyElementType( 0, DT_ODBC );

  VMODBC* poDB  = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_odbc;
  bool bResult = poDB->IsOpen();

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], bResult );
  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerDBIsOpen"
/*****************************************************************************/


/*****************************************************************************/
/*

     FUNCTION NAME:  VMVirtualOpSys::HandlerDBCanTransact

       DESCRIPTION:  determines if odbc driver can transact

             INPUT:  iArgc - count of arguments passed to function
            OUTPUT:  none

           RETURNS:  zero
*/
int VMVirtualOpSys::HandlerDBCanTransact( int iArgc )
{
  m_poInterpreter->SetLastCall( "DBCanTransact" );

  VerifyRunLineArguments( iArgc, 1 );
  VerifyElementType( 0, DT_ODBC );

  VMODBC* poDB  = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_odbc;
  bool bResult = poDB->CanTransact();

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], bResult );
  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerDBCanTransact"
/*****************************************************************************/


/*****************************************************************************/
/*

     FUNCTION NAME:  VMVirtualOpSys::HandlerDBSetLogonTimeOut

       DESCRIPTION:  sets the logon timeout for the odbc object

             INPUT:  iArgc - count of arguments passed to function
            OUTPUT:  none

           RETURNS:  zero
*/
int VMVirtualOpSys::HandlerDBSetLogonTimeOut( int iArgc )
{
  m_poInterpreter->SetLastCall( "DBSetLogonTimeOut" );

  VerifyRunLineArguments( iArgc, 2 );
  VerifyElementType( 1, DT_ODBC    );
  VerifyElementType( 0, DT_INTEGER );

  VMODBC* poDB     = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_odbc;
  long    lTimeOut = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_integer;

  poDB->SetLoginTimeout( lTimeOut );

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], true );
  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerDBSetLogonTimeOut"
/*****************************************************************************/


/*****************************************************************************/
/*

     FUNCTION NAME:  VMVirtualOpSys::HandlerDBSetQueryTimeOut

       DESCRIPTION:  sets the query timeout for the odbc object

             INPUT:  iArgc - count of arguments passed to function
            OUTPUT:  none

           RETURNS:  zero
*/
int VMVirtualOpSys::HandlerDBSetQueryTimeOut( int iArgc )
{
  m_poInterpreter->SetLastCall( "DBSetQueryTimeOut" );

  VerifyRunLineArguments( iArgc, 2 );
  VerifyElementType( 1, DT_ODBC    );
  VerifyElementType( 0, DT_INTEGER );

  VMODBC* poDB     = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_odbc;
  long    lTimeOut = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_integer;

  poDB->SetQueryTimeout( lTimeOut );

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], true );
  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerDBSetQueryTimeOut"
/*****************************************************************************/


/*****************************************************************************/
/*

     FUNCTION NAME:  VMVirtualOpSys::HandlerDBBeginTran

       DESCRIPTION:  begins a transaction context in the dbms

             INPUT:  iArgc - count of arguments passed to function
            OUTPUT:  none

           RETURNS:  zero
*/
int VMVirtualOpSys::HandlerDBBeginTran( int iArgc )
{
  m_poInterpreter->SetLastCall( "DBBeginTran" );

  VerifyRunLineArguments( iArgc, 1 );
  VerifyElementType( 0, DT_ODBC );

  VMODBC* poDB  = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_odbc;
  bool bResult = poDB->BeginTrans();

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], bResult );
  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerDBBeginTran"
/*****************************************************************************/


/*****************************************************************************/
/*

     FUNCTION NAME:  VMVirtualOpSys::HandlerDBCommitTran

       DESCRIPTION:  commits a transaction context to the dbms

             INPUT:  iArgc - count of arguments passed to function
            OUTPUT:  none

           RETURNS:  zero
*/
int VMVirtualOpSys::HandlerDBCommitTran( int iArgc )
{
  m_poInterpreter->SetLastCall( "DBCommitTran" );

  VerifyRunLineArguments( iArgc, 1 );
  VerifyElementType( 0, DT_ODBC );

  VMODBC* poDB  = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_odbc;
  bool bResult = poDB->CommitTrans();

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], bResult );
  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerDBCommitTran"
/*****************************************************************************/


/*****************************************************************************/
/*

     FUNCTION NAME:  VMVirtualOpSys::HandlerDBRollbackTran

       DESCRIPTION:  rollsback a transaction context in the dbms

             INPUT:  iArgc - count of arguments passed to function
            OUTPUT:  none

           RETURNS:  zero
*/
int VMVirtualOpSys::HandlerDBRollbackTran( int iArgc )
{
  m_poInterpreter->SetLastCall( "DBRollbackTran" );

  VerifyRunLineArguments( iArgc, 1 );
  VerifyElementType( 0, DT_ODBC );

  VMODBC* poDB  = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_odbc;
  bool bResult = poDB->Rollback();

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], bResult );
  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerDBRollbackTran"
/*****************************************************************************/


/*****************************************************************************/
/*

     FUNCTION NAME:  VMVirtualOpSys::HandlerDBExecQuery

       DESCRIPTION:  issues a query to the dbms

             INPUT:  iArgc - count of arguments passed to function
            OUTPUT:  none

           RETURNS:  zero
*/
int VMVirtualOpSys::HandlerDBExecQuery( int iArgc )
{
  m_poInterpreter->SetLastCall( "DBExecQuery" );

  VerifyRunLineArguments( iArgc, 2 );
  VerifyElementType( 1, DT_ODBC   );
  VerifyElementType( 0, DT_STRING );

  VMODBC* poDB   = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_odbc;
  char* pchQuery = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_string->str_data;

  bool bResult = poDB->ExecuteQuery( pchQuery );

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], bResult );
  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerDBExecQuery"
/*****************************************************************************/


/*****************************************************************************/
/*

     FUNCTION NAME:  VMVirtualOpSys::HandlerDBIsEmptySet

       DESCRIPTION:  determines if query produced empty result set

             INPUT:  iArgc - count of arguments passed to function
            OUTPUT:  none

           RETURNS:  zero
*/
int VMVirtualOpSys::HandlerDBIsEmptySet( int iArgc )
{
  m_poInterpreter->SetLastCall( "DBIsEmptySet" );

  VerifyRunLineArguments( iArgc, 1 );
  VerifyElementType( 0, DT_ODBC );

  VMODBC* poDB  = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_odbc;
  bool bResult = poDB->IsEmptySet();

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], bResult );
  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerDBIsEmptySet"
/*****************************************************************************/


/*****************************************************************************/
/*

     FUNCTION NAME:  VMVirtualOpSys::HandlerDBIsEOF

       DESCRIPTION:  determines if result set is exhausted (EOF)

             INPUT:  iArgc - count of arguments passed to function
            OUTPUT:  none

           RETURNS:  zero
*/
int VMVirtualOpSys::HandlerDBIsEOF( int iArgc )
{
  m_poInterpreter->SetLastCall( "DBIsEOF" );

  VerifyRunLineArguments( iArgc, 1 );
  VerifyElementType( 0, DT_ODBC );

  VMODBC* poDB  = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_odbc;
  bool bResult = poDB->IsEOF();

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], bResult );
  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerDBIsEOF"
/*****************************************************************************/


/*****************************************************************************/
/*

     FUNCTION NAME:  VMVirtualOpSys::HandlerDBIsBOF

       DESCRIPTION:  determines if result set is at begining (BOF)

             INPUT:  iArgc - count of arguments passed to function
            OUTPUT:  none

           RETURNS:  zero
*/
int VMVirtualOpSys::HandlerDBIsBOF( int iArgc )
{
  m_poInterpreter->SetLastCall( "DBIsBOF" );

  VerifyRunLineArguments( iArgc, 1 );
  VerifyElementType( 0, DT_ODBC );

  VMODBC* poDB  = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_odbc;
  bool bResult = poDB->IsBOF();

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], bResult );
  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerDBIsBOF"
/*****************************************************************************/


/*****************************************************************************/
/*

     FUNCTION NAME:  VMVirtualOpSys::HandlerDBMoveNext

       DESCRIPTION:  moves to the next row in the result set

             INPUT:  iArgc - count of arguments passed to function
            OUTPUT:  none

           RETURNS:  zero
*/
int VMVirtualOpSys::HandlerDBMoveNext( int iArgc )
{
  m_poInterpreter->SetLastCall( "DBMoveNext" );

  VerifyRunLineArguments( iArgc, 1 );
  VerifyElementType( 0, DT_ODBC );

  VMODBC* poDB  = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_odbc;
  bool bResult = poDB->MoveNext();

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], bResult );
  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerDBMoveNext"
/*****************************************************************************/


/*****************************************************************************/
/*

     FUNCTION NAME:  VMVirtualOpSys::HandlerDBMovePrev

       DESCRIPTION:  moves to the previous row in the result set

             INPUT:  iArgc - count of arguments passed to function
            OUTPUT:  none

           RETURNS:  zero
*/
int VMVirtualOpSys::HandlerDBMovePrev( int iArgc )
{
  m_poInterpreter->SetLastCall( "DBMovePrev" );

  VerifyRunLineArguments( iArgc, 1 );
  VerifyElementType( 0, DT_ODBC );

  VMODBC* poDB  = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_odbc;
  bool bResult = poDB->MovePrev();

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], bResult );
  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerDBMovePrev"
/*****************************************************************************/


/*****************************************************************************/
/*

     FUNCTION NAME:  VMVirtualOpSys::HandlerDBMoveToStart

       DESCRIPTION:  moves to the first row in the result set

             INPUT:  iArgc - count of arguments passed to function
            OUTPUT:  none

           RETURNS:  zero
*/
int VMVirtualOpSys::HandlerDBMoveToStart( int iArgc )
{
  m_poInterpreter->SetLastCall( "DBMoveToStart" );

  VerifyRunLineArguments( iArgc, 1 );
  VerifyElementType( 0, DT_ODBC );

  VMODBC* poDB  = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_odbc;
  bool bResult = poDB->MoveToStart();

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], bResult );
  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerDBMoveToStart"
/*****************************************************************************/


/*****************************************************************************/
/*

     FUNCTION NAME:  VMVirtualOpSys::HandlerDBMoveToEnd

       DESCRIPTION:  moves to the last row in the result set

             INPUT:  iArgc - count of arguments passed to function
            OUTPUT:  none

           RETURNS:  zero
*/
int VMVirtualOpSys::HandlerDBMoveToEnd( int iArgc )
{
  m_poInterpreter->SetLastCall( "DBMoveToEnd" );

  VerifyRunLineArguments( iArgc, 1 );
  VerifyElementType( 0, DT_ODBC );

  VMODBC* poDB  = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_odbc;
  bool bResult = poDB->MoveToEnd();

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], bResult );
  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerDBMoveToEnd"
/*****************************************************************************/


/*****************************************************************************/
/*

     FUNCTION NAME:  VMVirtualOpSys::HandlerDBMoveAheadBy

       DESCRIPTION:  moves the cursor ahead by the given amount

             INPUT:  iArgc - count of arguments passed to function
            OUTPUT:  none

           RETURNS:  zero
*/
int VMVirtualOpSys::HandlerDBMoveAheadBy( int iArgc )
{
  m_poInterpreter->SetLastCall( "DBMoveAheadBy" );

  VerifyRunLineArguments( iArgc, 2 );
  VerifyElementType( 1, DT_ODBC    );
  VerifyElementType( 0, DT_INTEGER );

  VMODBC* poDB   = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_odbc;
  long    lMoveBy = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_integer;

  bool bResult = poDB->MoveForward( lMoveBy );

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], bResult );
  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerDBMoveAheadBy"
/*****************************************************************************/


/*****************************************************************************/
/*

     FUNCTION NAME:  VMVirtualOpSys::HandlerDBMoveBackBy

       DESCRIPTION:  moves the cursor backward by the given amount

             INPUT:  iArgc - count of arguments passed to function
            OUTPUT:  none

           RETURNS:  zero
*/
int VMVirtualOpSys::HandlerDBMoveBackBy( int iArgc )
{
  m_poInterpreter->SetLastCall( "DBMoveBackBy" );

  VerifyRunLineArguments( iArgc, 2 );
  VerifyElementType( 1, DT_ODBC    );
  VerifyElementType( 0, DT_INTEGER );

  VMODBC* poDB   = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_odbc;
  long    lMoveBy = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_integer;

  bool bResult = poDB->MoveBackward( lMoveBy );

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], bResult );
  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerDBMoveBackBy"
/*****************************************************************************/


/*****************************************************************************/
/*

     FUNCTION NAME:  VMVirtualOpSys::HandlerDBMoveFromStartBy

       DESCRIPTION:  moves the cursor 'n' away from the start of the record set

             INPUT:  iArgc - count of arguments passed to function
            OUTPUT:  none

           RETURNS:  zero
*/
int VMVirtualOpSys::HandlerDBMoveFromStartBy( int iArgc )
{
  m_poInterpreter->SetLastCall( "DBMoveFromStartBy" );

  VerifyRunLineArguments( iArgc, 2 );
  VerifyElementType( 1, DT_ODBC    );
  VerifyElementType( 0, DT_INTEGER );

  VMODBC* poDB   = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_odbc;
  long    lMoveBy = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_integer;

  bool bResult = poDB->MoveToIndexFromStart( lMoveBy );

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], bResult );
  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerDBMoveFromStartBy"
/*****************************************************************************/


/*****************************************************************************/
/*

     FUNCTION NAME:  VMVirtualOpSys::HandlerDBMoveFromEndBy

       DESCRIPTION:  moves the cursor 'n' away from the end of the record set

             INPUT:  iArgc - count of arguments passed to function
            OUTPUT:  none

           RETURNS:  zero
*/
int VMVirtualOpSys::HandlerDBMoveFromEndBy( int iArgc )
{
  m_poInterpreter->SetLastCall( "DBMoveFromEndBy" );

  VerifyRunLineArguments( iArgc, 2 );
  VerifyElementType( 1, DT_ODBC    );
  VerifyElementType( 0, DT_INTEGER );

  VMODBC* poDB    = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_odbc;
  long    lMoveBy = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_integer;

  bool bResult = poDB->MoveToIndexFromEnd( lMoveBy );

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], bResult );
  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerDBMoveFromEndBy"
/*****************************************************************************/


/*****************************************************************************/
/*

     FUNCTION NAME:  VMVirtualOpSys::HandlerDBGetFieldByIndex

       DESCRIPTION:  returns the odbc column data by index. nil is returned
                     on an invalid index value. sql data is converted to
                     one of the intrinsic vm data types

             INPUT:  iArgc - count of arguments passed to function
            OUTPUT:  none

           RETURNS:  zero
*/
int VMVirtualOpSys::HandlerDBGetFieldByIndex( int iArgc )
{
  m_poInterpreter->SetLastCall( "DBGetFieldByIndex" );

  VerifyRunLineArguments( iArgc, 2 );
  VerifyElementType( 1, DT_ODBC    );
  VerifyElementType( 0, DT_INTEGER );

  VMODBC*      poDB   = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_odbc;
  unsigned int lIndex = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_integer;

  COLUMN_INFO_BY_INDEX* poColumns;

  poColumns = poDB->GetColumnsByIndex();

  if ( poColumns->size() < lIndex )
  {
    m_poVirtualChip->m_psStackPointer[ iArgc ].ResetValue( true );
    set_nil( &m_poVirtualChip->m_psStackPointer[ iArgc ] );
  }
  else
  {
    VMColumnInfo*             poColumn = NULL;
    int                       iMax     = poColumns->size();
    COLUMN_INFO_BY_INDEX_ITER oIter    = poColumns->begin();

    for ( int iLoop = 0; iLoop < iMax; iLoop++ )
    {
      if ( iLoop == lIndex )
      {
        poColumn = *oIter;
        break;
      }
      oIter++;
    }

    if ( NULL != poColumn )
    {
      switch ( poColumn->m_iSqlDataType )
      {
        // character family
        //
        case SQL_CHAR:
        case SQL_VARCHAR:
        case SQL_LONGVARCHAR:
        case SQL_WCHAR:
        case SQL_WVARCHAR:
        case SQL_WLONGVARCHAR:
        //
        // interval types are stored as string
        //
        case SQL_INTERVAL_DAY:
        case SQL_INTERVAL_DAY_TO_MINUTE:
        case SQL_INTERVAL_HOUR:
        case SQL_INTERVAL_DAY_TO_SECOND:
        case SQL_INTERVAL_MINUTE:
        case SQL_INTERVAL_HOUR_TO_MINUTE:
        case SQL_INTERVAL_SECOND:
        case SQL_INTERVAL_HOUR_TO_SECOND:
        case SQL_INTERVAL_DAY_TO_HOUR:
        case SQL_INTERVAL_MINUTE_TO_SECOND:
        {
          VMString* poData  = (VMString*)poColumn->m_pvData;
          char*     pchData = poData->Buffer();
          int       iLength = strlen( pchData ) + 1;

          m_poVirtualChip->m_psStackPointer[ iArgc ].ResetValue( true );

          vmstring* pchReturn = AllocateNewString( iLength + 2, true );
          strcpy( pchReturn->str_data, pchData );
          SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], pchReturn );          
        }
        break;

        // Integer family
        //
        case SQL_BIT:
        {
          BOOL* pBool = (BOOL*)poColumn->m_pvData;
          m_poVirtualChip->m_psStackPointer[ iArgc ].ResetValue( true );
          SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], (bool)*pBool );          

        }
        break;

        case SQL_TINYINT:
        {
          unsigned char* pchValue = (unsigned char*)poColumn->m_pvData;
          m_poVirtualChip->m_psStackPointer[ iArgc ].ResetValue( true );
          SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], (long)*pchValue );          
        }
        break;

        case SQL_SMALLINT:
        {
          int* piValue = (int*)poColumn->m_pvData;
          m_poVirtualChip->m_psStackPointer[ iArgc ].ResetValue( true );
          SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], (long)*piValue );          
        }
	     break;

        case SQL_INTEGER:
        {
          long* plValue = (long*)poColumn->m_pvData;
          m_poVirtualChip->m_psStackPointer[ iArgc ].ResetValue( true );
          SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], *plValue );          
        }
        break;

        case SQL_DECIMAL:
        case SQL_DOUBLE:
        case SQL_BIGINT:
        {
          double* pdblValue = (double*)poColumn->m_pvData;
          m_poVirtualChip->m_psStackPointer[ iArgc ].ResetValue( true );
          SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], *pdblValue );          
        }
        break;
  
        // Floating-point type family and Fixed-point exact numerics.  
        //
        //    case SQL_DECIMAL:
        case SQL_REAL:
        case SQL_FLOAT:
        {
          float* pfValue = (float*)poColumn->m_pvData;
          m_poVirtualChip->m_psStackPointer[ iArgc ].ResetValue( true );
          SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], (double)*pfValue );          
        }
        break;

        case SQL_NUMERIC:
        {
          SQL_NUMERIC_STRUCT* pxValue = (SQL_NUMERIC_STRUCT*)poColumn->m_pvData;

          // Convert the little endian mode data into numeric data.
          //
          long val    = 0;
          long value  = 0;
          int  i      = 1;
          int  last   = 1;
          int  current = 1;
          int  a       = 0;
          int  b       = 0;

          for ( i = 0; i <= 15; i++ )
          {
            current = (int) pxValue->val[ i ];
            a = current % 16; //Obtain LSD
            b = current / 16; //Obtain MSD
				
            value += last * a;	
            last   = last * 16;	
            value += last * b;
            last   = last * 16;	
          }

          // The returned value in the above code is scaled
          // to the value specified in the scale field of 
          // the numeric structure. For example 25.212 would
          // be returned as 25212. The scale in this case 
          // is 3 hence the integer value needs to be divided by 1000.
          //
          int divisor = 1;
          if ( pxValue->scale > 0 )
          {
	         for ( i = 0; i < pxValue->scale; i++ )	
            {
              divisor = divisor * 10;
            }
          }
          double dblValue = (double) value /(double)divisor;

          // Examine the sign value returned in the sign field 
          // for the numeric structure.
          // NOTE: The ODBC 3.0 spec required drivers to return
          // the sign as 1 for positive numbers and 2 for 
          // negative number. This was changed in the
          // ODBC 3.5 spec to return 0 for negative instead of 2.
          //
          int sign;
          if ( !pxValue->sign )
          {
            sign = -1;
          }
          else
          {
            sign = 1;
          }
	       dblValue *= sign;

          m_poVirtualChip->m_psStackPointer[ iArgc ].ResetValue( true );
          SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], dblValue );          
        }
        break;

        case SQL_BINARY:
        case SQL_VARBINARY:
        case SQL_LONGVARBINARY:
        {
          // copy construct the byte data so that if the column
          // data is destroyed, the vm copy is still good
          //
          VMByteArray* poData = (VMByteArray*)poColumn->m_pvData;
          VMByteArray* poByteArray = new VMByteArray( *poData );

          m_poVirtualChip->m_psStackPointer[ iArgc ].ResetValue( true );
          set_bytearray( &m_poVirtualChip->m_psStackPointer[ iArgc ], poByteArray ); 
        }
        break;

        // Date/Time family
        //
        case SQL_TIMESTAMP:
        case SQL_DATE:
        {
          SQL_TIMESTAMP_STRUCT* pxDateTime = (SQL_TIMESTAMP_STRUCT*)poColumn->m_pvData;
          SYSTEMTIME            xDateTime;

          xDateTime.wYear   = pxDateTime->year;
          xDateTime.wMonth  = pxDateTime->month;
          xDateTime.wDay    = pxDateTime->day;
          xDateTime.wHour   = pxDateTime->hour;
          xDateTime.wMinute = pxDateTime->minute;
          xDateTime.wSecond = pxDateTime->second;
          xDateTime.wMilliseconds = static_cast< WORD >( pxDateTime->fraction ); // 2b|!2b==?

          m_poVirtualChip->m_psStackPointer[ iArgc ].ResetValue( true );
          SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], xDateTime ); 
        }
        break;

        case SQL_TIME:
        {
          SQL_TIME_STRUCT* pxTime = (SQL_TIME_STRUCT*)poColumn->m_pvData;

          SYSTEMTIME            xDateTime;
          
          GetLocalTime( &xDateTime );
          xDateTime.wHour   = pxTime->hour;
          xDateTime.wMinute = pxTime->minute;
          xDateTime.wSecond = pxTime->second;

          m_poVirtualChip->m_psStackPointer[ iArgc ].ResetValue( true );
          SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], xDateTime ); 
        }
        break;

        case SQL_GUID:
        {
          SQLGUID* pxGuid =(SQLGUID*)poColumn->m_pvData;
          VMString oText;
     
          oText.Format( "{%8.8X-%4.4X-%4.4X-%8.8X}",
                         pxGuid->Data1,
                         pxGuid->Data2,
                         pxGuid->Data3,
                         pxGuid->Data4 );

          char* pchData = oText.Buffer();
          int   iLength = strlen( pchData ) + 1;

          m_poVirtualChip->m_psStackPointer[ iArgc ].ResetValue( true );

          vmstring* pchReturn = AllocateNewString( iLength + 2, true );
          strcpy( pchReturn->str_data, pchData );
          SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], pchReturn );          
        }
        break;

        default:
        {
          m_poVirtualChip->m_psStackPointer[ iArgc ].ResetValue( true );
          set_nil( &m_poVirtualChip->m_psStackPointer[ iArgc ] );
        }
        break;
      }
    }
    else
    {
      // column was not found...this should never happen
      // but coded up 'just in case'
      //
      m_poVirtualChip->m_psStackPointer[ iArgc ].ResetValue( true );
      set_nil( &m_poVirtualChip->m_psStackPointer[ iArgc ] );
    }
  }
  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerDBGetFieldByIndex"
/*****************************************************************************/


/*****************************************************************************/
/*

     FUNCTION NAME:  VMVirtualOpSys::HandlerDBGetFieldByName

       DESCRIPTION:  returns the odbc column data by name. nil is returned
                     on an invalid name value. sql data is converted to
                     one of the intrinsic vm data types

             INPUT:  iArgc - count of arguments passed to function
            OUTPUT:  none

           RETURNS:  zero
*/
int VMVirtualOpSys::HandlerDBGetFieldByName( int iArgc )
{
  m_poInterpreter->SetLastCall( "DBGetFieldByName" );

  VerifyRunLineArguments( iArgc, 2 );
  VerifyElementType( 1, DT_ODBC    );
  VerifyElementType( 0, DT_STRING  );

  VMODBC* poDB  = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_odbc;
  char* pchName = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_string->str_data;

  COLUMN_INFO_BY_NAME* poColumns;

  poColumns = poDB->GetColumnsByName();

  COLUMN_INFO_BY_NAME_ITER oIter = poColumns->find( pchName );

  if ( oIter == poColumns->end() )
  {
    m_poVirtualChip->m_psStackPointer[ iArgc ].ResetValue( true );
    set_nil( &m_poVirtualChip->m_psStackPointer[ iArgc ] );
  }
  else
  {
    VMColumnInfo*  poColumn = (*oIter).second;

    switch ( poColumn->m_iSqlDataType )
    {
      // character family
      //
      case SQL_CHAR:
      case SQL_VARCHAR:
      case SQL_LONGVARCHAR:
      case SQL_WCHAR:
      case SQL_WVARCHAR:
      case SQL_WLONGVARCHAR:
      //
      // interval types are stored as string
      //
      case SQL_INTERVAL_DAY:
      case SQL_INTERVAL_DAY_TO_MINUTE:
      case SQL_INTERVAL_HOUR:
      case SQL_INTERVAL_DAY_TO_SECOND:
      case SQL_INTERVAL_MINUTE:
      case SQL_INTERVAL_HOUR_TO_MINUTE:
      case SQL_INTERVAL_SECOND:
      case SQL_INTERVAL_HOUR_TO_SECOND:
      case SQL_INTERVAL_DAY_TO_HOUR:
      case SQL_INTERVAL_MINUTE_TO_SECOND:
      {
        VMString* poData  = (VMString*)poColumn->m_pvData;
        char*     pchData = poData->Buffer();
        int       iLength = strlen( pchData ) + 1;

        m_poVirtualChip->m_psStackPointer[ iArgc ].ResetValue( true );

        vmstring* pchReturn = AllocateNewString( iLength + 2, true );
        strcpy( pchReturn->str_data, pchData );
        SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], pchReturn );          
      }
      break;

      // Integer family
      //
      case SQL_BIT:
      {
        BOOL* pBool = (BOOL*)poColumn->m_pvData;
        m_poVirtualChip->m_psStackPointer[ iArgc ].ResetValue( true );
        SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], (bool)*pBool );          
      }
      break;

      case SQL_TINYINT:
      {
        unsigned char* pchValue = (unsigned char*)poColumn->m_pvData;
        m_poVirtualChip->m_psStackPointer[ iArgc ].ResetValue( true );
        SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], (long)*pchValue );          
      }
      break;

      case SQL_SMALLINT:
      {
        int* piValue = (int*)poColumn->m_pvData;
        m_poVirtualChip->m_psStackPointer[ iArgc ].ResetValue( true );
        SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], (long)*piValue );          
      }
      break;

      case SQL_INTEGER:
      {
        long* plValue = (long*)poColumn->m_pvData;
        m_poVirtualChip->m_psStackPointer[ iArgc ].ResetValue( true );
        SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], *plValue );          
      }
      break;

      case SQL_DECIMAL:
      case SQL_DOUBLE:
      case SQL_BIGINT:
      {
        double* pdblValue = (double*)poColumn->m_pvData;
        m_poVirtualChip->m_psStackPointer[ iArgc ].ResetValue( true );
        SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], *pdblValue );          
      }
      break;
  
      // Floating-point type family and Fixed-point exact numerics.  
      //
      //    case SQL_DECIMAL:
      case SQL_REAL:
      case SQL_FLOAT:
      {
        float* pfValue = (float*)poColumn->m_pvData;
        m_poVirtualChip->m_psStackPointer[ iArgc ].ResetValue( true );
        SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], (double)*pfValue );          
      }
      break;

      case SQL_NUMERIC:
      {
        SQL_NUMERIC_STRUCT* pxValue = (SQL_NUMERIC_STRUCT*)poColumn->m_pvData;

        // Convert the little endian mode data into numeric data.
        //
        long val    = 0;
        long value  = 0;
        int  i      = 1;
        int  last   = 1;
        int  current = 1;
        int  a       = 0;
        int  b       = 0;

        for ( i = 0; i <= 15; i++ )
        {
          current = (int) pxValue->val[ i ];
          a = current % 16; //Obtain LSD
          b = current / 16; //Obtain MSD
				
          value += last * a;	
          last   = last * 16;	
          value += last * b;
          last   = last * 16;	
        }

        // The returned value in the above code is scaled
        // to the value specified in the scale field of 
        // the numeric structure. For example 25.212 would
        // be returned as 25212. The scale in this case 
        // is 3 hence the integer value needs to be divided by 1000.
        //
        int divisor = 1;
        if ( pxValue->scale > 0 )
        {
          for ( i = 0; i < pxValue->scale; i++ )	
          {
            divisor = divisor * 10;
          }
        }
        double dblValue = (double) value /(double)divisor;

        // Examine the sign value returned in the sign field 
        // for the numeric structure.
        // NOTE: The ODBC 3.0 spec required drivers to return
        // the sign as 1 for positive numbers and 2 for 
        // negative number. This was changed in the
        // ODBC 3.5 spec to return 0 for negative instead of 2.
        //
        int sign;
        if ( !pxValue->sign )
        {
          sign = -1;
        }
        else
        {
          sign = 1;
        }
        dblValue *= sign;

        m_poVirtualChip->m_psStackPointer[ iArgc ].ResetValue( true );
        SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], dblValue );          
      }
      break;

      case SQL_BINARY:
      case SQL_VARBINARY:
      case SQL_LONGVARBINARY:
      {
        // copy construct the byte data so that if the column
        // data is destroyed, the vm copy is still good
        //
        VMByteArray* poData = (VMByteArray*)poColumn->m_pvData;
        VMByteArray* poByteArray = new VMByteArray( *poData );

        m_poVirtualChip->m_psStackPointer[ iArgc ].ResetValue( true );
        set_bytearray( &m_poVirtualChip->m_psStackPointer[ iArgc ], poByteArray ); 
      }
      break;

      // Date/Time family
      //
      case SQL_TIMESTAMP:
      case SQL_DATE:
      {
        SQL_TIMESTAMP_STRUCT* pxDateTime = (SQL_TIMESTAMP_STRUCT*)poColumn->m_pvData;
        SYSTEMTIME            xDateTime;

        xDateTime.wYear   = pxDateTime->year;
        xDateTime.wMonth  = pxDateTime->month;
        xDateTime.wDay    = pxDateTime->day;
        xDateTime.wHour   = pxDateTime->hour;
        xDateTime.wMinute = pxDateTime->minute;
        xDateTime.wSecond = pxDateTime->second;
        xDateTime.wMilliseconds = static_cast< WORD >( pxDateTime->fraction ); // 2b|!2b==?

        m_poVirtualChip->m_psStackPointer[ iArgc ].ResetValue( true );
        SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], xDateTime ); 
      }
      break;

      case SQL_TIME:
      {
        SQL_TIME_STRUCT* pxTime = (SQL_TIME_STRUCT*)poColumn->m_pvData;

        SYSTEMTIME            xDateTime;
          
        GetLocalTime( &xDateTime );
        xDateTime.wHour   = pxTime->hour;
        xDateTime.wMinute = pxTime->minute;
        xDateTime.wSecond = pxTime->second;

        m_poVirtualChip->m_psStackPointer[ iArgc ].ResetValue( true );
        SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], xDateTime ); 
      }
      break;

      case SQL_GUID:
      {
        SQLGUID* pxGuid =(SQLGUID*)poColumn->m_pvData;
        VMString oText;
     
        oText.Format( "{%8.8X-%4.4X-%4.4X-%8.8X}",
                       pxGuid->Data1,
                       pxGuid->Data2,
                       pxGuid->Data3,
                       pxGuid->Data4 );

        char* pchData = oText.Buffer();
        int   iLength = strlen( pchData ) + 1;

        m_poVirtualChip->m_psStackPointer[ iArgc ].ResetValue( true );

        vmstring* pchReturn = AllocateNewString( iLength + 2, true );
        strcpy( pchReturn->str_data, pchData );
        SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], pchReturn );          
      }
      break;

      default:
      {
        m_poVirtualChip->m_psStackPointer[ iArgc ].ResetValue( true );
        set_nil( &m_poVirtualChip->m_psStackPointer[ iArgc ] );
      }
      break;
    }
  }
  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerDBGetFieldByName"
/*****************************************************************************/


/*****************************************************************************/
/*

     FUNCTION NAME:  VMVirtualOpSys::HandlerDBGetColumnCount

       DESCRIPTION:  returns the number of columns on the record set

             INPUT:  iArgc - count of arguments passed to function
            OUTPUT:  none

           RETURNS:  zero
*/
int VMVirtualOpSys::HandlerDBGetColumnCount( int iArgc )
{
  m_poInterpreter->SetLastCall( "DBGetColumnCount" );

  VerifyRunLineArguments( iArgc, 1 );
  VerifyElementType( 0, DT_ODBC );

  VMODBC* poDB = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_odbc;
  long lResult = poDB->GetColumnsByIndex()->size();

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], lResult );
  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerDBGetColumnCount"
/*****************************************************************************/


/*****************************************************************************/
/*

     FUNCTION NAME:  VMVirtualOpSys::HandlerDBFetchRow

       DESCRIPTION:  pulls the next row of data from the drivers into local
                     buffers

             INPUT:  iArgc - count of arguments passed to function
            OUTPUT:  none

           RETURNS:  zero
*/
int VMVirtualOpSys::HandlerDBFetchRow( int iArgc )
{
  m_poInterpreter->SetLastCall( "DBFetchRow" );

  VerifyRunLineArguments( iArgc, 1 );
  VerifyElementType( 0, DT_ODBC );

  VMODBC* poDB = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_odbc;
  poDB->ExchangeData( NULL );

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], true );
  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerDBFetchRow"
/*****************************************************************************/


/*****************************************************************************/
/*

     FUNCTION NAME:  VMVirtualOpSys::HandlerDBGetServerName

       DESCRIPTION:  pulls the next row of data from the drivers into local
                     buffers

             INPUT:  iArgc - count of arguments passed to function
            OUTPUT:  none

           RETURNS:  zero
*/
int VMVirtualOpSys::HandlerDBGetServerName( int iArgc )
{
  m_poInterpreter->SetLastCall( "DBGetServerName" );

  VerifyRunLineArguments( iArgc, 1 );
  VerifyElementType( 0, DT_ODBC );

  VMODBC* poDB     = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_odbc;

  char achServerName[ 256 ];

  poDB->GetDbmsHostName( achServerName, 255 );

  vmstring* pxResult = AllocateNewString( strlen( achServerName ) + 1, true );
  strcpy( pxResult->str_data, achServerName );

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], pxResult );
  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerDBGetServerName"
/*****************************************************************************/


/*****************************************************************************/
/*

     FUNCTION NAME:  VMVirtualOpSys::HandlerCreateOdbcDsn

       DESCRIPTION:  pulls the next row of data from the drivers into local
                     buffers

             INPUT:  iArgc - count of arguments passed to function
            OUTPUT:  none

           RETURNS:  zero
*/
int VMVirtualOpSys::HandlerCreateOdbcDsn( int iArgc )
{
  m_poInterpreter->SetLastCall( "SysCreateOdbcDsn" );


  bool bResult = false;

  VMOdbcDsnInstaller oDsnMaker;

  VerifyElementType( iArgc - 1, DT_STRING );

  const char* pchDbType = m_poVirtualChip->m_psStackPointer[ iArgc - 1 ].v.v_string->str_data;

  if ( 0 == strcmp( pchDbType, "MsSqlServer" ) )
  {
    VerifyRunLineArguments( iArgc, 5 );
    VerifyElementType( 3, DT_STRING );
    VerifyElementType( 2, DT_STRING );
    VerifyElementType( 1, DT_STRING );
    VerifyElementType( 0, DT_STRING );

    char* pchDsnName     = m_poVirtualChip->m_psStackPointer[ 3 ].v.v_string->str_data;
    char* pchDescription = m_poVirtualChip->m_psStackPointer[ 2 ].v.v_string->str_data;
    char* pchServerName  = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_string->str_data;
    char* pchUseDb       = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_string->str_data;
  
    bResult = oDsnMaker.CreateDSNForSQLServer( pchDsnName, 
                                               pchDescription, 
                                               pchServerName, 
                                               pchUseDb );
  }
  else
  {
    bResult = false;
  }

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], bResult );
  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerCreateOdbcDsn"
/*****************************************************************************/


/*****************************************************************************/
/*

     FUNCTION NAME:  VMVirtualOpSys::HandlerDBGetDatabaseName

       DESCRIPTION:  pulls the next row of data from the drivers into local
                     buffers

             INPUT:  iArgc - count of arguments passed to function
            OUTPUT:  none

           RETURNS:  zero
*/
int VMVirtualOpSys::HandlerDBGetDatabaseName( int iArgc )
{
  m_poInterpreter->SetLastCall( "DBGetDatabaseName" );

  VerifyRunLineArguments( iArgc, 1 );
  VerifyElementType( 0, DT_ODBC );

  VMODBC* poDB     = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_odbc;
  VMString oDBName = poDB->GetDatabaseName();

  vmstring* pxResult = AllocateNewString( oDBName.Length() + 1, true );
  strcpy( pxResult->str_data, oDBName.Buffer() );

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], pxResult );
  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerDBGetDatabaseName"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerIsProcessRunning

       DESCRIPTION:  determines if the process-name passed into this is running
                     in the OS

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerIsProcessRunning( int iArgc )
{
  m_poInterpreter->SetLastCall( "IsProcessRunning" );

  char* pchToFind;
  int   iReturn;
  VMString oHost( _T(".") );
  VMString oFind;
  VMString oMsg;

  VerifyRunLineArguments( iArgc, 1 );
  VerifyElementType( 0, DT_STRING );

  pchToFind = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_string->str_data;

  VMProcessProbe  oProbe;
  oFind   = pchToFind;
  iReturn = oProbe.IsProcessRunning( oHost, oFind, oMsg );

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], iReturn );

  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerIsProcessRunning"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  "HandlerAddVariable / HandlerAddSubExpression 
                      HandlerSetEquation / HandlerSolve"

       DESCRIPTION:  Calculation Object Managment Methods

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerAddVariable( int iArgc )
{
  m_poInterpreter->SetLastCall( "CalcAddVariable" );

  char  achNumVal[ 50 ];
  char* pchVarName     = NULL;
  char* pchVarStrValue = NULL;

  VerifyRunLineArguments( iArgc, 3 );
  VerifyElementType( 2, DT_CALCULATOR );
  VerifyElementType( 1, DT_STRING );

  assert( ( DT_INTEGER == m_poVirtualChip->m_psStackPointer[ 0 ].v_type )
       || ( DT_STRING  == m_poVirtualChip->m_psStackPointer[ 0 ].v_type )
       || ( DT_DOUBLE  == m_poVirtualChip->m_psStackPointer[ 0 ].v_type ) );

  VMCalculator* poCalculator = get_calculator( &m_poVirtualChip->m_psStackPointer[2] );

  pchVarName = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_string->str_data;

  switch( m_poVirtualChip->m_psStackPointer[ 0 ].v_type )
  {
    case DT_INTEGER:
      pchVarStrValue = achNumVal;
      ltoa( m_poVirtualChip->m_psStackPointer[ 0 ].v.v_integer, 
            achNumVal, 
            10 );
    break;

    case DT_STRING:
      pchVarStrValue = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_string->str_data;
    break;

    case DT_DOUBLE:
      pchVarStrValue = achNumVal;
      ltoa( static_cast<long>( m_poVirtualChip->m_psStackPointer[ 0 ].v.v_double ), 
            achNumVal, 
            10 );
    break;

    default:
    break;
  }

  poCalculator->AddVariable( pchVarName, pchVarStrValue );
  
  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], 1 );
  m_poVirtualChip->m_psStackPointer += iArgc;

  return 0;
}
int VMVirtualOpSys::HandlerAddSubExpression( int iArgc )
{
  m_poInterpreter->SetLastCall( "CalcAddExpression" );

  char* pchVarName     = NULL;
  char* pchVarStrValue = NULL;

  VerifyRunLineArguments( iArgc, 3 );
  VerifyElementType( 2, DT_CALCULATOR );
  VerifyElementType( 1, DT_STRING );
  VerifyElementType( 0, DT_STRING );

  VMCalculator* poCalculator = get_calculator( &m_poVirtualChip->m_psStackPointer[ 2 ] );

  pchVarName     = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_string->str_data;
  pchVarStrValue = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_string->str_data;

  poCalculator->AddSubExpression( pchVarName, pchVarStrValue );
  
  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], 1 );
  m_poVirtualChip->m_psStackPointer += iArgc;

  return 0;
}
int VMVirtualOpSys::HandlerSetEquation( int iArgc )
{
  m_poInterpreter->SetLastCall( "CalcSetEquation" );

  char* pchVarStrValue = NULL;

  VerifyRunLineArguments( iArgc, 2 );
  VerifyElementType( 1, DT_CALCULATOR );
  VerifyElementType( 0, DT_STRING );

  VMCalculator* poCalculator = get_calculator( &m_poVirtualChip->m_psStackPointer[1] );

  pchVarStrValue =  m_poVirtualChip->m_psStackPointer[0].v.v_string->str_data;

  poCalculator->SetEquation( pchVarStrValue );
  
  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], 1 );
  m_poVirtualChip->m_psStackPointer += iArgc;

  return 0;
}
int VMVirtualOpSys::HandlerSolve( int iArgc )
{
  m_poInterpreter->SetLastCall( "CalcSolve" );

  VerifyRunLineArguments( iArgc, 1 );
  VerifyElementType( 0, DT_CALCULATOR );

  VMCalculator* poCalculator = get_calculator( &m_poVirtualChip->m_psStackPointer[ 0 ] );

  double dResult;
  poCalculator->GetResult( dResult );

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], dResult );

  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "HandlerAddVariable / HandlerAddSubExpression 
                    HandlerSetEquation / HandlerSolve"
/*****************************************************************************/


// mjs: comment these form input functions
#ifndef NOT_USING_XML_FORMS

int VMVirtualOpSys::HandlerCreateForm( int iArgc )
{
  m_poInterpreter->SetLastCall( "CreateForm" );

  char* pchFormName = NULL;
  char* pchFormText = NULL;
  bool  bNeedDelete = false;
  bool  bSuccess    = true;
  bool  bGoodText   = true;

  VerifyRunLineArguments( iArgc, 2 );
  VerifyElementType( 1, DT_STRING );

  if ( m_poVirtualChip->m_psStackPointer[ 0 ].v_type == DT_STRING )
  {
    pchFormText = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_string->str_data;
    bGoodText   = true;
  }
  else
  if ( m_poVirtualChip->m_psStackPointer[ 0 ].v_type == DT_NTFILEHANDLE )
  {
    DWORD  dwFileSize;
    DWORD  dwBytesRead;
    HANDLE hFile = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_handle;

    if ( 0xFFFFFFFF != ( dwFileSize = GetFileSize( hFile, NULL ) ) )
    {
      bNeedDelete = true;
      pchFormText = new char[ dwFileSize + 1 ];
      memset( pchFormText, 0, dwFileSize + 1 );

      if ( ReadFile( hFile, 
                     pchFormText,
                     dwFileSize,
                     &dwBytesRead,
                     NULL ) )
      {
        if ( dwBytesRead != dwFileSize )
        {
          bGoodText = false;
          bSuccess  = false;
        }
      }
    } 
    else 
    {
      bGoodText = false;
      bSuccess  = false;
    } 
  }
  else
  {
    VerifyElementType( 0, DT_STRING );
  }

  if ( bGoodText )
  {
    pchFormName = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_string->str_data;

    FORMS_BY_NAME_ITER oIter = m_oLoadedForms.find( std::string( pchFormName ) );
    if ( oIter != m_oLoadedForms.end() )
    {
      delete (*oIter).second;
      m_oLoadedForms.erase( oIter );
    }

    CXMLFormFacade* poNewForm = new CXMLFormFacade( NULL );
    poNewForm->SetServerContext( m_poServerContext );
    poNewForm->SetVar( m_poServerContext->m_poScriptArguments );
    m_oLoadedForms.insert( FORMS_BY_NAME::value_type( std::string( pchFormName ), poNewForm ) );

    poNewForm->ParseForm( std::string( pchFormText ) );

    if ( bNeedDelete )
    {
      delete [] pchFormText;
    }
  }

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], bSuccess );
  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}

int VMVirtualOpSys::HandlerRunForm( int iArgc )
{
  m_poInterpreter->SetLastCall( "RunForm" );

  char* pchFormName = NULL;
  int   iResult     = IDCANCEL;

  VerifyRunLineArguments( iArgc, 1 );
  VerifyElementType( 0, DT_STRING );

  pchFormName = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_string->str_data;

  FORMS_BY_NAME_ITER oIter = m_oLoadedForms.find( std::string( pchFormName ) );


  if ( oIter != m_oLoadedForms.end() )
  {
    CXMLFormFacade* poForm = (*oIter).second;

    if ( NULL != m_poInterpreter && NULL != m_poInterpreter->m_poDebugger )
    {
      iResult = ::SendMessage( m_poInterpreter->m_poDebugger->m_hWndVars, 
                               WM_SCRIPT_RUN_SCREEN, 
                               (WPARAM)this, 
                               (LPARAM)poForm ); 
    }
    else
    if ( NULL != m_hWndCommandTarget )
    {
      iResult = ::SendMessage( m_hWndCommandTarget, 
                               WM_SCRIPT_NOTIFY_MSG,  
                               (WPARAM)WM_SCRIPT_RUN_SCREEN, 
                               (LPARAM)poForm ); 
    }
    else
    {
      m_poXmlFormFacade = poForm;
      iResult = poForm->RunForm( true, true );
    }
  }

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], iResult );
  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}

int VMVirtualOpSys::HandlerDestroyForm( int iArgc )
{
  m_poInterpreter->SetLastCall( "DestroyForm" );

  char* pchFormName = NULL;
  bool  bResult     = true;

  VerifyRunLineArguments( iArgc, 1 );
  VerifyElementType( 0, DT_STRING );

  pchFormName = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_string->str_data;

  FORMS_BY_NAME_ITER oIter = m_oLoadedForms.find( std::string( pchFormName ) );
  if ( oIter != m_oLoadedForms.end() )
  {
    CXMLFormFacade* poForm = (*oIter).second;
    if ( m_poXmlFormFacade == poForm )
    {
      m_poXmlFormFacade = NULL;
    }
    delete poForm;
    m_oLoadedForms.erase( oIter );
  }

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], bResult );
  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}


/*****************************************************************************/
/*

     FUNCTION NAME:  VMVirtualOpSys::HandlerFormGetCtrlValueAsString

       DESCRIPTION:  returns the string value of a given control from the 
                     contained control environment

             INPUT:  iArgc - count of arguments passed to this
            OUTPUT:  none

           RETURNS:  0
*/
int VMVirtualOpSys::HandlerFormGetCtrlValueAsString( int iArgc )
{
  m_poInterpreter->SetLastCall( "FormGetCtrlValueAsString" );

  char achValue[ 256 ];
  memset( achValue, 0, 256 );

  if ( iArgc == 1 )
  {
    VerifyElementType( 0, DT_STRING );
    const char* pchCtrl = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_string->str_data;
    m_poXmlFormFacade->GetFormFieldValue( pchCtrl, achValue );
  }
  else
  if ( iArgc == 2 )
  {
    VerifyElementType( 1, DT_STRING );
    VerifyElementType( 0, DT_STRING );

    char* pchFormName = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_string->str_data;

    FORMS_BY_NAME_ITER oIter = m_oLoadedForms.find( std::string( pchFormName ) );
    if ( oIter != m_oLoadedForms.end() )
    {
      CXMLFormFacade* poForm = (*oIter).second;
      const char*     pchCtrl = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_string->str_data;
      poForm->GetFormFieldValue( pchCtrl, achValue );
    }
  }
  else
  {
    VerifyRunLineArguments( iArgc, 1 );
  }
  
  vmstring* pxResult = AllocateNewString( strlen( achValue ) + 2, true );
  pxResult->str_size = strlen( achValue ) + 2;
  strcpy( pxResult->str_data, achValue );
  
  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], pxResult );
  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerFormGetCtrlValueAsString"
/*****************************************************************************/


/*****************************************************************************/
/*

     FUNCTION NAME:  VMVirtualOpSys::HandlerFormSetCtrlValueAsString

       DESCRIPTION:  sets the string value of a given control from the 
                     contained control environment

             INPUT:  iArgc - count of arguments passed to this
            OUTPUT:  none

           RETURNS:  0
*/
int VMVirtualOpSys::HandlerFormSetCtrlValueAsString( int iArgc )
{
  m_poInterpreter->SetLastCall( "FormSetCtrlValueAsString" );

  if ( iArgc == 2 )
  {
    VerifyElementType( 1, DT_STRING );
    VerifyElementType( 0, DT_STRING );

    const char* pchCtrl  = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_string->str_data;
    const char* pchValue = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_string->str_data;

    m_poXmlFormFacade->SetFormFieldValue( pchCtrl, pchValue );
  }
  else
  if ( iArgc == 3 )
  {
    VerifyElementType( 2, DT_STRING );
    VerifyElementType( 1, DT_STRING );
    VerifyElementType( 0, DT_STRING );

    char* pchFormName = m_poVirtualChip->m_psStackPointer[ 2 ].v.v_string->str_data;

    FORMS_BY_NAME_ITER oIter = m_oLoadedForms.find( std::string( pchFormName ) );
    if ( oIter != m_oLoadedForms.end() )
    {
      CXMLFormFacade* poForm = (*oIter).second;
      const char* pchCtrl  = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_string->str_data;
      const char* pchValue = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_string->str_data;

      poForm->SetFormFieldValue( pchCtrl, pchValue );
    }
  }
  else
  {
    VerifyRunLineArguments( iArgc, 2 );
  }

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], true );
  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerFormSetCtrlValueAsString"
/*****************************************************************************/
/*****************************************************************************/
/*

     FUNCTION NAME:  VMVirtualOpSys::HandlerFormGetCtrlValueAsInteger

       DESCRIPTION:  returns the integer value of a given control from the 
                     contained control environment

             INPUT:  iArgc - count of arguments passed to this
            OUTPUT:  none

           RETURNS:  0
*/
int VMVirtualOpSys::HandlerFormGetCtrlValueAsInteger( int iArgc )
{
  m_poInterpreter->SetLastCall( "FormGetCtrlValueAsInteger" );

  char achValue[ 256 ];
  long lResult = 0;
  
  if ( iArgc == 1 )
  {
    VerifyElementType( 0, DT_STRING );

    const char* pchCtrl = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_string->str_data;

    if ( m_poXmlFormFacade->GetFormFieldValue( pchCtrl, achValue ) )
    {
      lResult = atoi( achValue );
    }
  }
  else
  if ( iArgc == 2 )
  {
    VerifyElementType( 1, DT_STRING );
    VerifyElementType( 0, DT_STRING );

    char* pchFormName = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_string->str_data;

    FORMS_BY_NAME_ITER oIter = m_oLoadedForms.find( std::string( pchFormName ) );
    if ( oIter != m_oLoadedForms.end() )
    {
      CXMLFormFacade* poForm = (*oIter).second;
      const char*     pchCtrl = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_string->str_data;

      if ( poForm->GetFormFieldValue( pchCtrl, achValue ) )
      {
        lResult = atoi( achValue );
      }
    }
  }
  else
  {
    VerifyRunLineArguments( iArgc, 1 );
  }

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], lResult );
  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerFormGetCtrlValueAsInteger"
/*****************************************************************************/


/*****************************************************************************/
/*

     FUNCTION NAME:  VMVirtualOpSys::HandlerFormSetCtrlValueAsInteger

       DESCRIPTION:  sets the value of a given control from the 
                     contained control environment

             INPUT:  iArgc - count of arguments passed to this
            OUTPUT:  none

           RETURNS:  0
*/
int VMVirtualOpSys::HandlerFormSetCtrlValueAsInteger( int iArgc )
{
  m_poInterpreter->SetLastCall( "FormSetCtrlValueAsInteger" );

  char achValue[ 50 ];
  memset( achValue, 0, 50 );

  if ( iArgc == 2 )
  {
    VerifyElementType( 1, DT_STRING );
    VerifyElementType( 0, DT_INTEGER );

    const char* pchCtrl = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_string->str_data;
    int         iValue  = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_integer;

    itoa( iValue, achValue, 10 );
 
    m_poXmlFormFacade->SetFormFieldValue( pchCtrl, achValue );
  }
  else
  if ( iArgc == 3 )
  {
    VerifyElementType( 2, DT_STRING );
    VerifyElementType( 1, DT_STRING );
    VerifyElementType( 0, DT_INTEGER );

    char* pchFormName = m_poVirtualChip->m_psStackPointer[ 2 ].v.v_string->str_data;

    FORMS_BY_NAME_ITER oIter = m_oLoadedForms.find( std::string( pchFormName ) );
    if ( oIter != m_oLoadedForms.end() )
    {
      CXMLFormFacade* poForm = (*oIter).second;

      const char* pchCtrl = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_string->str_data;
      int         iValue  = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_integer;

      itoa( iValue, achValue, 10 );

      poForm->SetFormFieldValue( pchCtrl, achValue );
    }
  }
  else
  {
    VerifyRunLineArguments( iArgc, 2 );
  }

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], true );
  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerFormSetCtrlValueAsInteger"
/*****************************************************************************/


/*****************************************************************************/
/*

     FUNCTION NAME:  VMVirtualOpSys::HandlerFormGetCtrlValueAsDouble

       DESCRIPTION:  returns the double value of a given control from the 
                     contained control environment

             INPUT:  iArgc - count of arguments passed to this
            OUTPUT:  none

           RETURNS:  0
*/
int VMVirtualOpSys::HandlerFormGetCtrlValueAsDouble( int iArgc )
{
  m_poInterpreter->SetLastCall( "FormGetCtrlValueAsDouble" );

  double dblResult = 0;
  char achValue[ 256 ];
  memset( achValue, 0, 256 );

  if ( iArgc == 1 )
  {
    VerifyElementType( 0, DT_STRING );

    const char* pchCtrl = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_string->str_data;

    if ( m_poXmlFormFacade->GetFormFieldValue( pchCtrl, achValue ) )
    {
      dblResult = atof( achValue );
    }
  }
  else
  if ( iArgc == 2 )
  {
    VerifyElementType( 1, DT_STRING );
    VerifyElementType( 0, DT_STRING );

    char* pchFormName = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_string->str_data;

    FORMS_BY_NAME_ITER oIter = m_oLoadedForms.find( std::string( pchFormName ) );
    if ( oIter != m_oLoadedForms.end() )
    {
      CXMLFormFacade* poForm = (*oIter).second;
      const char*     pchCtrl = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_string->str_data;

      if ( poForm->GetFormFieldValue( pchCtrl, achValue ) )
      {
        dblResult = atof( achValue );
      }
    }
  }
  else
  {
    VerifyRunLineArguments( iArgc, 1 );
  }

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], dblResult );
  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerFormGetCtrlValueAsDouble"
/*****************************************************************************/


/*****************************************************************************/
/*

     FUNCTION NAME:  VMVirtualOpSys::HandlerFormSetCtrlValueAsDouble

       DESCRIPTION:  gets the double value of a given control from the 
                     contained control environment

             INPUT:  iArgc - count of arguments passed to this
            OUTPUT:  none

           RETURNS:  0
*/
int VMVirtualOpSys::HandlerFormSetCtrlValueAsDouble( int iArgc )
{
  m_poInterpreter->SetLastCall( "FormSetCtrlValueAsDouble" );

  char*           pchCtrl  = NULL;
  double          dblValue = 0.0;
  int             iDepth   = 2;
  CXMLFormFacade* poForm   = NULL;

  if ( iArgc == 3 )
  {
    VerifyElementType( 2, DT_STRING );
    VerifyElementType( 1, DT_DOUBLE );
    VerifyElementType( 0, DT_INTEGER );

    poForm   = m_poXmlFormFacade;
    pchCtrl  = m_poVirtualChip->m_psStackPointer[ 2 ].v.v_string->str_data;
    dblValue = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_double;
    iDepth   = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_integer;
  }
  else
  if ( iArgc == 4 )
  {
    VerifyElementType( 3, DT_STRING );
    VerifyElementType( 2, DT_STRING );
    VerifyElementType( 1, DT_DOUBLE );
    VerifyElementType( 0, DT_INTEGER );

    char* pchFormName = m_poVirtualChip->m_psStackPointer[ 3 ].v.v_string->str_data;

    FORMS_BY_NAME_ITER oIter = m_oLoadedForms.find( std::string( pchFormName ) );
    if ( oIter != m_oLoadedForms.end() )
    {
      poForm   = (*oIter).second;
      pchCtrl  = m_poVirtualChip->m_psStackPointer[ 2 ].v.v_string->str_data;
      dblValue = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_double;
      iDepth   = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_integer;
    }
  }
  else
  {
    VerifyRunLineArguments( iArgc, 3 );
  }

  char    achValue[ 60 ];
  int     iDecimalPointAt;
  int     iSign;
  char*   pchBuffer;
  double  source =  dblValue;
  int     iPrecision = 10;

  // from docs: Only digits are stored in the string. 
  //
  // The position of the decimal point and the sign of value
  // can be obtained from dec and sign after the call.
  //
  // The dec parameter points to an integer value giving the
  // position of the decimal point with respect to the 
  // beginning of the string. A 0 or negative integer value
  // indicates that the decimal point lies to the left of the
  // first digit. 
  //
  // The sign parameter points to an integer that indicates 
  // the sign of the converted number. If the integer value
  // is 0, the number is positive. Otherwise, the number 
  // is negative.
  //
  pchBuffer = _ecvt( source, 
                     iPrecision, 
                     &iDecimalPointAt, 
                     &iSign );
  int  iIndex = 0;
  memset( achValue, 0, 60 );
  if ( iSign != 0 )
  {
    // if negative, put in the sign
    //
    achValue[ 0 ] = '-';
    iIndex++; 
  }
 
  if ( iDecimalPointAt <= 0 )
  {
    // if decimal is first, then go this way
    //
    achValue[ iIndex ] = '.';
    iIndex++; 
    strcat( achValue, pchBuffer );
  }
  else
  {
    // decimal point embedded somewhere in the number
    // copy the whole part of the number first
    //
    for ( int iLoop = 0; iLoop < iDecimalPointAt; iLoop++ )
    {
      achValue[ iIndex ] = pchBuffer[ iLoop ];
      iIndex++;
    }
    // slap in the decimal point, then copy the rest 
    // of the buffer
    //
    achValue[ iIndex ] = '.';
    strcat( achValue, pchBuffer + iDecimalPointAt );
  }

  // trim off trailing zeroes
  //
  int iTop = strlen( achValue );
  while ( ( iTop > 1 ) 
       && ( achValue[ iTop ] == '0' )
       && ( achValue[ iTop - 1 ] == '0' ) )
  {
    achValue[ iTop ] = 0;
    iTop--;
  } 

  char* pchDecimalAt = strchr( achValue, '.' );
  if ( pchDecimalAt != NULL )
  {
    pchDecimalAt += iDepth + 1;
    *pchDecimalAt = 0;
  }

  poForm->SetFormFieldValue( pchCtrl, achValue );

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], true );
  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerFormSetCtrlValueAsDouble"
/*****************************************************************************/


/*****************************************************************************/
/*

     FUNCTION NAME:  VMVirtualOpSys::HandlerFormCtrlValidateFail

       DESCRIPTION:  pops up the validation tool tip for the given control

             INPUT:  iArgc - count of arguments passed to this
            OUTPUT:  none

           RETURNS:  0
*/
int VMVirtualOpSys::HandlerFormCtrlValidateFail( int iArgc )
{
  m_poInterpreter->SetLastCall( "FormCtrlValidateFail" );

  VerifyRunLineArguments( iArgc, 2 );
  VerifyElementType( 1, DT_STRING );
  VerifyElementType( 0, DT_STRING );

  const char* pchCtrl  = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_string->str_data;
  const char* pchValue = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_string->str_data;

  m_poXmlFormFacade->ShowControlToolTip( pchCtrl, pchValue );
  m_poXmlFormFacade->SetDataInvalid( true );

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], true );
  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerFormCtrlValidateFail"
/*****************************************************************************/


/*****************************************************************************/
/*

     FUNCTION NAME:  VMVirtualOpSys::HandlerFormClearAllFields

       DESCRIPTION:  clears all the data entry fields on a form

             INPUT:  iArgc - count of arguments passed to this
            OUTPUT:  none

           RETURNS:  0
*/
int VMVirtualOpSys::HandlerFormClearAllFields( int iArgc )
{
  m_poInterpreter->SetLastCall( "FormClearAllFields" );

  VerifyRunLineArguments( iArgc, 0 );

  m_poXmlFormFacade->ClearAllFieldValues();

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], true );
  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerFormClearAllFields"
/*****************************************************************************/


/*****************************************************************************/
/*

     FUNCTION NAME:  VMVirtualOpSys::HandlerFormClearFieldByName

       DESCRIPTION:  clears the given control

             INPUT:  iArgc - count of arguments passed to this
            OUTPUT:  none

           RETURNS:  0
*/
int VMVirtualOpSys::HandlerFormClearFieldByName( int iArgc )
{
  m_poInterpreter->SetLastCall( "FormClearFieldByName" );

  VerifyRunLineArguments( iArgc, 1 );
  VerifyElementType( 0, DT_STRING );

  const char* pchCtrl  = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_string->str_data;

  m_poXmlFormFacade->ClearFormFieldValueByName( pchCtrl );

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], true );
  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerFormClearFieldByName"
/*****************************************************************************/


/*****************************************************************************/
/*

     FUNCTION NAME:  VMVirtualOpSys::HandlerShowHideFormGroup

       DESCRIPTION:  shows/hides the given form section

             INPUT:  iArgc - count of arguments passed to this
            OUTPUT:  none

           RETURNS:  0
*/
int VMVirtualOpSys::HandlerShowHideFormGroup( int iArgc )
{
  m_poInterpreter->SetLastCall( "FormShowHideFormGroup" );

  VerifyRunLineArguments( iArgc, 2 );
  VerifyElementType( 1, DT_STRING );
  VerifyElementType( 0, DT_BYTE   );

  const char* pchSection  = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_string->str_data;
  bool        bShowHide   = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_byte;

  m_poXmlFormFacade->ShowHideFormGroup( bShowHide, pchSection );

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], true );
  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerShowHideFormGroup"
/*****************************************************************************/


/*****************************************************************************/
/*

     FUNCTION NAME:  VMVirtualOpSys::HandlerEnableDisableFormGroup

       DESCRIPTION:  enables/disables the given form section

             INPUT:  iArgc - count of arguments passed to this
            OUTPUT:  none

           RETURNS:  0
*/
int VMVirtualOpSys::HandlerEnableDisableFormGroup( int iArgc )
{
  m_poInterpreter->SetLastCall( "FormEnableDisableFormGroup" );

  VerifyRunLineArguments( iArgc, 2 );
  VerifyElementType( 1, DT_STRING );
  VerifyElementType( 0, DT_BYTE   );

  const char* pchSection  = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_string->str_data;
  bool        bShowHide   = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_byte;

  m_poXmlFormFacade->EnableDisableFormGroup( bShowHide, pchSection );

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], true );
  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerEnableDisableFormGroup"
/*****************************************************************************/


/*****************************************************************************/
/*

     FUNCTION NAME:  VMVirtualOpSys::HandlerShowHideSubForm

       DESCRIPTION:  shows/hides the given sub-form section

             INPUT:  iArgc - count of arguments passed to this
            OUTPUT:  none

           RETURNS:  0
*/
int VMVirtualOpSys::HandlerShowHideSubForm( int iArgc )
{
  m_poInterpreter->SetLastCall( "FormShowHideSubForm" );

  VerifyRunLineArguments( iArgc, 2 );
  VerifyElementType( 1, DT_STRING );
  VerifyElementType( 0, DT_BYTE   );

  const char* pchSubForm  = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_string->str_data;
  bool        bShowHide   = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_byte;

  m_poXmlFormFacade->ShowHideSubForm( bShowHide, pchSubForm );

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], true );
  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerShowHideSubForm"
/*****************************************************************************/


/*****************************************************************************/
/*

     FUNCTION NAME:  VMVirtualOpSys::HandlerShowHideControl

       DESCRIPTION:  shows/hides an individual control

             INPUT:  iArgc - count of arguments passed to this
            OUTPUT:  none

           RETURNS:  0
*/
int VMVirtualOpSys::HandlerShowHideControl( int iArgc )
{
  m_poInterpreter->SetLastCall( "FormShowHideControl" );

  VerifyRunLineArguments( iArgc, 2 );
  VerifyElementType( 1, DT_STRING );
  VerifyElementType( 0, DT_BYTE   );

  const char* pchControl  = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_string->str_data;
  bool        bShowHide   = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_byte;

  m_poXmlFormFacade->ShowHideControl( bShowHide, pchControl );

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], true );
  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerShowHideControl"
/*****************************************************************************/


/*****************************************************************************/
/*

     FUNCTION NAME:  VMVirtualOpSys::HandlerFormSetFocus

       DESCRIPTION:  enables/disables an individual control

             INPUT:  iArgc - count of arguments passed to this
            OUTPUT:  none

           RETURNS:  0
*/
int VMVirtualOpSys::HandlerFormSetFocus( int iArgc )
{
  m_poInterpreter->SetLastCall( "FormSetFocus" );

  VerifyRunLineArguments( iArgc, 1 );
  VerifyElementType( 0, DT_STRING );

  const char* pchControl  = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_string->str_data;

  m_poXmlFormFacade->SetFocusToControl( pchControl );

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], true );
  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerFormSetFocus"
/*****************************************************************************/


/*****************************************************************************/
/*

     FUNCTION NAME:  VMVirtualOpSys::HandlerEnableDisableControl

       DESCRIPTION:  enables/disables an individual control

             INPUT:  iArgc - count of arguments passed to this
            OUTPUT:  none

           RETURNS:  0
*/
int VMVirtualOpSys::HandlerEnableDisableControl( int iArgc )
{
  m_poInterpreter->SetLastCall( "FormEnableDisableControl" );

  VerifyRunLineArguments( iArgc, 2 );
  VerifyElementType( 1, DT_STRING );
  VerifyElementType( 0, DT_BYTE   );

  const char* pchControl  = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_string->str_data;
  bool        bShowHide   = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_byte;

  m_poXmlFormFacade->EnableDisableControl( bShowHide, pchControl );

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], true );
  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerEnableDisableControl"
/*****************************************************************************/


/*****************************************************************************/
/*

     FUNCTION NAME:  VMVirtualOpSys::HandlerIsFormGroupVisible

       DESCRIPTION:  returns visible status of form section

             INPUT:  iArgc - count of arguments passed to this
            OUTPUT:  none

           RETURNS:  0
*/
int VMVirtualOpSys::HandlerIsFormGroupVisible( int iArgc )
{
  m_poInterpreter->SetLastCall( "FormIsFormGroupVisible" );

  VerifyRunLineArguments( iArgc, 1 );
  VerifyElementType( 0, DT_STRING );

  const char* pchSection  = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_string->str_data;

  bool bResult = m_poXmlFormFacade->IsFormGroupVisible( pchSection );

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], bResult );
  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerIsFormGroupVisible"
/*****************************************************************************/


/*****************************************************************************/
/*

     FUNCTION NAME:  VMVirtualOpSys::HandlerIsFormGroupEnabled

       DESCRIPTION:  returns enabled status of form section

             INPUT:  iArgc - count of arguments passed to this
            OUTPUT:  none

           RETURNS:  0
*/
int VMVirtualOpSys::HandlerIsFormGroupEnabled( int iArgc )
{
  m_poInterpreter->SetLastCall( "FormIsFormGroupEnabled" );

  VerifyRunLineArguments( iArgc, 1 );
  VerifyElementType( 0, DT_STRING );

  const char* pchSection  = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_string->str_data;

  bool bResult = m_poXmlFormFacade->IsFormGroupEnabled( pchSection );

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], bResult );
  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerIsFormGroupEnabled"
/*****************************************************************************/


/*****************************************************************************/
/*

     FUNCTION NAME:  VMVirtualOpSys::HandlerIsSubFormVisible

       DESCRIPTION:  returns visible status of a sub-form

             INPUT:  iArgc - count of arguments passed to this
            OUTPUT:  none

           RETURNS:  0
*/
int VMVirtualOpSys::HandlerIsSubFormVisible( int iArgc )
{
  m_poInterpreter->SetLastCall( "FormIsSubFormVisible" );

  VerifyRunLineArguments( iArgc, 1 );
  VerifyElementType( 0, DT_STRING );

  const char* pchSubForm  = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_string->str_data;

  bool bResult = m_poXmlFormFacade->IsSubFormVisible( pchSubForm );

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], bResult );
  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerIsSubFormVisible"
/*****************************************************************************/


/*****************************************************************************/
/*

     FUNCTION NAME:  VMVirtualOpSys::HandlerIsControlVisible

       DESCRIPTION:  returns visible status of a control

             INPUT:  iArgc - count of arguments passed to this
            OUTPUT:  none

           RETURNS:  0
*/
int VMVirtualOpSys::HandlerIsControlVisible( int iArgc )
{
  m_poInterpreter->SetLastCall( "FormIsControlVisible" );

  VerifyRunLineArguments( iArgc, 1 );
  VerifyElementType( 0, DT_STRING );

  const char* pchControl  = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_string->str_data;

  bool bResult = m_poXmlFormFacade->IsControlVisible( pchControl );

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], bResult );
  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerIsControlVisible"
/*****************************************************************************/


/*****************************************************************************/
/*

     FUNCTION NAME:  VMVirtualOpSys::HandlerIsControlEnabled

       DESCRIPTION:  returns enabled status of a control

             INPUT:  iArgc - count of arguments passed to this
            OUTPUT:  none

           RETURNS:  0
*/
int VMVirtualOpSys::HandlerIsControlEnabled( int iArgc )
{
  m_poInterpreter->SetLastCall( "FormIsControlEnabled" );

  VerifyRunLineArguments( iArgc, 1 );
  VerifyElementType( 0, DT_STRING );

  const char* pchControl  = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_string->str_data;

  bool bResult = m_poXmlFormFacade->IsControlEnabled( pchControl );

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], bResult );
  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerIsControlEnabled"
/*****************************************************************************/


/*****************************************************************************/
/*

     FUNCTION NAME:  VMVirtualOpSys::HandlerIsFormButtonChecked

       DESCRIPTION:  returns check state of a form button

             INPUT:  iArgc - count of arguments passed to this
            OUTPUT:  none

           RETURNS:  0
*/
int VMVirtualOpSys::HandlerIsFormButtonChecked( int iArgc )
{
  m_poInterpreter->SetLastCall( "FormIsFormButtonChecked" );

  VerifyRunLineArguments( iArgc, 1 );
  VerifyElementType( 0, DT_STRING );

  const char* pchControl  = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_string->str_data;

  bool bResult = m_poXmlFormFacade->IsFormButtonChecked( pchControl );

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], bResult );
  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerIsFormButtonChecked"
/*****************************************************************************/


/*****************************************************************************/
/*

     FUNCTION NAME:  VMVirtualOpSys::HandlerSetFocusToControl

       DESCRIPTION:  sets focus to a specific control

             INPUT:  iArgc - count of arguments passed to this
            OUTPUT:  none

           RETURNS:  0
*/
int VMVirtualOpSys::HandlerSetFocusToControl( int iArgc )
{
  m_poInterpreter->SetLastCall( "FormSetFocusToControl" );

  VerifyRunLineArguments( iArgc, 1 );
  VerifyElementType( 0, DT_STRING );

  const char* pchControl  = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_string->str_data;

  m_poXmlFormFacade->SetFocusToControl( pchControl );

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], true );
  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerSetFocusToControl"
/*****************************************************************************/


/*****************************************************************************/
/*

     FUNCTION NAME:  VMVirtualOpSys::HandlerAddStringToComboBox

       DESCRIPTION:  adds string to a combo box

             INPUT:  iArgc - count of arguments passed to this
            OUTPUT:  none

           RETURNS:  0
*/
int VMVirtualOpSys::HandlerAddStringToComboBox( int iArgc )
{
  m_poInterpreter->SetLastCall( "FormAddStringToComboBox" );

  VerifyRunLineArguments( iArgc, 2 );
  VerifyElementType( 1, DT_STRING );
  VerifyElementType( 0, DT_STRING );

  const char* pchControl = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_string->str_data;
  const char* pchValue   = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_string->str_data;

  m_poXmlFormFacade->AddStringToComboBox( pchControl, pchValue );

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], true );
  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerAddStringToComboBox"
/*****************************************************************************/


/*****************************************************************************/
/*

     FUNCTION NAME:  VMVirtualOpSys::HandlerRemoveStringFromComboBox

       DESCRIPTION:  remove string from a combo box

             INPUT:  iArgc - count of arguments passed to this
            OUTPUT:  none

           RETURNS:  0
*/
int VMVirtualOpSys::HandlerRemoveStringFromComboBox( int iArgc )
{
  m_poInterpreter->SetLastCall( "FormRemoveStringFromComboBox" );

  VerifyRunLineArguments( iArgc, 2 );
  VerifyElementType( 1, DT_STRING );
  VerifyElementType( 0, DT_STRING );

  const char* pchControl = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_string->str_data;
  const char* pchValue   = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_string->str_data;

  m_poXmlFormFacade->RemoveStringFromComboBox( pchControl, pchValue );

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], true );
  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerRemoveStringFromComboBox"
/*****************************************************************************/


/*****************************************************************************/
/*

     FUNCTION NAME:  VMVirtualOpSys::HandlerAddStringToListBox

       DESCRIPTION:  adds string to a List box

             INPUT:  iArgc - count of arguments passed to this
            OUTPUT:  none

           RETURNS:  0
*/
int VMVirtualOpSys::HandlerAddStringToListBox( int iArgc )
{
  m_poInterpreter->SetLastCall( "FormAddStringToListBox" );

  VerifyRunLineArguments( iArgc, 2 );
  VerifyElementType( 1, DT_STRING );
  VerifyElementType( 0, DT_STRING );

  const char* pchControl = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_string->str_data;
  const char* pchValue   = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_string->str_data;

  m_poXmlFormFacade->AddStringToListBox( pchControl, pchValue );

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], true );
  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerAddStringToListBox"
/*****************************************************************************/


/*****************************************************************************/
/*

     FUNCTION NAME:  VMVirtualOpSys::HandlerRemoveStringFromListBox

       DESCRIPTION:  remove string from a List box

             INPUT:  iArgc - count of arguments passed to this
            OUTPUT:  none

           RETURNS:  0
*/
int VMVirtualOpSys::HandlerRemoveStringFromListBox( int iArgc )
{
  m_poInterpreter->SetLastCall( "FormRemoveStringFromListBox" );

  VerifyRunLineArguments( iArgc, 2 );
  VerifyElementType( 1, DT_STRING );
  VerifyElementType( 0, DT_STRING );

  const char* pchControl = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_string->str_data;
  const char* pchValue   = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_string->str_data;

  m_poXmlFormFacade->RemoveStringFromListBox( pchControl, pchValue );

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], true );
  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerRemoveStringFromListBox"
/*****************************************************************************/


/*****************************************************************************/
/*

     FUNCTION NAME:  VMVirtualOpSys::HandlerAddRecordToList

       DESCRIPTION:  add a string to a list view on the form

             INPUT:  iArgc - count of arguments passed to this
            OUTPUT:  none

           RETURNS:  0
*/
int VMVirtualOpSys::HandlerAddRecordToList( int iArgc )
{
  m_poInterpreter->SetLastCall( "FormAddRecordToList" );

  VerifyRunLineArguments( iArgc, 2 );
  VerifyElementType( 1, DT_STRING );
  VerifyElementType( 0, DT_STRING );

  // note pchValue is expected to be in format: field^field^field^field^|
  //
  const char* pchControl = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_string->str_data;
  const char* pchValue   = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_string->str_data;

  m_poXmlFormFacade->AddRecordsToList( pchControl, pchValue );

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], true );
  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerAddRecordToList"
/*****************************************************************************/


/*****************************************************************************/
/*

     FUNCTION NAME:  VMVirtualOpSys::HandlerRemoveRecordFromListByIndex

       DESCRIPTION:  removes a specified record from the list

             INPUT:  iArgc - count of arguments passed to this
            OUTPUT:  none

           RETURNS:  0
*/
int VMVirtualOpSys::HandlerRemoveRecordFromListByIndex( int iArgc )
{
  m_poInterpreter->SetLastCall( "FormAddRecordToList" );

  VerifyRunLineArguments( iArgc, 2 );
  VerifyElementType( 1, DT_STRING  );
  VerifyElementType( 0, DT_INTEGER );

  const char* pchControl = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_string->str_data;
  long        iIndex     = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_integer;

  m_poXmlFormFacade->RemoveRecordFromListByIndex( pchControl, iIndex );

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], true );
  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerRemoveRecordFromListByIndex"
/*****************************************************************************/


/*****************************************************************************/
/*

     FUNCTION NAME:  VMVirtualOpSys::HandlerRemoveAllStringsFromComboBox

       DESCRIPTION:  clears a combo box

             INPUT:  iArgc - count of arguments passed to this
            OUTPUT:  none

           RETURNS:  0
*/
int VMVirtualOpSys::HandlerRemoveAllStringsFromComboBox( int iArgc )
{
  m_poInterpreter->SetLastCall( "FormRemoveAllStringsFromComboBox" );

  VerifyRunLineArguments( iArgc, 1 );
  VerifyElementType( 0, DT_STRING );

  const char* pchControl  = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_string->str_data;

  m_poXmlFormFacade->RemoveAllStringsFromComboBox( pchControl );

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], true );
  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerRemoveAllStringsFromComboBox"
/*****************************************************************************/


/*****************************************************************************/
/*

     FUNCTION NAME:  VMVirtualOpSys::HandlerRemoveAllStringsFromListBox

       DESCRIPTION:  clears a list box

             INPUT:  iArgc - count of arguments passed to this
            OUTPUT:  none

           RETURNS:  0
*/
int VMVirtualOpSys::HandlerRemoveAllStringsFromListBox( int iArgc )
{
  m_poInterpreter->SetLastCall( "FormRemoveAllStringsFromListBox" );

  VerifyRunLineArguments( iArgc, 1 );
  VerifyElementType( 0, DT_STRING );

  const char* pchControl  = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_string->str_data;

  m_poXmlFormFacade->RemoveAllStringsFromListBox( pchControl );

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], true );
  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerRemoveAllStringsFromListBox"
/*****************************************************************************/


/*****************************************************************************/
/*

     FUNCTION NAME:  VMVirtualOpSys::HandlerFormCheckButton

       DESCRIPTION:  clears a list box

             INPUT:  iArgc - count of arguments passed to this
            OUTPUT:  none

           RETURNS:  0
*/
int VMVirtualOpSys::HandlerFormCheckButton( int iArgc )
{
  m_poInterpreter->SetLastCall( "FormRemoveAllStringsFromListBox" );

  VerifyRunLineArguments( iArgc, 2 );
  VerifyElementType( 1, DT_STRING );
  VerifyElementType( 0, DT_BYTE );

  const char* pchControl = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_string->str_data;
  bool        bChecked   = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_byte; 

  m_poXmlFormFacade->FormCheckButton( pchControl, bChecked );

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], true );
  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerFormCheckButton"
/*****************************************************************************/


/*****************************************************************************/
/*

     FUNCTION NAME:  VMVirtualOpSys::HandlerSetListBoxStrings

       DESCRIPTION:  sets the contents of a list box

             INPUT:  iArgc - count of arguments passed to this
            OUTPUT:  none

           RETURNS:  0
*/
int VMVirtualOpSys::HandlerSetListBoxStrings( int iArgc )
{
  m_poInterpreter->SetLastCall( "FormSetListBoxStrings" );

  VerifyRunLineArguments( iArgc, 2 );
  VerifyElementType( 1, DT_STRING );
  VerifyElementType( 0, DT_USERVECTOR );

  const char*      pchControl = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_string->str_data;
  VMDataVector*    poVector   = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_uservector;
  CTRL_STRING_LIST oToAdd;
  VMVariant*       poValue = NULL;
  int              iCount  = poVector->GetCount();
  
  for ( int iLoop = 0; iLoop < iCount; iLoop++ )
  {
    poVector->GetAtIndex( iLoop, *poValue );
    if ( poValue != NULL && poValue->v_type == DT_STRING )
    {
      oToAdd.push_back( std::string( poValue->v.v_string->str_data ) );
    }
  }

  m_poXmlFormFacade->SetListBoxStrings( pchControl, oToAdd );

  oToAdd.clear();

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], true );
  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerSetListBoxStrings"
/*****************************************************************************/


/*****************************************************************************/
/*

     FUNCTION NAME:  VMVirtualOpSys::HandlerSetComboBoxStrings

       DESCRIPTION:  sets the contents of a combo box

             INPUT:  iArgc - count of arguments passed to this
            OUTPUT:  none

           RETURNS:  0
*/
int VMVirtualOpSys::HandlerSetComboBoxStrings( int iArgc )
{
  m_poInterpreter->SetLastCall( "FormSetComboBoxStrings" );

  VerifyRunLineArguments( iArgc, 2 );
  VerifyElementType( 1, DT_STRING );
  VerifyElementType( 0, DT_USERVECTOR );

  const char*      pchControl = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_string->str_data;
  VMDataVector*    poVector   = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_uservector;
  CTRL_STRING_LIST oToAdd;
  VMVariant*       poValue = NULL;
  int              iCount  = poVector->GetCount();
  
  for ( int iLoop = 0; iLoop < iCount; iLoop++ )
  {
    poVector->GetAtIndex( iLoop, *poValue );
    if ( poValue != NULL && poValue->v_type == DT_STRING )
    {
      oToAdd.push_back( std::string( poValue->v.v_string->str_data ) );
    }
  }

  m_poXmlFormFacade->SetComboBoxStrings( pchControl, oToAdd );

  oToAdd.clear();

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], true );
  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerSetComboBoxStrings"
/*****************************************************************************/


/*****************************************************************************/
/*

     FUNCTION NAME:  VMVirtualOpSys::HandlerSetComboBoxCurSel

       DESCRIPTION:  sets the current selection of a combo box

             INPUT:  iArgc - count of arguments passed to this
            OUTPUT:  none

           RETURNS:  0
*/
int VMVirtualOpSys::HandlerSetComboBoxCurSel( int iArgc )
{
  m_poInterpreter->SetLastCall( "FormSetComboBoxCurSel" );

  VerifyRunLineArguments( iArgc, 2 );
  VerifyElementType( 1, DT_STRING );
  VerifyElementType( 0, DT_INTEGER );

  const char* pchControl = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_string->str_data;
  int         iIndex   = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_integer;
  
  m_poXmlFormFacade->SetComboBoxSelIndex( pchControl, iIndex );

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], true );
  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerSetComboBoxCurSel"
/*****************************************************************************/


/*****************************************************************************/
/*

     FUNCTION NAME:  VMVirtualOpSys::HandlerSetListBoxCurSel

       DESCRIPTION:  sets the current selection of a list box

             INPUT:  iArgc - count of arguments passed to this
            OUTPUT:  none

           RETURNS:  0
*/
int VMVirtualOpSys::HandlerSetListBoxCurSel( int iArgc )
{
  m_poInterpreter->SetLastCall( "FormSetListBoxCurSel" );

  VerifyRunLineArguments( iArgc, 2 );
  VerifyElementType( 1, DT_STRING );
  VerifyElementType( 0, DT_INTEGER );

  const char* pchControl = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_string->str_data;
  int         iIndex   = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_integer;
  
  m_poXmlFormFacade->SetListBoxSelIndex( pchControl, iIndex );

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], true );
  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerSetListBoxCurSel"
/*****************************************************************************/


/*****************************************************************************/
/*

     FUNCTION NAME:  VMVirtualOpSys::HandlerSetTabControlCurSel

       DESCRIPTION:  sets the current selection of a tab control

             INPUT:  iArgc - count of arguments passed to this
            OUTPUT:  none

           RETURNS:  0
*/
int VMVirtualOpSys::HandlerSetTabControlCurSel( int iArgc )
{
  m_poInterpreter->SetLastCall( "FormSetTabControlCurSel" );

  VerifyRunLineArguments( iArgc, 2 );
  VerifyElementType( 1, DT_STRING );
  VerifyElementType( 0, DT_INTEGER );

  const char* pchControl = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_string->str_data;
  int         iIndex   = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_integer;
  
  m_poXmlFormFacade->SelectTab( pchControl, iIndex );

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], true );
  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerSetTabControlCurSel"
/*****************************************************************************/
#endif


/*****************************************************************************/
/*

     FUNCTION NAME:  VMVirtualOpSys::HandlerIsStringNumeric

       DESCRIPTION:  evaluates the given string to determine if the string
                     'looks like a number' i.e., has only digits and decimal
                     point

             INPUT:  iArgc - count of arguments passed to this
            OUTPUT:  none

           RETURNS:  0
*/
int VMVirtualOpSys::HandlerIsStringNumeric( int iArgc )
{
  m_poInterpreter->SetLastCall( "IsStringNumeric" );

  VerifyRunLineArguments( iArgc, 1 );
  VerifyElementType( 0, DT_STRING );

  const char* pchToTest  = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_string->str_data;

  bool bIsNumeric = true;
  int  iTop       = strlen( pchToTest );
  for ( int iLoop = 0; iLoop < iTop; iLoop++ )
  {
    if ( !isdigit( pchToTest[ iLoop ] ) )
    {
      if ( '.' != pchToTest[ iLoop ] )
      {
        bIsNumeric = false;
        break;
      }
    }
  }
  
  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], bIsNumeric );
  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerIsStringNumeric"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerFileExists

       DESCRIPTION:  confirms that a file EXISTS 

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerFileExists( int iArgc )
{
  m_poInterpreter->SetLastCall( "FileExists" );

  int    iReturnCode;
  HANDLE hFile;

  VerifyRunLineArguments( iArgc, 1 );
  VerifyElementType( 0, DT_STRING );

  hFile = CreateFile( m_poVirtualChip->m_psStackPointer[ 0 ].v.v_string->str_data, 
                      GENERIC_READ,
                      FILE_SHARE_READ | FILE_SHARE_WRITE,
                      NULL,
                      OPEN_EXISTING,
                      FILE_ATTRIBUTE_NORMAL,
                      NULL );
  if ( INVALID_HANDLE_VALUE != hFile )
  {
    iReturnCode = 1;
  }
  else
  {
    iReturnCode = 0;
  }

  CloseHandle( hFile );

  // send back the return code
  //
  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], iReturnCode );

  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerFileExists"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerOpenFile

       DESCRIPTION:  Opens/Creates a file for use within a scripting session
                     This method maps to : OpenFile, CreateFile, OpenCreateFile

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerOpenFile( int iArgc )
{
  m_poInterpreter->SetLastCall( "OpenCreateFile" );

  HANDLE hFile;

  VerifyRunLineArguments( iArgc, 4 );
  VerifyElementType( 3, DT_STRING );
  VerifyElementType( 2, DT_INTEGER );
  VerifyElementType( 1, DT_INTEGER );
  VerifyElementType( 0, DT_INTEGER );

  long lWritable = m_poVirtualChip->m_psStackPointer[ 2 ].v.v_integer;
  long lShared   = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_integer;
  long lCreation = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_integer;

  DWORD dwFileAccessMode = GENERIC_READ;
  switch ( lWritable )
  {
    case 0:
    {
      dwFileAccessMode = GENERIC_READ;
    }
    break;

    case 1:
    {
      dwFileAccessMode = GENERIC_WRITE;
    }
    break;

    case 2:
    {
      dwFileAccessMode = GENERIC_READ | GENERIC_WRITE;
    }
    break;
  }

  DWORD dwShared = 0;
  switch ( lShared )
  {
    case 1:
    {
      dwShared = FILE_SHARE_READ;
    }
    break;

    case 2:
    {
      dwShared = FILE_SHARE_WRITE;
    }
    break;

    case 3:
    {
      dwShared = FILE_SHARE_READ | FILE_SHARE_WRITE;
    }
    break;
  }

  DWORD dwCreateMode = CREATE_NEW;
  switch ( lCreation )
  {
    case 0:
    {
      // Creates a new file. The function fails if the specified file already exists. 
      //
      dwCreateMode = CREATE_NEW;
    }
    break;

    case 1:
    {
      // Creates a new file. If the file exists, the function overwrites the file 
      // and clears the existing attributes. 
      //
      dwCreateMode = CREATE_ALWAYS;
    }
    break;

    case 2:
    {
      // Opens the file. The function fails if the file does not exist. 
      //
      dwCreateMode = OPEN_EXISTING;
    }
    break;

    case 3:
    {
      // Opens the file, if it exists. If the file does not exist, the 
      // function creates the file as if dwCreationDisposition were CREATE_NEW. 
      //
      dwCreateMode = OPEN_ALWAYS;
    }
    break;

    case 4:
    {
      // Opens the file. Once opened, the file is truncated so that its size is 
      // zero bytes. The calling process must open the file with at least 
      // GENERIC_WRITE access. The function fails if the file does not exist. 
      //
      dwCreateMode = TRUNCATE_EXISTING;
    }
    break;
  }

  hFile = CreateFile( m_poVirtualChip->m_psStackPointer[ 3 ].v.v_string->str_data, 
                      dwFileAccessMode,
                      dwShared,
                      NULL,
                      dwCreateMode,
                      FILE_ATTRIBUTE_NORMAL,
                      NULL );

  if ( INVALID_HANDLE_VALUE == hFile )
  {
    CloseHandle( hFile );
    hFile = 0L;
  }

  // send back the return code
  //
  set_ntfilehandle( &m_poVirtualChip->m_psStackPointer[iArgc], hFile );
  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerOpenFile"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerMeasureFile

       DESCRIPTION:  returns the size of an NT style file to the caller

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerMeasureFile( int iArgc )
{
  m_poInterpreter->SetLastCall( "MeasureFile" );

  HANDLE hFile;

  VerifyRunLineArguments( iArgc, 1 );
  VerifyElementType( 0, DT_NTFILEHANDLE );

  hFile = m_poVirtualChip->m_psStackPointer[0].v.v_handle;

  DWORD dwReturn = GetFileSize( hFile, NULL );

  // If we failed, set size to zero
  // 
  if ( dwReturn == 0xFFFFFFFF )
  {
    dwReturn = -1;
  }
 
  // send back the return code
  //
  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], dwReturn );
  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerMeasureFile"
/*****************************************************************************/


/*****************************************************************************/
/*

     FUNCTION NAME:  VMVirtualOpSys::HandlerCountLinesInFile

       DESCRIPTION:  counts the number of lines in a file. 

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerCountLinesInFile( int iArgc )
{
  m_poInterpreter->SetLastCall( "CountLinesInFile" );

  HANDLE hFile;
  long   lMove;
  long   lReference;
  DWORD  dwMoved;
  long   lReturn = 0;

  VerifyRunLineArguments( iArgc, 3 );
  VerifyElementType( 2, DT_NTFILEHANDLE );
  VerifyElementType( 1, DT_INTEGER );
  VerifyElementType( 0, DT_INTEGER );

  hFile      = m_poVirtualChip->m_psStackPointer[ 2 ].v.v_handle;
  lMove      = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_integer;
  lReference = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_integer;

  DWORD dwReference = FILE_BEGIN;
  switch ( lReference )
  {
    case 0:
    {
      dwReference = FILE_BEGIN;
    }
    break;

    case 1:
    {
      dwReference = FILE_CURRENT;
    }
    break;

    case 3:
    {
      dwReference = FILE_END;
    }
    break;
  }
  dwMoved = SetFilePointer( hFile, lMove, NULL, dwReference );
  if ( 0xFFFFFFFF == dwMoved )
  {
    lReturn = -1;
  }
  else
  {
    unsigned char chLast;
    unsigned char chCrnt;
    DWORD         dwNumRead;

    while ( ReadFile( hFile, &chCrnt, 1, &dwNumRead, NULL ) )
    {
      chLast = chCrnt;
           
      if ( ( chLast == chCrnt ) && ( ( '\n' == chCrnt ) || ( '\r' == chCrnt ) ) )
      {
        lReturn++;
      }
      if ( ( '\r' == chLast ) && ( '\n' == chCrnt ) )
      {
        lReturn++;
      }
      else
      if ( ( '\r' == chLast ) && ( '\n' != chCrnt ) )
      {
        lReturn++;
      }
      else
      if ( ( '\r' != chLast ) && ( '\n' == chCrnt ) )
      {
        lReturn++;
      }
    }
  }
  // send back the return code
  //
  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], lReturn );

  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerCountLinesInFile"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerWriteTextToFile

       DESCRIPTION:  writes a text block to a file

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerWriteTextToFile( int iArgc )
{
  m_poInterpreter->SetLastCall( "WriteTextToFile" );

  VerifyRunLineArguments( iArgc, 2 );
  VerifyElementType( 1, DT_NTFILEHANDLE );
  VerifyElementType( 0, DT_STRING );

  HANDLE hFile   = m_poVirtualChip->m_psStackPointer[1].v.v_handle;
  char*  pchText = m_poVirtualChip->m_psStackPointer[0].v.v_string->str_data; 

  DWORD  dwWritten     = 0;
  DWORD  dwSizeToWrite = strlen( pchText );
  bool   bResult       = false;

  if ( dwSizeToWrite )
  {
    if ( WriteFile( hFile, pchText, dwSizeToWrite, &dwWritten, NULL ) )
    {
      if ( dwSizeToWrite == dwWritten )
      {
         bResult = true;
      }
    }
  }

  // send back the return code
  //
  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], bResult );

  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerWriteTextToFile"
/*****************************************************************************/



/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerWriteToFile

       DESCRIPTION:  Elliptic function for writing to a file. Knows how to
                     write integers and strings. Walks across the param list
                     writing what it finds in each position.

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerWriteToFile( int iArgc )
{
  m_poInterpreter->SetLastCall( "WriteToFile" );

  long        lArgsWritten = 0;
  HANDLE      hFile;
  long        lToWrite   = 0;
  char*       pchToWrite = NULL;
  DWORD       dwSizeToWrite;
  void*       pToWrite;
  DWORD       dwWritten;
  long        lNumEntrys;
  char*       pChar;
  int         len;
  REC_HEADER  xRecHeader;

  VerifyRunLineArguments( iArgc, 3 );
  VerifyElementType( 2, DT_NTFILEHANDLE );
  VerifyElementType( 1, DT_INTEGER );
  VerifyElementType( 0, DT_VECTOR );

  xRecHeader.m_iHeaderSize = sizeof( REC_HEADER );

  hFile      = m_poVirtualChip->m_psStackPointer[2].v.v_handle;
  lNumEntrys = m_poVirtualChip->m_psStackPointer[1].v.v_integer;

  if ( lNumEntrys <= m_poVirtualChip->m_psStackPointer[0].v.v_vector->vec_size )
  {
    for ( int iLoop = 0; iLoop <= lNumEntrys; iLoop++ )
    {
      switch( m_poVirtualChip->m_psStackPointer[0].v.v_vector->vec_data[ iLoop ].v_type )
      {
        case DT_INTEGER:
        {
          lToWrite = m_poVirtualChip->m_psStackPointer[0].v.v_vector->vec_data[ iLoop ].v.v_integer;
          pToWrite = &lToWrite;
          dwSizeToWrite = sizeof( long );

          xRecHeader.m_iType = DT_INTEGER;
          xRecHeader.m_iRecSize = sizeof( long );
        }             
        break;

        case DT_STRING:
        {
          pChar  = strgetdata( &m_poVirtualChip->m_psStackPointer[0].v.v_vector->vec_data[ iLoop ] );
          len    = strgetsize( &m_poVirtualChip->m_psStackPointer[0].v.v_vector->vec_data[ iLoop ] );
          pchToWrite = new char[len + 1 ];
          strncpy( pchToWrite, pChar, len );
          *(pchToWrite+len) = 0;
          pToWrite = pchToWrite;
          dwSizeToWrite = strlen( pchToWrite ) + 1;

          xRecHeader.m_iType = DT_STRING;
          xRecHeader.m_iRecSize = dwSizeToWrite;
        }             
        break;

        // mjs: add new types here. double, date, dword, byte, etc.

        default: 
        {
          dwSizeToWrite = 0;
        }
        break;
      }
      if ( dwSizeToWrite )
      {
        if ( WriteFile( hFile, &xRecHeader, (DWORD)sizeof( REC_HEADER ), &dwWritten, NULL ) )
        {
          if ( sizeof( REC_HEADER ) == dwWritten )
          {
            if ( WriteFile( hFile, pToWrite, dwSizeToWrite, &dwWritten, NULL ) )
            {
              if ( dwSizeToWrite == dwWritten )
              {
                lArgsWritten++;
              }
              else
              {
                break;
              }
            }
            else
            {
              break;
            }
          }
          else
          {
            break;
          }
        }
        else
        {
          break;
        }
      }
    }
  }
  // send back the return code
  //
  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], lArgsWritten );

  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerWriteToFile"
/*****************************************************************************/


/*****************************************************************************/
/*

     FUNCTION NAME:  VMVirtualOpSys::HandlerReadFromFile

       DESCRIPTION:  Elliptic function for reading from a file. Knows how to
                     read integers and strings. Walks across the param list
                     writing what it finds in each position.

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerReadFromFile( int iArgc )
{
  m_poInterpreter->SetLastCall( "ReadFromFile" );

  REC_HEADER  xRecHeader;
  long        lArgsRead = 0;
  HANDLE      hFile;
  DWORD       dwBytesRead;
  long        lOneLong;
  char*       pchReadTarget;
  long        lNumEntrys;

  VerifyRunLineArguments( iArgc, 2 );
  VerifyElementType( 1, DT_NTFILEHANDLE );
  VerifyElementType( 0, DT_INTEGER );

  xRecHeader.m_iHeaderSize = sizeof( REC_HEADER );

  hFile = m_poVirtualChip->m_psStackPointer[2].v.v_handle;
  lNumEntrys = m_poVirtualChip->m_psStackPointer[1].v.v_integer;

  VMDataVector* poVector = new VMDataVector;

  if ( lNumEntrys <= m_poVirtualChip->m_psStackPointer[0].v.v_var->de_value.v.v_vector->vec_size )
  {
    for ( int iLoop = 0; iLoop <= lNumEntrys; iLoop++ )
    {
      if ( ReadFile( hFile, &xRecHeader, (DWORD)sizeof( xRecHeader ), &dwBytesRead, NULL ) )
      {
        if ( (DWORD)sizeof( xRecHeader ) == dwBytesRead )
        {
          switch( xRecHeader.m_iType )
          {
            case DT_INTEGER:
            {
              if ( ReadFile( hFile, &lOneLong, (DWORD)sizeof( long ), &dwBytesRead, NULL ) )
              {
                if ( (DWORD)sizeof( long ) == dwBytesRead )
                {
                  VMVariant oValue;
                  oValue.v_type      = DT_INTEGER;
                  oValue.v.v_integer = lOneLong;
                  poVector->Append( oValue );
                }
              }
            }
            break;

            case DT_STRING:
            {
              pchReadTarget = new char[ xRecHeader.m_iRecSize ];
              if ( ReadFile( hFile, pchReadTarget, (DWORD) xRecHeader.m_iRecSize, &dwBytesRead, NULL ) )
              {
                if ( (DWORD)xRecHeader.m_iRecSize == dwBytesRead )
                {
                  VMVariant oValue;
                  oValue.v_type   = DT_STRING;
                  vmstring* pchReturn = AllocateNewString( strlen( pchReadTarget ), true );
                  oValue.v.v_string = pchReturn;
                  strcpy( pchReturn->str_data, pchReadTarget );
                  poVector->Append( oValue );
                }
              }
              delete [] pchReadTarget;
            }
            break;

            // mjs; add more types here, doubles, dates, bytes, dwords, etc.

          }
        }
      }
    }
  }

  // send back the return vector
  //
  set_uservector( &m_poVirtualChip->m_psStackPointer[ iArgc ], poVector );

  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerReadFromFile"
/*****************************************************************************/


int VMVirtualOpSys::HandlerLoadTextFile( int iArgc )
{
  m_poInterpreter->SetLastCall( "LoadTextFile" );

  HANDLE   hFile;
  DWORD    dwBytesRead;
  DWORD    dwFileSize;
  char*    pchData = NULL;

  VerifyRunLineArguments( iArgc, 1 );

  if ( m_poVirtualChip->m_psStackPointer[ 0 ].v_type == DT_STRING )
  {
    char* pchFile = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_string->str_data;

    hFile = CreateFile( pchFile, 
                        GENERIC_READ,
                        0,  // exclusive access
                        NULL,
                        OPEN_EXISTING,
                        FILE_ATTRIBUTE_NORMAL,
                        NULL ); 
  }
  else
  if ( m_poVirtualChip->m_psStackPointer[ 0 ].v_type == DT_NTFILEHANDLE )
  {
    hFile = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_handle;
  }
  else
  {
    VerifyElementType( 0, DT_STRING );
  }

  if ( INVALID_HANDLE_VALUE != hFile )
  {
    if ( 0xFFFFFFFF == ( dwFileSize = GetFileSize( hFile, NULL ) ) )
    {
      CloseHandle( hFile );
      hFile = NULL;
    }
    else
    {
      // read a block of records and process it
      //
      pchData = new char[ dwFileSize + 1 ];
      pchData[ dwFileSize ] = 0; 
      if ( ReadFile( hFile, 
                     pchData,
                     dwFileSize,
                     &dwBytesRead,
                     NULL ) )
      {
        if ( dwBytesRead != dwFileSize )
        {
          delete [] pchData;
          pchData = NULL;
        }
      }
      else
      {
        delete [] pchData;
        pchData = NULL;
      }
      CloseHandle( hFile );
    }
  }

  if ( NULL != pchData )
  {
    vmstring* pchReturn = AllocateNewString( strlen( pchData ), true );
    strcpy( pchReturn->str_data, pchData );
    SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], pchReturn );
  }
  else
  {
    set_nil( &m_poVirtualChip->m_psStackPointer[ iArgc ] );
  }
  m_poVirtualChip->m_psStackPointer += iArgc;

  return 0;
}


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerReadLineFromFile

       DESCRIPTION:  reads a file until it finds a \r, \n, or \r\n pair
                     returns the contents to the caller.

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerReadLineFromFile( int iArgc )
{
  m_poInterpreter->SetLastCall( "ReadLineFromFile" );

  HANDLE   hFile;
  char     achReply[2048];
  DWORD    dwNumberRead;
  char     chCrnt = 0;
  char     chLast = 0;

  VerifyRunLineArguments( iArgc, 1 );
  VerifyElementType( 0, DT_NTFILEHANDLE );

  hFile = m_poVirtualChip->m_psStackPointer[0].v.v_handle;
  ZeroMemory( achReply, 2048 );

  for ( int iLoop = 0; iLoop < 2048; iLoop++ )
  {
    if ( !ReadFile( hFile, achReply+iLoop, 1, &dwNumberRead, NULL ) )
    {
      if ( 1 != dwNumberRead )
      {
        break;
      }
      chLast = chCrnt;
      chCrnt = *achReply+iLoop;

      if ( ( chLast == chCrnt ) && ( ( '\n' == chCrnt ) || ( '\r' == chCrnt ) ) )
      {
        break;
      }

      if ( ( '\r' == chLast ) && ( '\n' == chCrnt ) )
      {
        break;
      }
      else
      if ( ( '\r' == chLast ) && ( '\n' != chCrnt ) )
      {
        break;
      }
      else
      if ( ( '\r' != chLast ) && ( '\n' == chCrnt ) )
      {
        break;
      }
    }
  }
  vmstring* pchReturn = AllocateNewString( strlen( achReply ), true );
  strcpy( pchReturn->str_data, achReply );
  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], pchReturn );

  m_poVirtualChip->m_psStackPointer += iArgc;

  return 0;
}
/* End of function "VMVirtualOpSys::HandlerReadLineFromFile"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerWriteLineToFile

       DESCRIPTION:  writes a line of text into a file at the current file
                     position

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerWriteLineToFile( int iArgc )
{
  m_poInterpreter->SetLastCall( "WriteLineToFile" );

  char*    pchToWrite;
  HANDLE   hFile;
  DWORD    dwNumberWritten;

  VerifyRunLineArguments( iArgc, 2 );
  VerifyElementType( 1, DT_NTFILEHANDLE );
  VerifyElementType( 0, DT_STRING );

  hFile      = m_poVirtualChip->m_psStackPointer[1].v.v_handle;
  pchToWrite = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_string->str_data;

  BOOL bReturn = WriteFile( hFile, pchToWrite, strlen( pchToWrite ), &dwNumberWritten, NULL );
  FlushFileBuffers( hFile );

  bReturn &= ( dwNumberWritten == strlen( pchToWrite ) );

  // send back the return code
  //
  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], bReturn );

  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerWriteLineToFile"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerSetFilePointer

       DESCRIPTION:  allows the SOB script to position the file pointer.

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerSetFilePointer( int iArgc )
{
  m_poInterpreter->SetLastCall( "SetFilePointer" );

  HANDLE   hFile;
  long     lNewPosition;
  long     lReference;
  DWORD    dwReference;

  VerifyRunLineArguments( iArgc, 3 );
  VerifyElementType( 2, DT_NTFILEHANDLE );
  VerifyElementType( 1, DT_INTEGER );
  VerifyElementType( 0, DT_INTEGER );

  hFile        = m_poVirtualChip->m_psStackPointer[2].v.v_handle;
  lNewPosition = m_poVirtualChip->m_psStackPointer[1].v.v_integer;
  lReference   = m_poVirtualChip->m_psStackPointer[0].v.v_integer;

  dwReference = FILE_BEGIN;
  switch ( lReference )
  {
    case 0:
    {
      dwReference = FILE_BEGIN;
    }
    break;

    case 1:
    {
      dwReference = FILE_CURRENT;
    }
    break;

    case 2: 
    {
      dwReference = FILE_END;
    }
    break;
  }

  BOOL  bReturn;
  DWORD dwReturn = SetFilePointer( hFile, lNewPosition, NULL, dwReference );

  if ( 0xFFFFFFFF == dwReturn )
  {
    bReturn = FALSE;
  }
  else
  {
    bReturn = TRUE;
  }

  // send back the return code
  //
  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], bReturn );

  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerSetFilePointer"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerGetFileAttribute

       DESCRIPTION:  returns a flag indicating whether or not a specific file
                     attribute is on/off

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerGetFileAttribute( int iArgc )
{
  m_poInterpreter->SetLastCall( "GetFileAttribute" );

  char* pchFile;
  char* pchAttrib;
  DWORD dwReturn = -1;
  DWORD dwAttrib;

  if ( 1 == iArgc )
  {
    VerifyElementType( 0, DT_STRING );
    pchFile = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_string->str_data;
  }
  else
  if ( 2 == iArgc )
  {
    VerifyElementType( 1, DT_STRING );
    VerifyElementType( 0, DT_STRING );
    pchFile   = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_string->str_data;
    pchAttrib = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_string->str_data;
  }
  else
  {      
    VerifyRunLineArguments( iArgc, 2 );
  }

/*
#define FILE_ATTRIBUTE_READONLY             0x00000001  
#define FILE_ATTRIBUTE_HIDDEN               0x00000002  
#define FILE_ATTRIBUTE_SYSTEM               0x00000004  
#define FILE_ATTRIBUTE_DIRECTORY            0x00000010  
#define FILE_ATTRIBUTE_ARCHIVE              0x00000020  
#define FILE_ATTRIBUTE_ENCRYPTED            0x00000040  
#define FILE_ATTRIBUTE_NORMAL               0x00000080  
#define FILE_ATTRIBUTE_TEMPORARY            0x00000100  
#define FILE_ATTRIBUTE_COMPRESSED           0x00000800  
#define FILE_ATTRIBUTE_OFFLINE              0x00001000  
*/
  dwAttrib = GetFileAttributes( pchFile );
  if ( 0xFFFFFFFF == dwAttrib )
  {
    dwReturn = -1;
  }

  if ( 2 == iArgc && -1 != dwReturn )
  {
    dwReturn = 1;

    // FILE_ATTRIBUTE_ARCHIVE The file or directory is an archive 
    // file or directory. Applications use this attribute to mark 
    // files for backup or removal. 
    //
    if ( strchr( pchAttrib, 'a' ) ) 
    { 
      dwReturn &= dwAttrib && FILE_ATTRIBUTE_ARCHIVE; 
    } 

    // FILE_ATTRIBUTE_COMPRESSED The file or directory is compressed. 
    // For a file, this means that all of the data in the file is 
    // compressed. For a directory, this means that compression is 
    // the default for newly created files and subdirectories. 
    //
    if ( strchr( pchAttrib, 'c' ) ) 
    { 
      dwReturn &= dwAttrib && FILE_ATTRIBUTE_COMPRESSED; 
    } 

    // FILE_ATTRIBUTE_DIRECTORY The handle identifies a directory. 
    //
    if ( strchr( pchAttrib, 'd' ) ) 
    { 
      dwReturn &= dwAttrib && FILE_ATTRIBUTE_DIRECTORY; 
    } 

    // FILE_ATTRIBUTE_ENCRYPTED The file or directory is encrypted. 
    // For a file, this means that all data streams are encrypted. 
    // For a directory, this means that encryption is the default 
    // for newly created files and subdirectories. 
    //
    if ( strchr( pchAttrib, 'e' ) ) 
    { 
      dwReturn &= dwAttrib && FILE_ATTRIBUTE_ENCRYPTED; 
    } 

    // FILE_ATTRIBUTE_HIDDEN The file or directory is hidden. It is 
    // not included in an ordinary directory listing. 
    //
    if ( strchr( pchAttrib, 'h' ) ) 
    { 
      dwReturn &= dwAttrib && FILE_ATTRIBUTE_HIDDEN; 
    } 

    // FILE_ATTRIBUTE_NORMAL The file or directory has no other 
    // attributes set. This attribute is valid only if used alone. 
    // 
    if ( strchr( pchAttrib, 'n' ) ) 
    { 
      dwReturn &= dwAttrib && FILE_ATTRIBUTE_NORMAL; 
    } 

    // FILE_ATTRIBUTE_OFFLINE The data of the file is not immediately 
    // available. Indicates that the file data has been physically 
    // moved to offline storage. 
    // 
    if ( strchr( pchAttrib, 'o' ) ) 
    { 
      dwReturn &= dwAttrib && FILE_ATTRIBUTE_OFFLINE; 
    } 

    // FILE_ATTRIBUTE_READONLY The file or directory is read-only. 
    // Applications can read the file but cannot write to it or 
    // delete it. In the case of a directory, applications cannot 
    // delete it. 
    //
    if ( strchr( pchAttrib, 'r' ) ) 
    { 
      dwReturn &= dwAttrib && FILE_ATTRIBUTE_READONLY; 
    } 

    // FILE_ATTRIBUTE_SYSTEM The file or directory is part of, or 
    // is used exclusively by, the operating system. 
    //
    if ( strchr( pchAttrib, 's' ) ) 
    { 
      dwReturn &= dwAttrib && FILE_ATTRIBUTE_SYSTEM; 
    } 

    // FILE_ATTRIBUTE_TEMPORARY The file is being used for temporary 
    // storage. File systems attempt to keep all of the data in 
    // memory for quicker access rather than flushing the data back 
    // to mass storage. A temporary file should be deleted by the 
    // application as soon as it is no longer needed. 
    // 
    if ( strchr( pchAttrib, 't' ) )
    { 
      dwReturn &= dwAttrib && FILE_ATTRIBUTE_TEMPORARY; 
    } 
  }
  // send back the return code
  //
  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], dwReturn );

  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerGetFileAttribute"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerSetFileAttribute

       DESCRIPTION:  allows a script to change certain file attributes

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerSetFileAttribute( int iArgc )
{
  m_poInterpreter->SetLastCall( "SetFileAttribute" );

  char* pchFile;
  char* pchAttrib;
  long  lSetOrClear;
  DWORD dwReturn = -1;
  DWORD dwAttrib;
  DWORD dwSetTo;

  VerifyRunLineArguments( iArgc, 3 );
  VerifyElementType( 2, DT_STRING );
  VerifyElementType( 1, DT_STRING );
  VerifyElementType( 0, DT_INTEGER );

  pchFile     = m_poVirtualChip->m_psStackPointer[ 2 ].v.v_string->str_data;
  pchAttrib   = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_string->str_data;
  lSetOrClear = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_integer;

/*
#define FILE_ATTRIBUTE_READONLY             0x00000001  
#define FILE_ATTRIBUTE_HIDDEN               0x00000002  
#define FILE_ATTRIBUTE_SYSTEM               0x00000004  
#define FILE_ATTRIBUTE_ARCHIVE              0x00000020  
#define FILE_ATTRIBUTE_NORMAL               0x00000080  
*/

  dwAttrib = GetFileAttributes( pchFile );
  if ( 0xFFFFFFFF == dwAttrib )
  {
    dwReturn = -1;
  }

  if ( -1 != dwReturn )
  {
    dwReturn = 1;

    // FILE_ATTRIBUTE_ARCHIVE The file or directory is an archive 
    // file or directory. Applications use this attribute to mark 
    // files for backup or removal. 
    //
    if ( strchr( pchAttrib, 'a' ) ) 
    {
      if ( lSetOrClear )
      {
        dwSetTo = dwAttrib | FILE_ATTRIBUTE_ARCHIVE; 
      }
      else
      {
        dwSetTo = dwAttrib & ~FILE_ATTRIBUTE_ARCHIVE;
      }
    }
    // FILE_ATTRIBUTE_HIDDEN The file or directory is hidden. It is 
    // not included in an ordinary directory listing. 
    //
    else
    if ( strchr( pchAttrib, 'h' ) ) 
    {
      if ( lSetOrClear )
      {
        dwSetTo = dwAttrib | FILE_ATTRIBUTE_HIDDEN; 
      }
      else
      {
        dwSetTo = dwAttrib & ~FILE_ATTRIBUTE_HIDDEN;
      }
    }
    // FILE_ATTRIBUTE_NORMAL The file or directory has no other 
    // attributes set. This attribute is valid only if used alone. 
    // 
    else
    if ( strchr( pchAttrib, 'n' ) ) 
    {
      if ( lSetOrClear )
      {
        dwSetTo = FILE_ATTRIBUTE_NORMAL; 
      }
      else
      {
        dwSetTo = dwAttrib & ~FILE_ATTRIBUTE_NORMAL;
      }
    }
    // FILE_ATTRIBUTE_READONLY The file or directory is read-only. 
    // Applications can read the file but cannot write to it or 
    // delete it. In the case of a directory, applications cannot 
    // delete it. 
    //
    else
    if ( strchr( pchAttrib, 'r' ) ) 
    {
      if ( lSetOrClear )
      {
        dwSetTo = dwAttrib | FILE_ATTRIBUTE_READONLY; 
      }
      else
      {
        dwSetTo = dwAttrib & ~FILE_ATTRIBUTE_READONLY;
      }
    }
    // FILE_ATTRIBUTE_SYSTEM The file or directory is part of, or 
    // is used exclusively by, the operating system. 
    //
    else
    if ( strchr( pchAttrib, 's' ) ) 
    {
      if ( lSetOrClear )
      {
        dwSetTo = dwAttrib | FILE_ATTRIBUTE_SYSTEM; 
      }
      else
      {
        dwSetTo = dwAttrib & ~FILE_ATTRIBUTE_SYSTEM;
      }
    }
  }

  if ( -1 != dwReturn && dwSetTo != dwAttrib )
  {
    dwReturn = (DWORD) SetFileAttributes( pchFile, dwSetTo );
  }

  // send back the return code
  //
  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], dwReturn );

  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerSetFileAttribute"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerDeleteFile

       DESCRIPTION:  allows a SOB script to nuke files

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerDeleteFile( int iArgc )
{
  m_poInterpreter->SetLastCall( "DeleteFile" );

  char*  pchFile;

  VerifyRunLineArguments( iArgc, 1 );
  VerifyElementType( 0, DT_STRING );

  pchFile = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_string->str_data;

  BOOL bReturn = DeleteFile( pchFile );

  // send back the return code
  //
  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], bReturn );

  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerDeleteFile"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerMoveFile

       DESCRIPTION:  attempts to move a file

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerMoveFile( int iArgc )
{
  m_poInterpreter->SetLastCall( "MoveFile" );

  char*  pchSource;
  char*  pchTarget;

  VerifyRunLineArguments( iArgc, 2 );
  VerifyElementType( 1, DT_STRING );
  VerifyElementType( 0, DT_STRING );

  pchSource = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_string->str_data;
  pchTarget = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_string->str_data;

  BOOL bReturn = MoveFile( pchSource, pchTarget );

  // send back the return code
  //
  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], bReturn );

  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerMoveFile"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerCompareFiles

       DESCRIPTION:  compares the contents of two files 

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerCompareFiles( int iArgc )
{
  m_poInterpreter->SetLastCall( "CompareFiles" );

  char*  pchFileOne;
  char*  pchFileTwo;
  long   lReturn;

  VerifyRunLineArguments( iArgc, 2 );
  VerifyElementType( 1, DT_STRING );
  VerifyElementType( 0, DT_STRING );

  pchFileOne = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_string->str_data;
  pchFileTwo = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_string->str_data;

  HANDLE hFile1 = CreateFile( pchFileOne,
                              GENERIC_WRITE | GENERIC_READ,
                              0,  // exclusive access
                              NULL,
                              OPEN_EXISTING,
                              FILE_ATTRIBUTE_NORMAL,
                              NULL );

  HANDLE hFile2 = CreateFile( pchFileTwo,
                              GENERIC_WRITE | GENERIC_READ,
                              0,  // exclusive access
                              NULL,
                              OPEN_EXISTING,
                              FILE_ATTRIBUTE_NORMAL,
                              NULL );

  if ( INVALID_HANDLE_VALUE != hFile1 && INVALID_HANDLE_VALUE != hFile2 )
  {
    DWORD dwSize1 = GetFileSize( hFile1, NULL );
    DWORD dwSize2 = GetFileSize( hFile2, NULL );

    if ( 0xFFFFFFFF != dwSize1 && 0xFFFFFFFF != dwSize2 )
    {
      if ( dwSize1 == dwSize2 )
      {
        unsigned char achFile1Chunk[1024];
        unsigned char achFile2Chunk[1024];
        DWORD         dwReadOne;
        DWORD         dwReadTwo;
        DWORD         dwTotalReadOne = 0;
        DWORD         dwTotalReadTwo = 0;

        while ( dwTotalReadOne <= dwSize1 && dwTotalReadTwo <= dwSize2 )
        {
          BOOL bReadOne = ReadFile( hFile1, achFile1Chunk, 1024, &dwReadOne, NULL );
          BOOL bReadTwo = ReadFile( hFile2, achFile2Chunk, 1024, &dwReadTwo, NULL );

          if ( bReadOne && bReadTwo )
          {
            if ( dwReadOne == dwReadTwo )
            {
              dwTotalReadOne += dwReadOne;
              dwTotalReadTwo += dwReadTwo;

              if ( 0 != ( lReturn = memcmp( achFile1Chunk, achFile2Chunk, dwReadOne ) ) )
              {
                break;
              }
            }
            else 
            {
              lReturn = -5;
              break;
            }
          }
          else
          {
            lReturn = -4;
            break;
          }
        } 
      }
      else
      {
        if ( dwSize1 < dwSize2 )
        {
          lReturn = -1;
        }
        else
        {
          lReturn = 1;
        }
      }
    }
    else
    {
      lReturn = -3;
    }

    CloseHandle( hFile1 );
    CloseHandle( hFile2 );
  }
  else
  {
    lReturn = -2;
  }

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], lReturn );

  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerCompareFiles"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerGetFileSize

       DESCRIPTION:  gets the file size for any given file name (works for
                     files 2Gig or less)

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerGetFileSize( int iArgc )
{
  m_poInterpreter->SetLastCall( "GetFileSize" );

  char*  pchFile;
  DWORD  dwSize = 0;

  VerifyRunLineArguments( iArgc, 1 );
  VerifyElementType( 0, DT_STRING );

  pchFile = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_string->str_data;

  HANDLE hFile = CreateFile( pchFile,
                             GENERIC_WRITE | GENERIC_READ,
                             0,  // exclusive access
                             NULL,
                             OPEN_EXISTING,
                             FILE_ATTRIBUTE_NORMAL,
                             NULL );

  if ( INVALID_HANDLE_VALUE != hFile )
  {
    dwSize = GetFileSize( hFile, NULL );
    if ( 0xFFFFFFFF == dwSize )
    {
      dwSize = -2;
    }      
  }
  else
  {
    dwSize = -1;
  }

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], dwSize );
  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerGetFileSize"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerGetFileTime

       DESCRIPTION:  fetches a specified time attribute for a given file.

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerGetFileTime( int iArgc )
{
  m_poInterpreter->SetLastCall( "GetFileTime" );

  char*       pchFile;
  char*       pchWhich;
  FILETIME    xCreated;
  FILETIME    xLastAccess;
  FILETIME    xLastWrite;
  SYSTEMTIME  xDateTime;

  VerifyRunLineArguments( iArgc, 2 );
  VerifyElementType( 1, DT_STRING );
  VerifyElementType( 0, DT_STRING );

  pchFile  = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_string->str_data;
  pchWhich = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_string->str_data;

  HANDLE hFile = CreateFile( pchFile,
                             GENERIC_WRITE | GENERIC_READ,
                             0,  // exclusive access
                             NULL,
                             OPEN_EXISTING,
                             FILE_ATTRIBUTE_NORMAL,
                             NULL );

  if ( INVALID_HANDLE_VALUE != hFile )
  {
    if ( GetFileTime( hFile, &xCreated, &xLastAccess, &xLastWrite ) )
    {
      if ( !strcmp( pchWhich, "c" ) )
      {
        FileTimeToSystemTime( &xCreated, &xDateTime );
      }
      else
      if ( !strcmp( pchWhich, "a" ) )
      {
        FileTimeToSystemTime( &xLastAccess, &xDateTime );
      }
      else
      if ( !strcmp( pchWhich, "w" ) )
      {
        FileTimeToSystemTime( &xLastWrite, &xDateTime );
      }
    }
  }
  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], xDateTime );
  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerGetFileTime"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerSetFileTime

       DESCRIPTION:  allows an SOB script to modify the file attributes of a
                     file.

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerSetFileTime( int iArgc )
{
  m_poInterpreter->SetLastCall( "SetFileTime" );

  char*      pchWhich;
  HANDLE     hFile;
  BOOL       bReturn;
  SYSTEMTIME xSysTime;
  FILETIME   xCreated;
  FILETIME   xLastAccess;
  FILETIME   xLastWrite;


  VerifyRunLineArguments( iArgc, 3 );
  VerifyElementType( 2, DT_NTFILEHANDLE );
  VerifyElementType( 1, DT_DATETIME );
  VerifyElementType( 0, DT_STRING );

  hFile     = m_poVirtualChip->m_psStackPointer[ 2 ].v.v_handle;
  xSysTime  = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_datetime;
  pchWhich  = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_string->str_data;

  if ( GetFileTime( hFile, &xCreated, &xLastAccess, &xLastWrite ) )
  {
    if ( !strcmp( pchWhich, "c" ) )
    {
      bReturn = SystemTimeToFileTime( &xSysTime, &xCreated );
    }
    else
    if ( !strcmp( pchWhich, "a" ) )
    {
      bReturn = SystemTimeToFileTime( &xSysTime, &xLastAccess );
    }
    else
    if ( !strcmp( pchWhich, "w" ) )
    {
      bReturn = SystemTimeToFileTime( &xSysTime, &xLastWrite );
    }

    if ( bReturn )
    {
      bReturn = SetFileTime( hFile, &xCreated, &xLastAccess, &xLastWrite );
    }
  }
  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], bReturn );

  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerSetFileTime"
/*****************************************************************************/


/*****************************************************************************/
/*

     FUNCTION NAME:  VMVirtualOpSys::HandlerTemplateStringFormat

       DESCRIPTION:  specialized template processing assist function. Pulls a
                     string (by name) from the template context, then formats
                     that string against all the inputs and then returns that
                     string to the interpreter via output variable

             INPUT:  int iArgc - the number of arguments passed to this 
            OUTPUT:  none

           RETURNS:  zero
*/
int VMVirtualOpSys::HandlerTemplateStringFormat( int iArgc )
{
  m_poInterpreter->SetLastCall( "TemplateStringFormat" );

  int        iNumPercents = 0;
  char*      pchFormatString;
  char       achOutputString[8096];
  char*      pcChar;
  int        iCurrentArgument = iArgc - 2;
  int        iCopyToPosition  = 0;
  char*      pChar;
  int        len;
  char       achAM_PM[] = "AM";

  memset( achOutputString, 0, sizeof( achOutputString ) );

  if ( iArgc >= 1 )
  {
    VerifyElementType( iArgc - 1, DT_STRING );

    const CAppContextVariant* poFieldValue;
    poFieldValue = m_poServerContext->GetFieldByName( m_poVirtualChip->m_psStackPointer[ iArgc - 1 ].v.v_string->str_data );

    if ( poFieldValue )
    {
      int iSize;
      poFieldValue->GetValue( (char*)NULL, iSize );
      pchFormatString = new char[ iSize + 1 ];
      poFieldValue->GetValue( pchFormatString, iSize );

      pcChar = pchFormatString;

      // count the number of arguments to expect from the call
      //
      do
      {
        if ( '%' == *pcChar ) 
        {
          if ( ( '%' != *(pcChar+1) ) && ( '%' != *(pcChar-1) ) )
          {
           iNumPercents++;
          }
        }
        pcChar++;
      }   while ( *pcChar != '\0' );

      pcChar = pchFormatString;

      // target_buffer, "format string with n % symbols", args....
      // since number of args must equal number % symbols, then
      // the total number of input arguments must be :
      // iNumPercents + 1
      //
      if ( iArgc >= iNumPercents + 1 )
      {
        do
        {
          if ( '%' == *pcChar )
          {
            if ( '%' == *(pcChar + 1) )
            {
              pcChar++;
              achOutputString[iCopyToPosition] = *pcChar;
              iCopyToPosition++;
            }
            else
            {
              char  achToAppend[1024];
              switch( m_poVirtualChip->m_psStackPointer[iCurrentArgument].v_type )
              {
                case DT_NIL:
                {
                  strcpy( achToAppend, "nil" );
                }
                break;

                case DT_INTEGER:
                {
                  sprintf( achToAppend, 
                           "%ld", 
                           m_poVirtualChip->m_psStackPointer[iCurrentArgument].v.v_integer );
                }
                break;

                case DT_STRING:
                {
                  pChar  = strgetdata( &m_poVirtualChip->m_psStackPointer[iCurrentArgument] );
                  len    = strgetsize( &m_poVirtualChip->m_psStackPointer[iCurrentArgument] );
                  strncpy( achToAppend, pChar, len );
                  achToAppend[len] = 0;
                }
                break;

                case DT_DWORD:
                {
                  sprintf( achToAppend,
                           "%ld",
                           m_poVirtualChip->m_psStackPointer[iCurrentArgument].v.v_dword );
                }
                break;

                case DT_DOUBLE:
                {
                  sprintf( achToAppend,
                           "% 10.2f",
                           m_poVirtualChip->m_psStackPointer[iCurrentArgument].v.v_double );
                }
                break;

                case DT_BYTE:
                {
                  sprintf( achToAppend,
                           "%s",
                           ( m_poVirtualChip->m_psStackPointer[iCurrentArgument].v.v_byte != 0 ) ? "true" : "false" );
                }
                break;

                case DT_DATETIME:
                {
                  SYSTEMTIME xTime = m_poVirtualChip->m_psStackPointer[iCurrentArgument].v.v_datetime; 

                  if ( xTime.wHour > 12 )        // Set up extension.
                    strcpy( achAM_PM, "PM" );
                  else
                    strcpy( achAM_PM, "AM" );

                  sprintf( achToAppend, 
                           "%02u/%02u/%04u %02u:%02u:%02u %s",
                           xTime.wMonth,
                           xTime.wDay,
                           xTime.wYear,
                           xTime.wHour,
                           xTime.wMinute,
                           xTime.wSecond,
                           achAM_PM );
                }
                break;
              }
              strcat( achOutputString, achToAppend );
              iCopyToPosition += strlen( achToAppend );
              iCurrentArgument--;
            }
          }
          else
          {
            achOutputString[iCopyToPosition] = *pcChar;
            iCopyToPosition++;
          }
          pcChar++;
        } while ( *pcChar != '\0' );     
      }
      delete [] pchFormatString;
    }
  }
  vmstring* pchOutput = AllocateNewString( strlen( achOutputString ), true );
  strcpy( pchOutput->str_data, achOutputString );
  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], pchOutput );

  m_poVirtualChip->m_psStackPointer += iArgc;
  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerTemplateStringFormat"
/*****************************************************************************/


const char ccCmdOpen[]         = { "$$"       };
const char ccCmdEnd[]          = { "$$"       };
const char ccDocVar[]          = { "$$DocVar" };
const char ccCmdModBeg[]       = { "("        };
const char ccCmdModEnd[]       = { ")$$"      };


/*****************************************************************************/
/*

     FUNCTION NAME:  VMVirtualOpSys::HandlerTemplateSectionOutputDirect

       DESCRIPTION:  specialized template processing function for building
                     an output string to send directly to the template processor
                     output file

             INPUT:  int iArgc - the number of arguments passed to this 
            OUTPUT:  none

           RETURNS:  zero
*/
int VMVirtualOpSys::HandlerTemplateSectionOutputDirect( int iArgc )
{
  m_poInterpreter->SetLastCall( "TemplateSectionOutputDirect" );

  char* pchFieldName = NULL;

  VerifyRunLineArguments( iArgc, 2   );
  VerifyElementType( 1, DT_STRING    );
  VerifyElementType( 0, DT_HASHTABLE );

  const CAppContextVariant* poFieldValue;
  poFieldValue = m_poServerContext->GetFieldByName( m_poVirtualChip->m_psStackPointer[ 1 ].v.v_string->str_data );

  int iIndex = 0;

  if ( poFieldValue )
  {
    VMHashTable* poMap = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_hashtable;
    int          iSize;

    poFieldValue->GetValue( (char*)NULL, iSize );
    char* pchTplSection = new char[ iSize + 1 ];
    poFieldValue->GetValue( pchTplSection, iSize );

    char* pchBase   = pchTplSection;
    char* pchOutVar = strstr( pchTplSection, ccDocVar );

    if ( NULL == pchOutVar )
    {
      // no variables in the block, so just output the block as is
      //
      m_poServerContext->WriteDirectToTemplateContext( pchTplSection );
      iIndex = iSize;
    }
    else
    {
      iIndex = pchOutVar - pchTplSection;
    }
    while ( NULL != pchOutVar && iIndex < iSize )
    {
      // write out the text from the beginning of block to the start
      // of the variable insertion point
      //
      if ( pchOutVar - pchBase > 0 )
      {
        char* pchSegment = new char[ pchOutVar - pchBase + 1 ];
        memset( pchSegment, 0, pchOutVar - pchBase + 1 );
        memcpy( pchSegment, pchBase, pchOutVar - pchBase );
        m_poServerContext->WriteDirectToTemplateContext( pchSegment );
        delete [] pchSegment;   
      }

      pchOutVar = strstr( pchOutVar, ccCmdModBeg );
      if ( pchOutVar != NULL )
      {
        iIndex = pchOutVar - pchTplSection;
        char* pchVarName = pchOutVar + 1;
        pchOutVar = strstr( pchVarName, ccCmdModEnd );
        if ( pchOutVar != NULL )
        {
          char  achVarName[ 256 ];
          memset( achVarName, 0, 256 );
          strncpy( achVarName, pchVarName, pchOutVar - pchVarName );

          pchBase = pchOutVar + strlen( ccCmdModEnd );

          if ( strlen( achVarName ) )
          {
            VMVariant oKey;
            VMVariant oValue;
            int       iAllocSize = strlen( achVarName ) + sizeof( VMSTRING );

            oKey.v_type     = DT_STRING;
            oKey.v.v_string = (VMSTRING*)new char[ iAllocSize ];
            memset( oKey.v.v_string, 0, iAllocSize );
            oKey.v.v_string->str_size = strlen( achVarName );            
            memcpy( &oKey.v.v_string->str_data, achVarName, strlen( achVarName ) );

            if ( poMap->LookUp( oKey, oValue ) )
            {
              switch ( oValue.v_type )
              {
                case DT_NIL:
                {
                  m_poServerContext->WriteDirectToTemplateContext( "nil" );
                }
                break;

                case DT_INTEGER:
                {
                  char achValue[ 50 ];
                  sprintf( achValue, "%ld", oValue.v.v_integer );
                  m_poServerContext->WriteDirectToTemplateContext( achValue );
                }
                break;

                case DT_STRING:
                {
                  m_poServerContext->WriteDirectToTemplateContext( oValue.v.v_string->str_data );
                }
                break;

                case DT_DWORD:
                {
                  char achValue[ 50 ];
                  sprintf( achValue, "%ld", oValue.v.v_dword );
                  m_poServerContext->WriteDirectToTemplateContext( achValue );
                }
                break;

                case DT_DATETIME:
                {
                  char       achAM_PM[ 10 ];
                  char       achValue[ 50 ];
                  SYSTEMTIME xTime = oValue.v.v_datetime; 

                  if ( xTime.wHour > 12 )        // Set up extension.
                  {
                    strcpy( achAM_PM, "PM" );
                  }
                  else
                  {
                    strcpy( achAM_PM, "AM" );
                  }

                  sprintf( achValue, 
                           "%02u/%02u/%04u %02u:%02u:%02u %s",
                           xTime.wMonth,
                           xTime.wDay,
                           xTime.wYear,
                           xTime.wHour,
                           xTime.wMinute,
                           xTime.wSecond,
                           achAM_PM );

                  m_poServerContext->WriteDirectToTemplateContext( achValue );
                }
                break;

                case DT_DOUBLE:
                {
                  char achValue[ 50 ];
                  sprintf( achValue,
                           "% 10.2f",
                           oValue.v.v_double );

                  m_poServerContext->WriteDirectToTemplateContext( achValue );
                }
                break;

                case DT_BYTE:
                {
                  char achValue[ 50 ];
                  sprintf( achValue,
                           "%s",
                           ( oValue.v.v_byte != 0 ) ? "true" : "false" );

                  m_poServerContext->WriteDirectToTemplateContext( achValue );
                }
                break;
              }
            }
            delete [] (char*) oKey.v.v_string;
          }
          iIndex = pchOutVar - pchTplSection;
        }
      }
      if ( iIndex < iSize )
      {
        pchOutVar = strstr( pchBase, ccDocVar );
      }
    }
    if ( iIndex < iSize )
    {
      if ( pchTplSection[ iIndex ]     == ')' 
        && pchTplSection[ iIndex + 1 ] == '$'  
        && pchTplSection[ iIndex + 2 ] == '$' )
      {
        iIndex += 3;
      }
      m_poServerContext->WriteDirectToTemplateContext( pchTplSection + iIndex );
    }
    delete [] pchTplSection;
  }
  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerTemplateSectionOutputDirect"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerRunTemplateFile

       DESCRIPTION:  processes a report template file

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerRunTemplateFile( int iArgc )
{
  VerifyRunLineArguments( iArgc, 3 );
  VerifyElementType( 2, DT_STRING );    // in file
  VerifyElementType( 1, DT_STRING );    // out file
  VerifyElementType( 0, DT_HASHTABLE ); // parameters to share with template

  char*         pchInFile  = m_poVirtualChip->m_psStackPointer[ 2 ].v.v_string->str_data;
  char*         pchOutFile = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_string->str_data;
  VMHashTable*  poMap      = get_hashtable( &m_poVirtualChip->m_psStackPointer[ 0 ] );

  // create another nested context to run the report 
  //
  VMFacade         oScript( false, NULL );
  SCRIPT_ARGUMENTS oArgs;

  oScript.SetVar( &oArgs );
  oScript.SetDebuggerHook( NULL );

  // if there are parameters to be passed,then share them here
  //
  int iCount  = poMap->GetCount();
  if ( iCount > 0 )
  {
    VMHashTableIterator oIter( *poMap );
    int iLoop = 0;
    while( iLoop < iCount )
    {
      VMVariant  oKey;
                 oKey.v_poMonitor = NULL;
                 oKey.v_type      = DT_NIL;

      VMVariant oVal;
                oVal.v_poMonitor = NULL;
                oVal.v_type      = DT_NIL;

      oKey = oIter.GetKey();
      oVal = oIter.GetData();

      // enforce template parameter type limits
      //
      if ( oKey.v_type == DT_STRING )
      {
        switch( oVal.v_type )
        {
          case DT_STRING:
          {
            oArgs.insert( SCRIPT_ARGUMENTS::value_type( oKey.v.v_string->str_data , 
                                                        new CAppContextVariant( oVal.v.v_string->str_data ) ) );
          }
          break;

          case DT_BYTE:
          {
            oArgs.insert( SCRIPT_ARGUMENTS::value_type( oKey.v.v_string->str_data , 
                                                        new CAppContextVariant( (bool)oVal.v.v_byte ) ) );
          }
          break;

          case DT_DOUBLE:
          {
            oArgs.insert( SCRIPT_ARGUMENTS::value_type( oKey.v.v_string->str_data , 
                                                        new CAppContextVariant( oVal.v.v_double ) ) );
          }
          break;

          case DT_DWORD:
          {
            oArgs.insert( SCRIPT_ARGUMENTS::value_type( oKey.v.v_string->str_data , 
                                                        new CAppContextVariant( oVal.v.v_dword ) ) );
          }
          break;

          case DT_DATETIME:
          {
            oArgs.insert( SCRIPT_ARGUMENTS::value_type( oKey.v.v_string->str_data , 
                                                        new CAppContextVariant( oVal.v.v_datetime ) ) );
          }
          break;

          case DT_INTEGER:
          {
            oArgs.insert( SCRIPT_ARGUMENTS::value_type( oKey.v.v_string->str_data , 
                                                        new CAppContextVariant( oVal.v.v_integer ) ) );
          }
          break;
        }
      }
      ++iLoop;
      ++oIter;
    }
  }

  // run the template now
  //
  oScript.RunTemplateFile( pchInFile, pchOutFile );

  if ( iCount > 0 )
  {
    // execution completed, clean up the data map
    //
    SCRIPT_ARGUMENTS_ITER oCleanIter;
    for( oCleanIter  = oArgs.begin();
         oCleanIter != oArgs.end();
         oCleanIter++ )
    {
      delete (*oCleanIter).second;
    }
    oArgs.clear();
  }

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], 1 );
  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerRunTemplateFile"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerIniFileDeleteEntry

       DESCRIPTION:  deletes an entry from an ini file by doing a "null write"
                     to the entry

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerIniFileDeleteEntry( int iArgc )
{
  m_poInterpreter->SetLastCall( "IniFileDeleteEntry" );

  char* pchIniFile;
  char* pchSection;
  char* pchEntry;
  long  lReturn = 0;

  VerifyRunLineArguments( iArgc, 3 );
  VerifyElementType( 2, DT_STRING );
  VerifyElementType( 1, DT_STRING );
  VerifyElementType( 0, DT_STRING );

  pchIniFile = m_poVirtualChip->m_psStackPointer[ 2 ].v.v_string->str_data;
  pchSection = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_string->str_data;
  pchEntry   = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_string->str_data;

  VMPathMaker oPath;
  if ( oPath.CreateFilePath( pchIniFile ) )
  {
    lReturn = WritePrivateProfileString( pchSection, 
                                         pchEntry,
                                         NULL,
                                         pchIniFile );
  }
  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], lReturn );

  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerIniFileDeleteEntry"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerIniGetSection

       DESCRIPTION:  returns an entire section of an ini file to the caller

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerIniGetSection( int iArgc )
{
  m_poInterpreter->SetLastCall( "IniGetSection" );

  char* pchIniFile;
  char* pchSection;
  char* pchDelim;
  char  achReply[32767];  // follow windows95 limitation
  DWORD dwReplySize;

  ZeroMemory( achReply, 32767 );

  VerifyRunLineArguments( iArgc, 3 );
  VerifyElementType( 2, DT_STRING );
  VerifyElementType( 1, DT_STRING );
  VerifyElementType( 0, DT_STRING );

  pchIniFile = m_poVirtualChip->m_psStackPointer[ 2 ].v.v_string->str_data;
  pchSection = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_string->str_data;
  pchDelim   = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_string->str_data;


  VMPathMaker oPath;
  if ( oPath.CreateFilePath( pchIniFile ) )
  {
    dwReplySize = GetPrivateProfileSection( pchSection,
                                            achReply,
                                            32767,
                                            pchIniFile );
  }
  for ( DWORD dwLoop = 0; dwLoop < dwReplySize; dwLoop++ )
  {
    if ( achReply[ dwLoop ] == 0 )
    {
      achReply[ dwLoop ] = *pchDelim;
    }
  }
  vmstring* pchReturn = AllocateNewString( strlen( achReply ), true );
  strcpy( pchReturn->str_data, achReply );
  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], pchReturn );

  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerIniGetSection"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerIniFileReadInt

       DESCRIPTION:  reads an integer from an ini file

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerIniFileReadInt( int iArgc )
{
  m_poInterpreter->SetLastCall( "IniFileReadInt" );

  char* pchIniFile;
  char* pchSection;
  char* pchEntry;
  int   iValue;
  char  achValue[ 32768 ];

  VerifyRunLineArguments( iArgc, 3 );
  VerifyElementType( 2, DT_STRING );
  VerifyElementType( 1, DT_STRING );
  VerifyElementType( 0, DT_STRING );

  pchIniFile = m_poVirtualChip->m_psStackPointer[ 2 ].v.v_string->str_data;
  pchSection = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_string->str_data;
  pchEntry   = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_string->str_data;

  DWORD dwResult = 0;

  dwResult = GetPrivateProfileString( pchSection,
                                      pchEntry,
                                      "0",
                                      achValue,
                                      32767,
                                      pchIniFile );
  if ( 0 < dwResult )
  {
    iValue = atoi( achValue );
  }

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], iValue );

  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerIniFileReadInt"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerIniFileWriteInt

       DESCRIPTION:  reads an integer from an ini file

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerIniFileWriteInt( int iArgc )
{
  m_poInterpreter->SetLastCall( "IniFileWriteInt" );

  char* pchIniFile;
  char* pchSection;
  char* pchEntry;
  long  lValue;
  long  lReturn = 0;

  VerifyRunLineArguments( iArgc, 4 );
  VerifyElementType( 3, DT_STRING );
  VerifyElementType( 2, DT_STRING );
  VerifyElementType( 1, DT_STRING );
  VerifyElementType( 0, DT_INTEGER );

  pchIniFile = m_poVirtualChip->m_psStackPointer[ 3 ].v.v_string->str_data;
  pchSection = m_poVirtualChip->m_psStackPointer[ 2 ].v.v_string->str_data;
  pchEntry   = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_string->str_data;

  lValue     = m_poVirtualChip->m_psStackPointer[0].v.v_integer;

  VMPathMaker oPath;
  if ( oPath.CreateFilePath( pchIniFile ) )
  {
    char  achValue[50];
    ltoa( lValue, achValue, 10 );
    lReturn = WritePrivateProfileString( pchSection, 
                                         pchEntry,
                                         achValue,
                                         pchIniFile );
  }
  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], lReturn );

  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerIniFileWriteInt"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerIniFileReadDouble

       DESCRIPTION:  reads an integer from an ini file

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerIniFileReadDouble( int iArgc )
{
  m_poInterpreter->SetLastCall( "IniFileReadDouble" );

  char*   pchIniFile;
  char*   pchSection;
  char*   pchEntry;
  double  dblValue;
  char    achValue[ 32768 ];

  VerifyRunLineArguments( iArgc, 3 );
  VerifyElementType( 2, DT_STRING );
  VerifyElementType( 1, DT_STRING );
  VerifyElementType( 0, DT_STRING );

  pchIniFile = m_poVirtualChip->m_psStackPointer[ 2 ].v.v_string->str_data;
  pchSection = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_string->str_data;
  pchEntry   = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_string->str_data;

  DWORD dwResult = 0;

  dwResult = GetPrivateProfileString( pchSection,
                                      pchEntry,
                                      "0",
                                      achValue,
                                      32767,
                                      pchIniFile );
  if ( 0 < dwResult )
  {
    dblValue = atof( achValue );
  }

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], dblValue );

  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerIniFileReadDouble"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerIniFileWriteDouble

       DESCRIPTION:  reads an integer from an ini file

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerIniFileWriteDouble( int iArgc )
{
  m_poInterpreter->SetLastCall( "IniFileWriteDouble" );

  char*   pchIniFile;
  char*   pchSection;
  char*   pchEntry;
  double  dblValue;
  long    lReturn = 0;

  VerifyRunLineArguments( iArgc, 4 );
  VerifyElementType( 3, DT_STRING );
  VerifyElementType( 2, DT_STRING );
  VerifyElementType( 1, DT_STRING );
  VerifyElementType( 0, DT_DOUBLE );

  pchIniFile = m_poVirtualChip->m_psStackPointer[ 3 ].v.v_string->str_data;
  pchSection = m_poVirtualChip->m_psStackPointer[ 2 ].v.v_string->str_data;
  pchEntry   = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_string->str_data;

  dblValue   = m_poVirtualChip->m_psStackPointer[0].v.v_double;

  VMPathMaker oPath;
  if ( oPath.CreateFilePath( pchIniFile ) )
  {
    char    achValue[ 60 ];
    int     iDecimalPointAt;
    int     iSign;
    char*   pchBuffer;
    int     iPrecision = 50;
    double  source =  dblValue;

    // from docs: Only digits are stored in the string. 
    //
    // The position of the decimal point and the sign of value
    // can be obtained from dec and sign after the call.
    //
    // The dec parameter points to an integer value giving the
    // position of the decimal point with respect to the 
    // beginning of the string. A 0 or negative integer value
    // indicates that the decimal point lies to the left of the
    // first digit. 
    //
    // The sign parameter points to an integer that indicates 
    // the sign of the converted number. If the integer value
    // is 0, the number is positive. Otherwise, the number 
    // is negative.
    //
    pchBuffer = _ecvt( m_poVirtualChip->m_psStackPointer->v.v_double, 
                       iPrecision, 
                       &iDecimalPointAt, 
                       &iSign );

    int  iIndex = 0;
    memset( achValue, 0, 60 );
    if ( iSign != 0 )
    {
      // if negative, put in the sign
      //
      achValue[ 0 ] = '-';
      iIndex++; 
    }
 
    if ( iDecimalPointAt <= 0 )
    {
      // if decimal is first, then go this way
      //
      achValue[ iIndex ] = '.';
      iIndex++; 
      strcat( achValue, pchBuffer );
    }
    else
    {
      // decimal point embedded somewhere in the number
      // copy the whole part of the number first
      //
      for ( int iLoop = 0; iLoop < iDecimalPointAt; iLoop++ )
      {
        achValue[ iIndex ] = pchBuffer[ iLoop ];
        iIndex++;
      }
      // slap in the decimal point, then copy the rest 
      // of the buffer
      //
      achValue[ iIndex ] = '.';
      strcat( achValue, pchBuffer + iDecimalPointAt );
    }

    // trim off trailing zeroes
    //
    int iTop = strlen( achValue );
    while ( ( iTop > 1 ) 
         && ( achValue[ iTop ] == '0' )
         && ( achValue[ iTop - 1 ] == '0' ) )
    {
      achValue[ iTop ] = 0;
      iTop--;
    } 

    lReturn = WritePrivateProfileString( pchSection, 
                                         pchEntry,
                                         achValue,
                                         pchIniFile );
  }
  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], lReturn );

  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerIniFileWriteDouble"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerIniFileReadBool

       DESCRIPTION:  reads an integer from an ini file

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerIniFileReadBool( int iArgc )
{
  m_poInterpreter->SetLastCall( "IniFileReadBool" );

  char* pchIniFile;
  char* pchSection;
  char* pchEntry;
  bool  bValue;
  char  achValue[ 32768 ];

  VerifyRunLineArguments( iArgc, 3 );
  VerifyElementType( 2, DT_STRING );
  VerifyElementType( 1, DT_STRING );
  VerifyElementType( 0, DT_STRING );

  pchIniFile = m_poVirtualChip->m_psStackPointer[ 2 ].v.v_string->str_data;
  pchSection = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_string->str_data;
  pchEntry   = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_string->str_data;

  DWORD dwResult = 0;

  dwResult = GetPrivateProfileString( pchSection,
                                      pchEntry,
                                      "0",
                                      achValue,
                                      32767,
                                      pchIniFile );
  if ( 0 < dwResult )
  {
    if ( 0 == strcmp( achValue, "TRUE" )
      || 0 == strcmp( achValue, "true" )
      || 0 == strcmp( achValue, "1"    ) )
    {
      bValue = true;
    }
    else
    {
      bValue = false;
    }
  }
  else
  {
    bValue = false;
  }

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], bValue );

  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerIniFileReadInt"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerIniFileWriteBool

       DESCRIPTION:  reads an integer from an ini file

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerIniFileWriteBool( int iArgc )
{
  m_poInterpreter->SetLastCall( "IniFileWriteBool" );

  char* pchIniFile;
  char* pchSection;
  char* pchEntry;
  bool  bValue;
  long  lReturn = 0;

  VerifyRunLineArguments( iArgc, 4 );
  VerifyElementType( 3, DT_STRING );
  VerifyElementType( 2, DT_STRING );
  VerifyElementType( 1, DT_STRING );
  VerifyElementType( 0, DT_BYTE   );

  pchIniFile = m_poVirtualChip->m_psStackPointer[ 3 ].v.v_string->str_data;
  pchSection = m_poVirtualChip->m_psStackPointer[ 2 ].v.v_string->str_data;
  pchEntry   = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_string->str_data;

  bValue     = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_byte;

  VMPathMaker oPath;
  if ( oPath.CreateFilePath( pchIniFile ) )
  {
    char  achValue[50];

    if ( bValue )
    {
      strcpy( achValue, "1" );
    }
    else
    {
      strcpy( achValue, "0" );
    }
       

    lReturn = WritePrivateProfileString( pchSection, 
                                         pchEntry,
                                         achValue,
                                         pchIniFile );
  }
  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], lReturn );

  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerIniFileWriteInt"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerIniFileReadString

       DESCRIPTION:  reads a string from an ini file

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerIniFileReadString( int iArgc )
{
  m_poInterpreter->SetLastCall( "IniFileReadString" );

  char* pchIniFile;
  char* pchSection;
  char* pchEntry;
  char  achValue[32768];
  
  ZeroMemory( achValue, 32768 );

  VerifyRunLineArguments( iArgc, 3 );
  VerifyElementType( 2, DT_STRING );
  VerifyElementType( 1, DT_STRING );
  VerifyElementType( 0, DT_STRING );

  pchIniFile = m_poVirtualChip->m_psStackPointer[ 2 ].v.v_string->str_data;
  pchSection = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_string->str_data;
  pchEntry   = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_string->str_data;

  DWORD dwResult = 0;

  dwResult = GetPrivateProfileString( pchSection,
                                      pchEntry,
                                      "0",
                                      achValue,
                                      32767,
                                      pchIniFile );

  vmstring* pchReturn = AllocateNewString( strlen( achValue ), true );
  strcpy( pchReturn->str_data, achValue );
  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], pchReturn );

  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VirtualOpSys::HandlerIniFileReadString"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerIniFileWriteString

       DESCRIPTION:  reads an integer from an ini file

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerIniFileWriteString( int iArgc )
{
  m_poInterpreter->SetLastCall( "IniFileWriteString" );

  char* pchIniFile;
  char* pchSection;
  char* pchEntry;
  char* pchValue;
  long lReturn = 0;

  VerifyRunLineArguments( iArgc, 4 );
  VerifyElementType( 3, DT_STRING );
  VerifyElementType( 2, DT_STRING );
  VerifyElementType( 1, DT_STRING );
  VerifyElementType( 0, DT_STRING );

  pchIniFile = m_poVirtualChip->m_psStackPointer[ 3 ].v.v_string->str_data;
  pchSection = m_poVirtualChip->m_psStackPointer[ 2 ].v.v_string->str_data;
  pchEntry   = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_string->str_data;
  pchValue   = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_string->str_data;

  VMPathMaker oPath;
  if ( oPath.CreateFilePath( pchIniFile ) )
  {
    lReturn = WritePrivateProfileString( pchSection, 
                                         pchEntry,
                                         pchValue,
                                         pchIniFile );
  }

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], lReturn );

  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerIniFileWriteString"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerFindOpen

       DESCRIPTION:  attempts to find the first directory in a specified 
                     directory

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerFindOpen( int iArgc )
{
  m_poInterpreter->SetLastCall( "FindOpen" );

  char            achCurrentDir[ _MAX_PATH + 1 ];
  char*           pchDirToScan;
  bool            bCanContinue;
  bool            bSetDir;
  HANDLE          hFind;
  WIN32_FIND_DATA xFileInfo;

  VerifyRunLineArguments( iArgc, 1 );
  VerifyElementType( 0, DT_STRING );

  pchDirToScan = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_string->str_data;

  if ( GetCurrentDirectory( MAX_PATH, achCurrentDir ) )
  {
    if ( 0 != strcmp( achCurrentDir, pchDirToScan ) )
    { 
      bCanContinue = bSetDir = SetCurrentDirectory( pchDirToScan );
    }

    if ( bCanContinue )
    {
      hFind = FindFirstFile( "*.*", &xFileInfo );

      if ( bSetDir )
      {
         SetCurrentDirectory( achCurrentDir );
      }
    }
  }
  // send back the return code
  //
  set_filefindhandle( &m_poVirtualChip->m_psStackPointer[iArgc], hFind );
  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerFindOpen"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerFindFirstDir

       DESCRIPTION:  attempts to find the first directory in a specified 
                     directory

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerFindFirstDir( int iArgc )
{
  m_poInterpreter->SetLastCall( "FindFirstDir" );

  char            achCurrentDir[MAX_PATH+1];
  char            achFullPath[MAX_PATH+1];
  char*           pchDirToScan;
  WIN32_FIND_DATA xFileInfo;
  HANDLE          hFind;
  vmstring*       pchReturn;
  BOOL            bFoundOne    = FALSE;
  BOOL            bCanContinue = TRUE;
  BOOL            bSetDir      = FALSE;

  VerifyRunLineArguments( iArgc, 2 );
  VerifyElementType( 1, DT_FILEFINDHANDLE );
  VerifyElementType( 0, DT_STRING );

  hFind        = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_handle;
  pchDirToScan = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_string->str_data;

  if ( GetCurrentDirectory( MAX_PATH, achCurrentDir ) )
  {
    if ( 0 != strcmp( achCurrentDir, pchDirToScan ) )
    { 
      bCanContinue = bSetDir = SetCurrentDirectory( pchDirToScan );
    }

    if ( bCanContinue )
    {
      if ( INVALID_HANDLE_VALUE != hFind ) 
      {
        while ( !bFoundOne && FindNextFile( hFind, &xFileInfo ) )
        {
          if ( xFileInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY )
          {
            sprintf( achFullPath, "%s%s", pchDirToScan, xFileInfo.cFileName );
            pchReturn = AllocateNewString( strlen( achFullPath ), true );
            strcpy( pchReturn->str_data, achFullPath );
            SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], pchReturn ); 
            bFoundOne = TRUE;
          }
        }
      }
      if ( bSetDir )
      {
        SetCurrentDirectory( achCurrentDir );
      }
    }
  }
  if ( !bFoundOne )
  {
    pchReturn = AllocateNewString( 0, true );
    SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], pchReturn ); 
  }
  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerFindFirstDir"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerFindNextDir

       DESCRIPTION:  continues the find loop for directories. Assumes that the
                     find handle given to it is good 

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerFindNextDir( int iArgc )
{
  m_poInterpreter->SetLastCall( "FindNextDir" );

  char            achCurrentDir[MAX_PATH+1];
  char            achFullPath[MAX_PATH+1];
  char*           pchDirToScan;
  WIN32_FIND_DATA xFileInfo;
  HANDLE          hFind = NULL;
  vmstring*       pchReturn;
  BOOL            bFoundOne = FALSE;
  BOOL            bCanContinue = TRUE;
  BOOL            bSetDir      = FALSE;

  VerifyRunLineArguments( iArgc, 2 );
  VerifyElementType( 1, DT_FILEFINDHANDLE );
  VerifyElementType( 0, DT_STRING );

  hFind        = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_handle;
  pchDirToScan = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_string->str_data;

  if ( GetCurrentDirectory( MAX_PATH, achCurrentDir ) )
  {
    if ( 0 != strcmp( achCurrentDir, pchDirToScan ) )
    { 
       bCanContinue = bSetDir = SetCurrentDirectory( pchDirToScan );
    }

    if ( bCanContinue )
    {
      while( !bFoundOne && FindNextFile( hFind, &xFileInfo ) )
      {
        if ( xFileInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY )
        {
          sprintf( achFullPath, "%s%s", pchDirToScan, xFileInfo.cFileName );
          pchReturn = AllocateNewString( strlen( achFullPath ), true );
          strcpy( pchReturn->str_data, achFullPath );
          SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], pchReturn ); 
          bFoundOne = TRUE;
        }
      }
      if ( bSetDir )
      {
        SetCurrentDirectory( achCurrentDir );
      }
    }
  }
  if ( !bFoundOne )
  {
    pchReturn = AllocateNewString( 0, true );
    SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], pchReturn ); 
  }

  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerFindNextDir"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerFindFirstFile

       DESCRIPTION:  opens a find loop for scanning files in a specific
                     directory.

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerFindFirstFile( int iArgc )
{
  m_poInterpreter->SetLastCall( "FindFirstFile" );

  char            achCurrentDir[MAX_PATH+1];
  char            achFullPath[MAX_PATH+1];
  char*           pchDirToScan;
  WIN32_FIND_DATA xFileInfo;
  HANDLE          hFind;
  vmstring*       pchReturn;
  BOOL            bFoundOne    = FALSE;
  BOOL            bCanContinue = TRUE;
  BOOL            bSetDir      = FALSE;

  VerifyRunLineArguments( iArgc, 2 );
  VerifyElementType( 1, DT_FILEFINDHANDLE );
  VerifyElementType( 0, DT_STRING );

  hFind        = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_handle;
  pchDirToScan = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_string->str_data;

  if ( GetCurrentDirectory( MAX_PATH, achCurrentDir ) )
  {
    if ( 0 != strcmp( achCurrentDir, pchDirToScan ) )
    { 
      bCanContinue = bSetDir = SetCurrentDirectory( pchDirToScan );
    }

    if ( bCanContinue )
    {
      if ( INVALID_HANDLE_VALUE != hFind ) 
      {
        while ( !bFoundOne && FindNextFile( hFind, &xFileInfo ) )
        {
          if ( xFileInfo.dwFileAttributes 
               & ( FILE_ATTRIBUTE_NORMAL | FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_ARCHIVE ) )
          {
            sprintf( achFullPath, "%s%s", pchDirToScan, xFileInfo.cFileName );
            pchReturn = AllocateNewString( strlen( achFullPath ), true );
            strcpy( pchReturn->str_data, achFullPath );
            SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], pchReturn ); 
            bFoundOne = TRUE;
          }
        }
      }
      if ( bSetDir )
      {
        SetCurrentDirectory( achCurrentDir );
      }
    }
  }
  if ( !bFoundOne )
  {
    pchReturn = AllocateNewString( 0, true );
    SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], pchReturn ); 
  }
  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerFindFirstFile"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerFindNextFile

       DESCRIPTION:  continues a file find loop. assumes that the find handle
                     provided to it is a valid one.

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerFindNextFile( int iArgc )
{
  m_poInterpreter->SetLastCall( "FindNextFile" );

  char            achCurrentDir[MAX_PATH+1];
  char            achFullPath[MAX_PATH+1];
  char*           pchDirToScan;
  WIN32_FIND_DATA xFileInfo;
  HANDLE          hFind = NULL;
  vmstring*       pchReturn;
  BOOL            bFoundOne = FALSE;
  BOOL            bCanContinue = TRUE;
  BOOL            bSetDir      = FALSE;

  VerifyRunLineArguments( iArgc, 2 );
  VerifyElementType( 1, DT_FILEFINDHANDLE );
  VerifyElementType( 0, DT_STRING );

  hFind        = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_handle;
  pchDirToScan = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_string->str_data;

  if ( GetCurrentDirectory( MAX_PATH, achCurrentDir ) )
  {
    if ( 0 != strcmp( achCurrentDir, pchDirToScan ) )
    { 
       bCanContinue = bSetDir = SetCurrentDirectory( pchDirToScan );
    }

    if ( bCanContinue )
    {
      while( !bFoundOne && FindNextFile( hFind, &xFileInfo ) )
      {
        if ( xFileInfo.dwFileAttributes 
           & ( FILE_ATTRIBUTE_NORMAL | FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_ARCHIVE ) )
        {
          sprintf( achFullPath, "%s%s", pchDirToScan, xFileInfo.cFileName );
          pchReturn = AllocateNewString( strlen( achFullPath ), true );
          strcpy( pchReturn->str_data, achFullPath );
          SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], pchReturn ); 
          bFoundOne = TRUE;
        }
      }
      if ( bSetDir )
      {
        SetCurrentDirectory( achCurrentDir );
      }
    }
  }
  if ( !bFoundOne )
  {
    pchReturn = AllocateNewString( 0, true );
    SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], pchReturn ); 
  }

  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerFindNextFile"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerFindClose

       DESCRIPTION:  closes a find file handle

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerFindClose( int iArgc )
{
  m_poInterpreter->SetLastCall( "FindClose" );

  VerifyRunLineArguments( iArgc, 1 );
  VerifyElementType( 0, DT_FILEFINDHANDLE );

  HANDLE hFind = m_poVirtualChip->m_psStackPointer[0].v.v_handle;
  BOOL bReturn = FindClose( hFind );

  // send back the return code
  //
  SetValue( &m_poVirtualChip->m_psStackPointer[iArgc], bReturn );

  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerFindClose"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerRegistryVerifyPath

       DESCRIPTION:  verifies that the given path is present in the registry

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerRegistryVerifyPath( int iArgc )
{
  m_poInterpreter->SetLastCall( "RegVerifyPath" );

  char*  pchHive;
  char*  pchPath;
  char*  pchKeyName;
  bool   bReturnCode = FALSE;  // assume failure 

  VerifyRunLineArguments( iArgc, 2 );
  VerifyElementType( 1, DT_STRING );
  VerifyElementType( 0, DT_STRING );

  pchHive    = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_string->str_data;
  pchPath    = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_string->str_data;

  // These are the registry hives that this will open/access.
  // If the key type is NOT one of these, then nothing will happen.
  //
  // "HKLM" = HKEY_LOCAL_MACHINE
  // "HCLS" = HKEY_CLASSES_ROOT
  // "HUSR" = HKEY_USERS
  // "HCUR" = HKEY_CURRENT_USER
  // "HCFG" = HKEY_CURRENT_CONFIG
  //
  BOOL  bSetHive = FALSE;
  DWORD dwHive;

  if ( !strcmp( pchHive, "HKLM" ) )
  {
    bSetHive = TRUE;
    dwHive   = keyLocalMachine;
  }
  else
  if ( !strcmp( pchHive, "HCLS" ) )
  {
    bSetHive = TRUE;
    dwHive   = keyClassesRoot;
  }
  else
  if ( !strcmp( pchHive, "HUSR" ) )
  {
    bSetHive = TRUE;
    dwHive   = keyUsers;
  }
  else
  if ( !strcmp( pchHive, "HCUR" ) )
  {
    bSetHive = TRUE;
    dwHive   = keyCurrentUser;
  }
  else
  if ( !strcmp( pchHive, "HCFG" ) )
  {
    bSetHive = TRUE;
    dwHive   = keyCurrentConfiguration;
  }

  if ( bSetHive )
  {
    VMRegistry  oRegistry;
    oRegistry.Connect( (HKEY) dwHive );
    bReturnCode = oRegistry.Open( pchPath );
    oRegistry.Close();
  }

  // send back the return code
  //
  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], bReturnCode );

  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerRegistryVerifyPath"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerRegistryCreatePath

       DESCRIPTION:  creates a directory path

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerRegistryCreatePath( int iArgc )
{
  m_poInterpreter->SetLastCall( "RegCreatePath" );

  bool bCreated = false;  // assumes failure

  VerifyRunLineArguments( iArgc, 2 );
  VerifyElementType( 1, DT_STRING );
  VerifyElementType( 0, DT_STRING );

  char* pchHive    = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_string->str_data;
  char* pchPath    = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_string->str_data;
  
  VMTokenizer oTokens( pchPath, "\\" );

  // These are the registry hives that this will open/access.
  // If the key type is NOT one of these, then nothing will happen.
  //
  // "HKLM" = HKEY_LOCAL_MACHINE
  // "HCLS" = HKEY_CLASSES_ROOT
  // "HUSR" = HKEY_USERS
  // "HCUR" = HKEY_CURRENT_USER
  // "HCFG" = HKEY_CURRENT_CONFIG
  //
  BOOL  bSetHive = FALSE;
  DWORD dwHive;

  if ( !strcmp( pchHive, "HKLM" ) )
  {
    bSetHive = TRUE;
    dwHive   = keyLocalMachine;
  }
  else
  if ( !strcmp( pchHive, "HCLS" ) )
  {
    bSetHive = TRUE;
    dwHive   = keyClassesRoot;
  }
  else
  if ( !strcmp( pchHive, "HUSR" ) )
  {
    bSetHive = TRUE;
    dwHive   = keyUsers;
  }
  else
  if ( !strcmp( pchHive, "HCUR" ) )
  {
    bSetHive = TRUE;
    dwHive   = keyCurrentUser;
  }
  else
  if ( !strcmp( pchHive, "HCFG" ) )
  {
    bSetHive = TRUE;
    dwHive   = keyCurrentConfiguration;
  }

  if ( bSetHive )
  {
    VMRegistry  oRegistry;
    if ( oRegistry.Connect( (HKEY) dwHive ) )
    {
      int iLoop = 0;
      VMString oPath;

      while ( oTokens.HasMoreTokens() )
      {
        VMString oToken = oTokens.GetNextToken();

        oPath += oToken;        

        switch( iLoop )
        { 
          case 0:
            bCreated = oRegistry.Create( oToken.Buffer() );
          break;

          default:
            bCreated &= oRegistry.CreateNode( oToken.Buffer() );
          break;
        }
        bCreated &= oRegistry.Open( oPath.Buffer() );
        oPath += "\\";
        iLoop++;
      }
    }
  }

  // send back the return code
  //
  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], bCreated );

  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerRegistryCreatePath"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerRegistryStringWrite

       DESCRIPTION:  writes a string to a registry location. The location and
                     the value to write are inbound parameters

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerRegistryStringWrite( int iArgc )
{
  m_poInterpreter->SetLastCall( "RegWriteString" );

  char*  pchHive;
  char*  pchPath;
  char*  pchKeyName;
  char*  pchToWrite;
  bool   bWriteSuccess = false;  // assumes failure

  VerifyRunLineArguments( iArgc, 4 );
  VerifyElementType( 3, DT_STRING );
  VerifyElementType( 2, DT_STRING );
  VerifyElementType( 1, DT_STRING );
  VerifyElementType( 0, DT_STRING );

  pchHive    = m_poVirtualChip->m_psStackPointer[ 3 ].v.v_string->str_data;
  pchPath    = m_poVirtualChip->m_psStackPointer[ 2 ].v.v_string->str_data;
  pchKeyName = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_string->str_data;
  pchToWrite = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_string->str_data;

  // These are the registry hives that this will open/access.
  // If the key type is NOT one of these, then nothing will happen.
  //
  // "HKLM" = HKEY_LOCAL_MACHINE
  // "HCLS" = HKEY_CLASSES_ROOT
  // "HUSR" = HKEY_USERS
  // "HCUR" = HKEY_CURRENT_USER
  // "HCFG" = HKEY_CURRENT_CONFIG
  //
  BOOL  bSetHive = FALSE;
  DWORD dwHive;

  if ( !strcmp( pchHive, "HKLM" ) )
  {
    bSetHive = TRUE;
    dwHive   = keyLocalMachine;
  }
  else
  if ( !strcmp( pchHive, "HCLS" ) )
  {
    bSetHive = TRUE;
    dwHive   = keyClassesRoot;
  }
  else
  if ( !strcmp( pchHive, "HUSR" ) )
  {
    bSetHive = TRUE;
    dwHive   = keyUsers;
  }
  else
  if ( !strcmp( pchHive, "HCUR" ) )
  {
    bSetHive = TRUE;
    dwHive   = keyCurrentUser;
  }
  else
  if ( !strcmp( pchHive, "HCFG" ) )
  {
    bSetHive = TRUE;
    dwHive   = keyCurrentConfiguration;
  }

  // mjs to do....put in the code to write the value to the registry
  //
  if ( bSetHive )
  {
    VMRegistry  oRegistry;
    if ( oRegistry.Connect( (HKEY) dwHive ) )
    {
      if ( oRegistry.Open( pchPath ) )
      {
        VMString oValue = pchToWrite;
        bWriteSuccess   = oRegistry.SetValue( pchKeyName, oValue );
      }
      oRegistry.Flush();
      oRegistry.Close();
    }
  }
  // send back the return code
  //
  SetValue( &m_poVirtualChip->m_psStackPointer[iArgc], bWriteSuccess );

  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerRegistryStringWrite"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerRegistryStringRead

       DESCRIPTION:  reads a string from the given registry location

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerRegistryStringRead( int iArgc )
{
  m_poInterpreter->SetLastCall( "RegReadString" );

  unsigned long lSize = 255;
  char*  pchHive;
  char*  pchPath;
  char*  pchKeyName;
  char*  pchHostName = NULL;

  bool   bWorked     = false;

  if ( iArgc == 3 )
  {
    VerifyElementType( 2, DT_STRING );
    VerifyElementType( 1, DT_STRING );
    VerifyElementType( 0, DT_STRING );

    pchHive    = m_poVirtualChip->m_psStackPointer[ 2 ].v.v_string->str_data;
    pchPath    = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_string->str_data;
    pchKeyName = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_string->str_data;
  }
  else
  if ( iArgc == 4 )
  {
    VerifyElementType( 3, DT_STRING );
    VerifyElementType( 2, DT_STRING );
    VerifyElementType( 1, DT_STRING );
    VerifyElementType( 0, DT_STRING );

    pchHostName = m_poVirtualChip->m_psStackPointer[ 3 ].v.v_string->str_data;
    pchHive     = m_poVirtualChip->m_psStackPointer[ 2 ].v.v_string->str_data;
    pchPath     = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_string->str_data;
    pchKeyName  = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_string->str_data;
  }
  else
  {
    VerifyRunLineArguments( iArgc, 3 );
  }

  // These are the registry hives that this will open/access.
  // If the key type is NOT one of these, then nothing will happen.
  //
  // "HKLM" = HKEY_LOCAL_MACHINE
  // "HCLS" = HKEY_CLASSES_ROOT
  // "HUSR" = HKEY_USERS
  // "HCUR" = HKEY_CURRENT_USER
  // "HCFG" = HKEY_CURRENT_CONFIG
  //
  BOOL  bSetHive = FALSE;
  DWORD dwHive;

  if ( !strcmp( pchHive, "HKLM" ) )
  {
    bSetHive = TRUE;
    dwHive   = keyLocalMachine;
  }
  else
  if ( !strcmp( pchHive, "HCLS" ) )
  {
    bSetHive = TRUE;
    dwHive   = keyClassesRoot;
  }
  else
  if ( !strcmp( pchHive, "HUSR" ) )
  {
    bSetHive = TRUE;
    dwHive   = keyUsers;
  }
  else
  if ( !strcmp( pchHive, "HCUR" ) )
  {
    bSetHive = TRUE;
    dwHive   = keyCurrentUser;
  }
  else
  if ( !strcmp( pchHive, "HCFG" ) )
  {
    bSetHive = TRUE;
    dwHive   = keyCurrentConfiguration;
  }

  if ( bSetHive )
  {
    VMRegistry  oRegistry;
    if ( oRegistry.Connect( (HKEY) dwHive, pchHostName ) )
    {
      if ( oRegistry.Open( pchPath ) )
      {
        VMString oValue;
        if ( oRegistry.GetValue( pchKeyName, oValue ) )
        {
          vmstring*  pchRead = AllocateNewString( oValue.GetLength(), true );
          strcpy( pchRead->str_data, (const char*) oValue );
          SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], pchRead );
          bWorked = true;
        }
      }
      oRegistry.Close();
    }
  }   
  if ( !bWorked )
  {
    vmstring*  pchRead = AllocateNewString( 0, true );
    SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], pchRead );
  }
  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerRegistryStringRead"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerRegistryIntWrite

       DESCRIPTION:  writes an integer value to the given registry location

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerRegistryIntWrite( int iArgc )
{
  m_poInterpreter->SetLastCall( "RegWriteInt" );

  char*  pchHive;
  char*  pchPath;
  char*  pchKeyName;
  DWORD  dwToWrite;
  bool   bWriteSuccess = false; // assumes failure

  VerifyRunLineArguments( iArgc, 4 );
  VerifyElementType( 3, DT_STRING  );
  VerifyElementType( 2, DT_STRING  );
  VerifyElementType( 1, DT_STRING  );
  VerifyElementType( 0, DT_INTEGER );

  pchHive    = m_poVirtualChip->m_psStackPointer[ 3 ].v.v_string->str_data;
  pchPath    = m_poVirtualChip->m_psStackPointer[ 2 ].v.v_string->str_data;
  pchKeyName = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_string->str_data;
  dwToWrite  = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_integer;

  // These are the registry hives that this will open/access.
  // If the key type is NOT one of these, then nothing will happen.
  //
  // "HKLM" = HKEY_LOCAL_MACHINE
  // "HCLS" = HKEY_CLASSES_ROOT
  // "HUSR" = HKEY_USERS
  // "HCUR" = HKEY_CURRENT_USER
  // "HCFG" = HKEY_CURRENT_CONFIG
  //
  BOOL  bSetHive = FALSE;
  DWORD dwHive;

  if ( !strcmp( pchHive, "HKLM" ) )
  {
    bSetHive = TRUE;
    dwHive   = keyLocalMachine;
  }
  else
  if ( !strcmp( pchHive, "HCLS" ) )
  {
    bSetHive = TRUE;
    dwHive   = keyClassesRoot;
  }
  else
  if ( !strcmp( pchHive, "HUSR" ) )
  {
    bSetHive = TRUE;
    dwHive   = keyUsers;
  }
  else
  if ( !strcmp( pchHive, "HCUR" ) )
  {
    bSetHive = TRUE;
    dwHive   = keyCurrentUser;
  }
  else
  if ( !strcmp( pchHive, "HCFG" ) )
  {
    bSetHive = TRUE;
    dwHive   = keyCurrentConfiguration;
  }

  // mjs to do....put in the code to write the value to the registry
  //
  if ( bSetHive )
  {
    VMRegistry  oRegistry;
    if ( oRegistry.Connect( (HKEY) dwHive ) )
    {
      if ( oRegistry.Open( pchPath ) )
      {
        bWriteSuccess = oRegistry.SetValue( pchKeyName, dwToWrite );
      }
      oRegistry.Flush();
      oRegistry.Close();
    }
  }
  // send back the return code
  //
  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], bWriteSuccess );

  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerRegistryIntWrite"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerRegistryIntRead

       DESCRIPTION:  reads an integer value from the given registry location

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerRegistryIntRead( int iArgc )
{
  m_poInterpreter->SetLastCall( "RegReadInt" );

  char*  pchHive;
  char*  pchPath;
  char*  pchKeyName;
  char*  pchHostName;
  DWORD  dwRegValue = -99;  // an "error code"
  bool   bWorked    = false;

  if ( iArgc == 3 )
  {
    VerifyElementType( 2, DT_STRING );
    VerifyElementType( 1, DT_STRING );
    VerifyElementType( 0, DT_STRING );

    pchHostName = NULL;
    pchHive     = m_poVirtualChip->m_psStackPointer[ 2 ].v.v_string->str_data;
    pchPath     = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_string->str_data;
    pchKeyName  = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_string->str_data;
  }
  else
  if ( iArgc == 4 )
  {
    VerifyElementType( 3, DT_STRING );
    VerifyElementType( 2, DT_STRING );
    VerifyElementType( 1, DT_STRING );
    VerifyElementType( 0, DT_STRING );

    pchHostName = m_poVirtualChip->m_psStackPointer[ 3 ].v.v_string->str_data;
    pchHive     = m_poVirtualChip->m_psStackPointer[ 2 ].v.v_string->str_data;
    pchPath     = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_string->str_data;
    pchKeyName  = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_string->str_data;
  }
  else
  {
    VerifyRunLineArguments( iArgc, 3 );
  }

  // These are the registry hives that this will open/access.
  // If the key type is NOT one of these, then nothing will happen.
  //
  // "HKLM" = HKEY_LOCAL_MACHINE
  // "HCLS" = HKEY_CLASSES_ROOT
  // "HUSR" = HKEY_USERS
  // "HCUR" = HKEY_CURRENT_USER
  // "HCFG" = HKEY_CURRENT_CONFIG
  //
  BOOL  bSetHive = FALSE;
  DWORD dwHive;

  if ( !strcmp( pchHive, "HKLM" ) )
  {
    bSetHive = TRUE;
    dwHive   = keyLocalMachine;
  }
  else
  if ( !strcmp( pchHive, "HCLS" ) )
  {
    bSetHive = TRUE;
    dwHive   = keyClassesRoot;
  }
  else
  if ( !strcmp( pchHive, "HUSR" ) )
  {
    bSetHive = TRUE;
    dwHive   = keyUsers;
  }
  else
  if ( !strcmp( pchHive, "HCUR" ) )
  {
    bSetHive = TRUE;
    dwHive   = keyCurrentUser;
  }
  else
  if ( !strcmp( pchHive, "HCFG" ) )
  {
    bSetHive = TRUE;
    dwHive   = keyCurrentConfiguration;
  }

  // mjs to do....put in the code to write the value to the registry
  //
  if ( bSetHive )
  {
    VMRegistry  oRegistry;
    if ( oRegistry.Connect( (HKEY) dwHive, pchHostName ) )
    {
      if ( oRegistry.Open( pchPath ) )
      {
        if ( oRegistry.GetValue( pchKeyName, dwRegValue ) )
        {
          int iValue = dwRegValue;
          SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], iValue );
          bWorked = true;
        }
        oRegistry.Close();
      }
    }
  }
  if ( !bWorked )
  {
    SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], -1999999999 );
  }
  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerRegistryIntRead"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerGetTempDir

       DESCRIPTION:  gets the temporary directory for the caller

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int  VMVirtualOpSys::HandlerGetTempDir( int iArgc )
{
  m_poInterpreter->SetLastCall( "GetTempDir" );

  VerifyRunLineArguments( iArgc, 0 );

  char achPath[ _MAX_PATH + 1 ];

  GetTempPath( _MAX_PATH, achPath );

  vmstring* pxResult = AllocateNewString( strlen( achPath ), true );
  memset( pxResult->str_data, 0, strlen( achPath ) );
  strcpy( pxResult->str_data, achPath );

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], pxResult );

  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerGetTempDir"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerGetSystemDir

       DESCRIPTION:  gets the system directory for the caller

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int  VMVirtualOpSys::HandlerGetSystemDir( int iArgc )
{
  m_poInterpreter->SetLastCall( "GetSystemDir" );

  VerifyRunLineArguments( iArgc, 0 );

  char achPath[ _MAX_PATH + 1 ];

  GetSystemDirectory( achPath, _MAX_PATH );

  vmstring* pxResult = AllocateNewString( strlen( achPath ), true );
  memset( pxResult->str_data, 0, strlen( achPath ) );
  strcpy( pxResult->str_data, achPath );

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], pxResult );

  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerGetSystemDir"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerGetTempFileName

       DESCRIPTION:  generates a temp file name

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int  VMVirtualOpSys::HandlerGetTempFileName( int iArgc )
{
  m_poInterpreter->SetLastCall( "GetTempFileName" );

  VerifyRunLineArguments( iArgc, 0 );

  char achPath[ _MAX_PATH + 1 ];
  char achTempFile[ _MAX_PATH + 1 ];

  GetTempPath( _MAX_PATH, achPath );
  GetTempFileName( achPath, "TMP", 0, achTempFile );

  vmstring* pxResult = AllocateNewString( strlen( achTempFile ), true );
  memset( pxResult->str_data, 0, strlen( achTempFile ) );
  strcpy( pxResult->str_data, achTempFile );

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], pxResult );

  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerGetTempFileName"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerSplitPathForFileName

       DESCRIPTION:  splits given path for the file name part

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int  VMVirtualOpSys::HandlerSplitPathForFileName( int iArgc )
{
  m_poInterpreter->SetLastCall( "SplitPathForFileName" );

  VerifyRunLineArguments( iArgc, 1 );
  VerifyElementType( 0, DT_STRING );

  char* pchPath = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_string->str_data;

  char achDrive[ _MAX_DRIVE + 1 ];
  char achPath[ _MAX_PATH + 1 ];
  char achFile[ _MAX_PATH + 1 ];
  char achExt[ _MAX_EXT + 1 ];

  _splitpath( pchPath, achDrive, achPath, achFile, achExt );

  vmstring* pxResult = AllocateNewString( strlen( achFile ), true );
  memset( pxResult->str_data, 0, strlen( achFile ) );
  strcpy( pxResult->str_data, achFile );

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], pxResult );

  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerSplitPathForFileName"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerGetShortPath

       DESCRIPTION:  splits given path for the file path part

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int  VMVirtualOpSys::HandlerGetShortPath( int iArgc )
{
  m_poInterpreter->SetLastCall( "GetAsShortPath" );

  VerifyRunLineArguments( iArgc, 1 );
  VerifyElementType( 0, DT_STRING );

  char* pchPath = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_string->str_data;

  char achShortPath[ _MAX_PATH + 1 ];
  GetShortPathName( pchPath, achShortPath, _MAX_PATH );

  vmstring* pxResult = AllocateNewString( strlen( achShortPath ), true );
  memset( pxResult->str_data, 0, strlen( achShortPath ) );
  strcpy( pxResult->str_data, achShortPath );

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], pxResult );

  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerGetShortPath"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerGetLongPath

       DESCRIPTION:  splits given path for the file path part

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int  VMVirtualOpSys::HandlerGetLongPath( int iArgc )
{
  m_poInterpreter->SetLastCall( "GetAsLongPath" );

  VerifyRunLineArguments( iArgc, 1 );
  VerifyElementType( 0, DT_STRING );

  char* pchPath = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_string->str_data;

  char achLongPath[ _MAX_PATH + 1 ];
  GetLongPathName( pchPath, achLongPath, _MAX_PATH );

  vmstring* pxResult = AllocateNewString( strlen( achLongPath ), true );
  memset( pxResult->str_data, 0, strlen( achLongPath ) );
  strcpy( pxResult->str_data, achLongPath );

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], pxResult );

  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerGetLongPath"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerSplitPathForPathPart

       DESCRIPTION:  splits given path for the file path part

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int  VMVirtualOpSys::HandlerSplitPathForPathPart( int iArgc )
{
  m_poInterpreter->SetLastCall( "SplitPathForPathPart" );

  VerifyRunLineArguments( iArgc, 1 );
  VerifyElementType( 0, DT_STRING );

  char* pchPath = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_string->str_data;

  char achDrive[ _MAX_DRIVE + 1 ];
  char achPath[ _MAX_PATH + 1 ];
  char achFile[ _MAX_PATH + 1 ];
  char achExt[ _MAX_EXT + 1 ];

  _splitpath( pchPath, achDrive, achPath, achFile, achExt );

  char achLongPath[ _MAX_PATH + 1 ];
  GetLongPathName( achPath, achLongPath, _MAX_PATH );

  vmstring* pxResult = AllocateNewString( strlen( achLongPath ), true );
  memset( pxResult->str_data, 0, strlen( achLongPath ) );
  strcpy( pxResult->str_data, achLongPath );

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], pxResult );

  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerSplitPathForPathPart"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerSplitPathForExtPart

       DESCRIPTION:  splits given path for the file extension part

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int  VMVirtualOpSys::HandlerSplitPathForExtPart( int iArgc )
{
  m_poInterpreter->SetLastCall( "SplitPathForExtPart" );

  VerifyRunLineArguments( iArgc, 1 );
  VerifyElementType( 0, DT_STRING );

  char* pchPath = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_string->str_data;

  char achDrive[ _MAX_DRIVE + 1 ];
  char achPath[ _MAX_PATH + 1 ];
  char achFile[ _MAX_PATH + 1 ];
  char achExt[ _MAX_EXT + 1 ];

  _splitpath( pchPath, achDrive, achPath, achFile, achExt );

  vmstring* pxResult = AllocateNewString( strlen( achExt ), true );
  memset( pxResult->str_data, 0, strlen( achExt ) );
  strcpy( pxResult->str_data, achExt );

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], pxResult );

  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerSplitPathForExtPart"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerSplitPathForDriveName

       DESCRIPTION:  splits given path for the file drive part

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int  VMVirtualOpSys::HandlerSplitPathForDriveName( int iArgc )
{
  m_poInterpreter->SetLastCall( "SplitPathForDriveName" );

  VerifyRunLineArguments( iArgc, 1 );
  VerifyElementType( 0, DT_STRING );

  char* pchPath = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_string->str_data;

  char achDrive[ _MAX_DRIVE + 1 ];
  char achPath[ _MAX_PATH + 1 ];
  char achFile[ _MAX_PATH + 1 ];
  char achExt[ _MAX_EXT + 1 ];

  _splitpath( pchPath, achDrive, achPath, achFile, achExt );

  vmstring* pxResult = AllocateNewString( strlen( achDrive ), true );
  memset( pxResult->str_data, 0, strlen( achDrive ) );
  strcpy( pxResult->str_data, achDrive );

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], pxResult );

  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerSplitPathForDriveName"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerOpenZipFile

       DESCRIPTION:  attaches a zip wrapper object to a file

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int  VMVirtualOpSys::HandlerOpenZipFile( int iArgc )
{
  m_poInterpreter->SetLastCall( "OpenZipFile" );

  VerifyRunLineArguments( iArgc, 2 );
  VerifyElementType( 0, DT_STRING );

  char* pchFile = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_string->str_data;

  if ( m_poVirtualChip->m_psStackPointer[ 1 ].v_type == DT_UNZIPPER )
  {
     m_poVirtualChip->m_psStackPointer[ 1 ].v.v_unzipper->OpenZip( pchFile );
  }
  else
  if ( m_poVirtualChip->m_psStackPointer[ 1 ].v_type == DT_ZIPMAKER )
  {
     m_poVirtualChip->m_psStackPointer[ 1 ].v.v_zipmaker->OpenZip( pchFile );
  }
  else
  {
    VerifyElementType( 1, DT_UNZIPPER );
  }

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], true );
  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerOpenZipFile"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerZipFileClose

       DESCRIPTION:  detaches a zip wrapper object from a file

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int  VMVirtualOpSys::HandlerZipFileClose( int iArgc )
{
  m_poInterpreter->SetLastCall( "ZipFileClose" );

  VerifyRunLineArguments( iArgc, 1 );

  if ( m_poVirtualChip->m_psStackPointer[ 0 ].v_type == DT_UNZIPPER )
  {
     m_poVirtualChip->m_psStackPointer[ 0 ].v.v_unzipper->CloseZip();
  }
  else
  if ( m_poVirtualChip->m_psStackPointer[ 0 ].v_type == DT_ZIPMAKER )
  {
     m_poVirtualChip->m_psStackPointer[ 0 ].v.v_zipmaker->CloseZip();
  }
  else
  {
    VerifyElementType( 0, DT_UNZIPPER );
  }

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], true );
  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerZipFileClose"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerExtractAllFromZipFile

       DESCRIPTION:  unzips all contents of a zip file

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int  VMVirtualOpSys::HandlerExtractAllFromZipFile( int iArgc )
{
  m_poInterpreter->SetLastCall( "ExtractAllFromZipFile" );

  VerifyRunLineArguments( iArgc, 3 );
  VerifyElementType( 2, DT_UNZIPPER );
  VerifyElementType( 1, DT_STRING   );
  VerifyElementType( 0, DT_BYTE     );

  char* pchPath     = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_string->str_data;
  bool  bIgnorePath = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_byte;

  m_poVirtualChip->m_psStackPointer[ 2 ].v.v_unzipper->UnzipTo( pchPath, bIgnorePath );

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], true );
  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerExtractAllFromZipFile"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerExtractOneFromZipFile

       DESCRIPTION:  unzips a single file from a zip file

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int  VMVirtualOpSys::HandlerExtractOneFromZipFile( int iArgc )
{
  m_poInterpreter->SetLastCall( "UnZipExtractFile" );

  VerifyRunLineArguments( iArgc, 4 );
  VerifyElementType( 3, DT_UNZIPPER );
  VerifyElementType( 2, DT_STRING   );
  VerifyElementType( 1, DT_STRING   );
  VerifyElementType( 0, DT_BYTE     );

  char* pchFile     = m_poVirtualChip->m_psStackPointer[ 2 ].v.v_string->str_data;
  char* pchPath     = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_string->str_data;
  bool  bIgnorePath = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_byte;

  VMUnzipper* poZip = m_poVirtualChip->m_psStackPointer[ 3 ].v.v_unzipper;

  int   iFileCount = poZip->GetFileCount();
  for ( int iLoop = 0; iLoop < iFileCount; iLoop++ )
  {
    VMUnzipFileInfo xInfo;
    poZip->GetFileInfo( iLoop, xInfo );
    if ( 0 == strcmp( xInfo.szFileName, pchFile ) )
    {
      poZip->UnzipFile( pchPath, bIgnorePath );
      break;
    }
  } 

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], true );
  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerExtractOneFromZipFile"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerDoesZipContainFile

       DESCRIPTION:  determines if a zip file contains a specific file

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int  VMVirtualOpSys::HandlerDoesZipContainFile( int iArgc )
{
  m_poInterpreter->SetLastCall( "DoesZipContainFile" );

  VerifyRunLineArguments( iArgc, 2 );
  VerifyElementType( 1, DT_UNZIPPER );
  VerifyElementType( 0, DT_STRING   );

  char* pchFile     = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_string->str_data;
  VMUnzipper* poZip = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_unzipper;

  int   iFileCount = poZip->GetFileCount();
  bool  bResult    = false;

  for ( int iLoop = 0; iLoop < iFileCount; iLoop++ )
  {
    VMUnzipFileInfo xInfo;
    poZip->GetFileInfo( iLoop, xInfo );
    if ( 0 == strcmp( xInfo.szFileName, pchFile ) )
    {
      bResult = true;
      break;
    }
  } 

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], bResult );
  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerDoesZipContainFile"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerGetZipFileFileCount

       DESCRIPTION:  counts the files in a zip file

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int  VMVirtualOpSys::HandlerGetZipFileFileCount( int iArgc )
{
  m_poInterpreter->SetLastCall( "GetZipFileFileCount" );

  VerifyRunLineArguments( iArgc, 1 );
  VerifyElementType( 0, DT_UNZIPPER );

  VMUnzipper* poZip = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_unzipper;

  int   iFileCount = poZip->GetFileCount();

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], iFileCount );
  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerGetZipFileFileCount"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerUnzipFileToString

       DESCRIPTION:  unzips a single file from a zip file to a string

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int  VMVirtualOpSys::HandlerUnzipFileToString( int iArgc )
{
  m_poInterpreter->SetLastCall( "UnzipFileToString" );

  VerifyRunLineArguments( iArgc, 2 );
  VerifyElementType( 1, DT_UNZIPPER );
  VerifyElementType( 0, DT_STRING   );

  char* pchBuffer   = NULL;
  char* pchFile     = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_string->str_data;
  VMUnzipper* poZip = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_unzipper;
  int iFileCount    = poZip->GetFileCount();

  for ( int iLoop = 0; iLoop < iFileCount; iLoop++ )
  {
    VMUnzipFileInfo xInfo;
    poZip->GetFileInfo( iLoop, xInfo );
    if ( 0 == strcmp( xInfo.szFileName, pchFile ) )
    {
      pchBuffer = new char[ xInfo.dwUncompressedSize + 1 ];
      memset( pchBuffer, 0, xInfo.dwUncompressedSize + 1 );

      poZip->UnZipFileDataToBuffer( xInfo, pchBuffer, xInfo.dwUncompressedSize );
      break;
    }
  } 

  if ( NULL == pchBuffer )
  {
    pchBuffer = new char;
    *pchBuffer = 0;
  }

  vmstring* pxResult = AllocateNewString( strlen( pchBuffer ), true );
  memset( pxResult->str_data, 0, strlen( pchBuffer ) );
  strcpy( pxResult->str_data, pchBuffer );

  delete [] pchBuffer;

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], pxResult );

  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerUnzipFileToString"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerUnzipFileToByteArray

       DESCRIPTION:  unzips a single file from a zip file to a byte array

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int  VMVirtualOpSys::HandlerUnzipFileToByteArray( int iArgc )
{
  m_poInterpreter->SetLastCall( "UnzipFileToByteArray" );

  VerifyRunLineArguments( iArgc, 2 );
  VerifyElementType( 1, DT_UNZIPPER );
  VerifyElementType( 0, DT_STRING   );

  char* pchBuffer   = NULL;
  char* pchFile     = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_string->str_data;
  VMUnzipper* poZip = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_unzipper;
  int iFileCount    = poZip->GetFileCount();

  int iSize         = 0;
  for ( int iLoop = 0; iLoop < iFileCount; iLoop++ )
  {
    VMUnzipFileInfo xInfo;
    poZip->GetFileInfo( iLoop, xInfo );
    if ( 0 == strcmp( xInfo.szFileName, pchFile ) )
    {
      iSize = xInfo.dwUncompressedSize;
      pchBuffer = new char[ xInfo.dwUncompressedSize ];
      memset( pchBuffer, 0, xInfo.dwUncompressedSize );

      poZip->UnZipFileDataToBuffer( xInfo, pchBuffer, xInfo.dwUncompressedSize );
      break;
    }
  } 

  if ( NULL == pchBuffer )
  {
    pchBuffer = new char;
    *pchBuffer = 0;
  }

  // make a byte array to return to the caller
  //
  VMByteArray* poBytes     = new VMByteArray( pchBuffer, iSize );
  VMTrackedAllocs* poAlloc = new VMTrackedAllocs;
  poAlloc->v.v_bytearray   = poBytes;
  poAlloc->v_type          = DT_BYTEARRAY;
  m_oTrackedAllocs.push_back( poAlloc );

  delete [] pchBuffer;

  set_bytearray( &m_poVirtualChip->m_psStackPointer[ iArgc ], poBytes );

  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerUnzipFileToByteArray"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerGetFileListFromZipFile

       DESCRIPTION:  unzips a single file from a zip file

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int  VMVirtualOpSys::HandlerGetFileListFromZipFile( int iArgc )
{
  m_poInterpreter->SetLastCall( "HandlerGetFileListFromZipFile" );

  VerifyRunLineArguments( iArgc, 1 );
  VerifyElementType( 0, DT_UNZIPPER );

  // make a vector to return all the match strings to the caller
  //
  VMDataVector* poVector   = new VMDataVector;
  VMTrackedAllocs* poAlloc = new VMTrackedAllocs;
  poAlloc->v.v_uservector  = poVector;
  poAlloc->v_type          = DT_USERVECTOR;
  m_oTrackedAllocs.push_back( poAlloc );

  VMUnzipper* poZip = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_unzipper;

  int iFileCount    = poZip->GetFileCount();

  for ( int iLoop = 0; iLoop < iFileCount; iLoop++ )
  {
    VMUnzipFileInfo xInfo;
    VMVariant       oNewItem;

    oNewItem.v_type = DT_STRING;
    poZip->GetFileInfo( iLoop, xInfo );

    vmstring* pxResult = AllocateNewString( strlen( xInfo.szFileName ) + 1, true );
    
    strcpy( pxResult->str_data, xInfo.szFileName );
    oNewItem.v.v_string = pxResult;

    poVector->Append( oNewItem );
  } 

  set_uservector( &m_poVirtualChip->m_psStackPointer[ iArgc ], poVector );

  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerGetFileListFromZipFile"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerAddFileToZip

       DESCRIPTION:  adds a single file to a zip file

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int  VMVirtualOpSys::HandlerAddFileToZip( int iArgc )
{
  m_poInterpreter->SetLastCall( "AddFileToZip" );

  VerifyRunLineArguments( iArgc, 3 );
  VerifyElementType( 2, DT_ZIPMAKER );
  VerifyElementType( 1, DT_STRING   );
  VerifyElementType( 0, DT_BYTE     );
  
  VMZipper*  poZip = m_poVirtualChip->m_psStackPointer[ 2 ].v.v_zipmaker;
  char*    pchFile = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_string->str_data;
  bool bIgnorePath = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_byte;

  bool bResult = poZip->AddFileToZip( pchFile, bIgnorePath );

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], bResult );

  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerAddFileToZip"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerAddFolderToZip

       DESCRIPTION:  adds a single file to a zip file

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int  VMVirtualOpSys::HandlerAddFolderToZip( int iArgc )
{
  m_poInterpreter->SetLastCall( "AddFolderToZip" );

  VerifyRunLineArguments( iArgc, 3 );
  VerifyElementType( 2, DT_ZIPMAKER );
  VerifyElementType( 1, DT_STRING   );
  VerifyElementType( 0, DT_BYTE     );
  
  VMZipper*  poZip = m_poVirtualChip->m_psStackPointer[ 2 ].v.v_zipmaker;
  char*    pchPath = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_string->str_data;
  bool bIgnorePath = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_byte;

  bool bResult = poZip->AddFolderToZip( pchPath, bIgnorePath );

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], bResult );

  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerAddFolderToZip"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerPutFileInZipAtPath

       DESCRIPTION:  adds a single file to a zip file

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int  VMVirtualOpSys::HandlerPutFileInZipAtPath( int iArgc )
{
  m_poInterpreter->SetLastCall( "PutFileInZipAtPath" );

  VerifyRunLineArguments( iArgc, 3 );
  VerifyElementType( 2, DT_ZIPMAKER );
  VerifyElementType( 1, DT_STRING   );
  VerifyElementType( 0, DT_STRING   );
  
  VMZipper*  poZip = m_poVirtualChip->m_psStackPointer[ 2 ].v.v_zipmaker;
  char*    pchFile = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_string->str_data;
  char*    pchPath = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_string->str_data;

  bool bResult = poZip->AddFileToZip( pchFile, pchPath );

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], bResult );

  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerPutFileInZipAtPath"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerEnumerateServers

       DESCRIPTION:  enumerates all the servers found on the network of the
                     requested type

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int  VMVirtualOpSys::HandlerEnumerateServers( int iArgc )
{
  m_poInterpreter->SetLastCall( "EnumerateServers" );

  VerifyRunLineArguments( iArgc, 1 );
  VerifyElementType( 0, DT_INTEGER );

  // make a vector to return all the match strings to the caller
  //
  VMDataVector* poVector   = new VMDataVector;
  VMTrackedAllocs* poAlloc = new VMTrackedAllocs;
  poAlloc->v.v_uservector  = poVector;
  poAlloc->v_type          = DT_USERVECTOR;
  m_oTrackedAllocs.push_back( poAlloc );

  int iServerType = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_integer;

/*
  following is from system include file: LMSERVER.H and/or SVRAPI.H

#define SV_TYPE_WORKSTATION         0x00000001  1
#define SV_TYPE_SERVER              0x00000002  2
#define SV_TYPE_SQLSERVER           0x00000004  4
#define SV_TYPE_DOMAIN_CTRL         0x00000008  8
#define SV_TYPE_DOMAIN_BAKCTRL      0x00000010  16
#define SV_TYPE_TIME_SOURCE         0x00000020  32
#define SV_TYPE_AFP                 0x00000040  64
#define SV_TYPE_NOVELL              0x00000080  128
#define SV_TYPE_DOMAIN_MEMBER       0x00000100  256
#define SV_TYPE_PRINTQ_SERVER       0x00000200  512
#define SV_TYPE_DIALIN_SERVER       0x00000400  1024
#define SV_TYPE_XENIX_SERVER        0x00000800  2048
#define SV_TYPE_SERVER_UNIX         SV_TYPE_XENIX_SERVER
#define SV_TYPE_NT                  0x00001000  4096
#define SV_TYPE_WFW                 0x00002000  8092
#define SV_TYPE_SERVER_MFPN         0x00004000  16184
#define SV_TYPE_SERVER_NT           0x00008000  32368
#define SV_TYPE_POTENTIAL_BROWSER   0x00010000  64736
#define SV_TYPE_BACKUP_BROWSER      0x00020000  129472
#define SV_TYPE_MASTER_BROWSER      0x00040000  258944
#define SV_TYPE_DOMAIN_MASTER       0x00080000  517888
#define SV_TYPE_SERVER_OSF          0x00100000  1035776
#define SV_TYPE_SERVER_VMS          0x00200000  2071552
#define SV_TYPE_WINDOWS             0x00400000  4143104     /* Windows95 and above * /
#define SV_TYPE_DFS                 0x00800000  8286208     /* Root of a DFS tree * /
#define SV_TYPE_CLUSTER_NT          0x01000000  16572416    /* NT Cluster * /
#define SV_TYPE_DCE                 0x10000000  33144832    /* IBM DSS (Directory and Security Services) or equivalent * /
#define SV_TYPE_ALTERNATE_XPORT     0x20000000  66289664    /* return list for alternate transport * /
#define SV_TYPE_LOCAL_LIST_ONLY     0x40000000  132579328   /* Return local list only * /
#define SV_TYPE_DOMAIN_ENUM         0x80000000  265158656
#define SV_TYPE_ALL                 0xFFFFFFFF  4294967295  /* handy for NetServerEnum2 * /
*/


  LPSERVER_INFO_101 pTmpBuf;
  LPSERVER_INFO_101 pBuf           = NULL;
  DWORD             dwLevel        = 101;
  DWORD             dwPrefMaxLen   = -1;
  DWORD             dwEntriesRead  = 0;
  DWORD             dwTotalEntries = 0;
  DWORD             dwTotalCount   = 0;
  DWORD             dwServerType   = iServerType;
  DWORD             dwResumeHandle = 0;
#ifdef VC_60_BUILD
  LPTSTR            pszServerName  = NULL;
#else
  LPCWSTR           pszServerName  = NULL;
#endif
  DWORD             i;
  NET_API_STATUS    nStatus;

  // Call the NetServerEnum function to retrieve information
  //  for all servers, specifying information level 101.
  //
  nStatus = NetServerEnum( pszServerName,
                           dwLevel,
                           (LPBYTE*) &pBuf,
                           dwPrefMaxLen,
                           &dwEntriesRead,
                           &dwTotalEntries,
                           dwServerType,
                           NULL,
                           &dwResumeHandle );

  // If the call succeeds,
  //
  if ( ( nStatus == NERR_Success ) || ( nStatus == ERROR_MORE_DATA ) )
  {
    if ( ( pTmpBuf = pBuf ) != NULL )
    {
      // Loop through the entries and 
      //  print the data for all server types.
      //
      for ( i = 0; i < dwEntriesRead; i++ )
      {
        assert( pTmpBuf != NULL );

        if ( pTmpBuf == NULL )
        {
          break;
        }

        VMVariant oNewItem;

        char  achServerName[ 255 ];
        char  chNull = 0;
        BOOL  bIgnored;

        memset( achServerName, 0, 255 );

        WideCharToMultiByte( CP_ACP, 
                             0, 
                             (const unsigned short*)pTmpBuf->sv101_name, 
                             -1,
                             achServerName,
                             254,
                             &chNull,
                             &bIgnored );

        vmstring* pxResult = AllocateNewString( strlen( achServerName ) + 1, true );
    
        strcpy( pxResult->str_data, achServerName );

        oNewItem.v_type     = DT_STRING;
        oNewItem.v.v_string = pxResult;

        poVector->Append( oNewItem );

        pTmpBuf++;
        dwTotalCount++;
      }
    }
  }

  // Free the allocated buffer.
  //
  if ( pBuf != NULL )
  {
    NetApiBufferFree( pBuf );
  }

  set_uservector( &m_poVirtualChip->m_psStackPointer[ iArgc ], poVector );

  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerEnumerateServers"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerMessageBox

       DESCRIPTION:  put a modal message box

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerMessageBox( int iArgc )
{
  m_poInterpreter->SetLastCall( "MessageBox" );

  // The following table represents the possible different
  // return values from message box. These return codes are 
  // what M'soft returns, our function just forwards that 
  // return value....
  //
  //=================================================
  // ButtonSet            ButtonHit      ReturnValue
  //=================================================
  // "AbortRetryIgnore"    Abort             3
  //                       Retry             4
  //                       Ignore            5
  //-------------------------------------------------
  // "OkOnly"              Okay              1
  //-------------------------------------------------
  // "OKCancel"            Okay              1
  //                       Cancel            2
  //-------------------------------------------------
  // "RetryCancel"         Retry             4
  //                       Cancel            2
  //-------------------------------------------------
  // "YesNo"               Yes               6
  //                       No                7
  //-------------------------------------------------
  // "YesNoCancel"         Yes               6
  //                       No                7
  //                       Cancel            2
  //=================================================
  // SUMMARY EVALUATION:
  //                       Okay              1
  //                       Cancel            2
  //                       Abort             3
  //                       Retry             4
  //                       Ignore            5
  //                       Yes               6
  //                       No                7
  //=================================================

  char* pchMessage;
  char* pchCaption;
  char* pchButtons;
  char* pchIcon;
  int   iFlags = 0;
   
  VerifyRunLineArguments( iArgc, 4 );
  VerifyElementType( 3, DT_STRING );
  VerifyElementType( 2, DT_STRING );
  VerifyElementType( 1, DT_STRING );
  VerifyElementType( 0, DT_STRING );

  pchMessage = m_poVirtualChip->m_psStackPointer[ 3 ].v.v_string->str_data;
  pchCaption = m_poVirtualChip->m_psStackPointer[ 2 ].v.v_string->str_data;
  pchButtons = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_string->str_data;
  pchIcon    = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_string->str_data;

  if ( !strcmp( pchButtons, "AbortRetryIgnore" ) )
  {
    iFlags |= MB_ABORTRETRYIGNORE;
  }
  else
  if ( !strcmp( pchButtons, "OkOnly" ) )
  {
    iFlags |= MB_OK;
  }
  else
  if ( !strcmp( pchButtons, "OKCancel" ) )
  {
    iFlags |= MB_OKCANCEL;
  }
  else
  if ( !strcmp( pchButtons, "RetryCancel" ) )
  {
    iFlags |= MB_RETRYCANCEL;
  }
  else
  if ( !strcmp( pchButtons, "YesNo" ) )
  {
    iFlags |= MB_YESNO;
  }
  else
  if ( !strcmp( pchButtons, "YesNoCancel" ) )
  {
    iFlags |= MB_YESNOCANCEL;
  }
  else
  {
    iFlags |= MB_OK;
  }

  if ( !strcmp( pchIcon, "Stop" ) )
  {
    iFlags |= MB_ICONSTOP;
  }
  else
  if ( !strcmp( pchIcon, "Warning" ) )
  {
    iFlags |= MB_ICONWARNING;
  }
  else
  if ( !strcmp( pchIcon, "Info" ) )
  {
    iFlags |= MB_ICONASTERISK;
  }
  else
  if ( !strcmp( pchIcon, "Question" ) )
  {
    iFlags |= MB_ICONQUESTION;
  }
  else
  {
    iFlags |= MB_ICONASTERISK;
  }

  // send back the return code
  //
  long lReturn = MessageBox( NULL, pchMessage, pchCaption, iFlags );

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], lReturn );

  m_poVirtualChip->m_psStackPointer += iArgc;

  return 0;
}
/* End of function "VMVirtualOpSys::HandlerMessageBox"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerTimeOutMessageBox

       DESCRIPTION:  put a modal message box

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerTimeOutMessageBox( int iArgc )
{
  m_poInterpreter->SetLastCall( "TimeoutMessageBox" );

  char* pchMessage;
  char* pchCaption;
  char* pchButtons;
  char* pchIcon;
  char* pchDefault;
  int   iFlags   = 0;
  int   iDefault = 0;
  int   iTimeOut = 0;
   
  VerifyRunLineArguments( iArgc, 6 );
  VerifyElementType( 5, DT_STRING );
  VerifyElementType( 4, DT_STRING );
  VerifyElementType( 3, DT_STRING );
  VerifyElementType( 2, DT_STRING );
  VerifyElementType( 1, DT_STRING );
  VerifyElementType( 0, DT_INTEGER );

  pchMessage = m_poVirtualChip->m_psStackPointer[ 5 ].v.v_string->str_data;
  pchCaption = m_poVirtualChip->m_psStackPointer[ 4 ].v.v_string->str_data;
  pchButtons = m_poVirtualChip->m_psStackPointer[ 3 ].v.v_string->str_data;
  pchIcon    = m_poVirtualChip->m_psStackPointer[ 2 ].v.v_string->str_data;
  pchDefault = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_string->str_data;

  if ( !strcmp( pchButtons, "AbortRetryIgnore" ) )
  {
    iFlags |= MB_ABORTRETRYIGNORE;
  }
  else
  if ( !strcmp( pchButtons, "OkOnly" ) )
  {
    iFlags |= MB_OK;
  }
  else
  if ( !strcmp( pchButtons, "OKCancel" ) )
  {
    iFlags |= MB_OKCANCEL;
  }
  else
  if ( !strcmp( pchButtons, "RetryCancel" ) )
  {
    iFlags |= MB_RETRYCANCEL;
  }
  else
  if ( !strcmp( pchButtons, "YesNo" ) )
  {
    iFlags |= MB_YESNO;
  }
  else
  if ( !strcmp( pchButtons, "YesNoCancel" ) )
  {
    iFlags |= MB_YESNOCANCEL;
  }
  else
  {
    iFlags |= MB_OK;
  }

  if ( !strcmp( pchIcon, "Stop" ) )
  {
    iFlags |= MB_ICONSTOP;
  }
  else
  if ( !strcmp( pchIcon, "Warning" ) )
  {
    iFlags |= MB_ICONWARNING;
  }
  else
  if ( !strcmp( pchIcon, "Info" ) )
  {
    iFlags |= MB_ICONASTERISK;
  }
  else
  if ( !strcmp( pchIcon, "Question" ) )
  {
    iFlags |= MB_ICONQUESTION;
  }
  else
  {
    iFlags |= MB_ICONASTERISK;
  }

  if ( !strcmp( pchDefault, "Abort" ) )
  {
    iDefault |= IDABORT;
  }
  else
  if ( !strcmp( pchDefault, "Cancel" ) )
  {
    iDefault |= IDCANCEL;
  }
  else
  if ( !strcmp( pchDefault, "Ignore" ) )
  {
    iDefault |= IDIGNORE;
  }
  else
  if ( !strcmp( pchDefault, "No" ) )
  {
    iDefault |= IDNO;
  }
  else
  if ( !strcmp( pchDefault, "Ok" ) )
  {
    iDefault |= IDOK;
  }
  else
  if ( !strcmp( pchDefault, "Retry" ) )
  {
    iDefault |= IDRETRY;
  }
  else
  {
    iDefault |= IDYES;
  }

  iTimeOut = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_integer;

  VMTimeOutMsgBox oWaitMsg( pchMessage,  // message
                            pchCaption,  // caption
                            iFlags,      // style 
                            iDefault,    // Default button
                            iTimeOut );  // Timeout Value in milliseconds

  // capture the return code
  //
  long lReturn = oWaitMsg.DoModal();

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], lReturn );

  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerTimeOutMessageBox"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerGetHost

       DESCRIPTION:  returns the name of the computer running this

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerGetHostName( int iArgc )
{
  m_poInterpreter->SetLastCall( "GetHostName" );

  VerifyRunLineArguments( iArgc, 0 );

  unsigned long lSize = MAX_COMPUTERNAME_LENGTH;
  char          achHost[ MAX_COMPUTERNAME_LENGTH + 1 ];
  GetComputerName( achHost, &lSize );

  vmstring*  pchHost = AllocateNewString( lSize + 1, true );
  strcpy( pchHost->str_data, achHost );

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], pchHost );
  m_poVirtualChip->m_psStackPointer += iArgc;

  return 0;
}
/* End of function "VMVirtualOpSys::HandlerGetHost"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerSqlLite2Open

       DESCRIPTION:  open/create a mini (sql lite) database file

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerSqlLite2Open( int iArgc )
{
  m_poInterpreter->SetLastCall( "SqlLite2Open" );

  VerifyRunLineArguments( iArgc, 2 );
  VerifyElementType( 1, DT_SQLLITE_2_DB );
  VerifyElementType( 0, DT_STRING       );
  
  VMSqlLiteDatabase* poMiniDB = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_sqllite2db;
  char*              pchFile  = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_string->str_data;
  VMString           oFile;
  oFile = pchFile;

  bool bResult = poMiniDB->Open( oFile );

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], bResult );
  m_poVirtualChip->m_psStackPointer += iArgc;

  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerSqlLite2Open"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerSqlLite3Open

       DESCRIPTION:  open/create a mini (sql lite) database file

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerSqlLite3Open( int iArgc )
{
  m_poInterpreter->SetLastCall( "SqlLite3Open" );

  VerifyRunLineArguments( iArgc, 2 );
  VerifyElementType( 1, DT_SQLLITE_3_DB );
  VerifyElementType( 0, DT_STRING       );
  
  VMSqlite3xDatabase* poMiniDB = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_sqllite3db;
  char*               pchFile  = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_string->str_data;

  bool bResult;
  try
  {
    poMiniDB->Open( pchFile );
    bResult = true;
  }
  catch( VMSqlite3xException oEx )
  {
    bResult = false;
  }
  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], bResult );
  m_poVirtualChip->m_psStackPointer += iArgc;

  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerSqlLite3Open"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerSqlLite2Close

       DESCRIPTION:  close a mini (sql lite) database file

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerSqlLite2Close( int iArgc )
{
  m_poInterpreter->SetLastCall( "SqlLite2Close" );

  VerifyRunLineArguments( iArgc, 1 );
  VerifyElementType( 0, DT_SQLLITE_2_DB );
  
  VMSqlLiteDatabase* poMiniDB = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_sqllite2db;

  bool bResult = poMiniDB->Close();

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], bResult );
  m_poVirtualChip->m_psStackPointer += iArgc;

  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerSqlLite2Close"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerSqlLite3Close

       DESCRIPTION:  close a mini (sql lite) database file

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerSqlLite3Close( int iArgc )
{
  m_poInterpreter->SetLastCall( "SqlLite3Close" );

  VerifyRunLineArguments( iArgc, 1 );
  VerifyElementType( 0, DT_SQLLITE_3_DB );
  
  VMSqlite3xDatabase* poMiniDB = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_sqllite3db;

  poMiniDB->Close();

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], true );
  m_poVirtualChip->m_psStackPointer += iArgc;

  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerSqlLite2Close"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerSqlLite2IsGood

       DESCRIPTION:  close a mini (sql lite) database file

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerSqlLite2IsGood( int iArgc )
{
  m_poInterpreter->SetLastCall( "SqlLite2IsGood" );

  VerifyRunLineArguments( iArgc, 1 );

  bool bResult = false;

  if ( m_poVirtualChip->m_psStackPointer[ 0 ].v_type == DT_SQLLITE_2_DB )
  {
    VMSqlLiteDatabase* poMiniDB = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_sqllite2db;

    bResult = poMiniDB->IsOkay();
  }
  else
  if ( m_poVirtualChip->m_psStackPointer[ 0 ].v_type == DT_SQLLITE_2_ROWSET )
  {
    VMSqlLiteQueryResult* poQuery  = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_sqllite2rowset;  

    bResult = ( poQuery->m_oLastError.GetLength() == 0 ) ? true : false;
  }
  else
  {
    VerifyElementType( 0, DT_SQLLITE_2_DB );
  }

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], bResult );
  m_poVirtualChip->m_psStackPointer += iArgc;

  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerSqlLite2IsGood"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerSqlLite2ExecQuery

       DESCRIPTION:  execute a query against a mini (sql lite) database

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerSqlLite2ExecQuery( int iArgc )
{
  m_poInterpreter->SetLastCall( "SqlLite2ExecQuery" );

  VerifyRunLineArguments( iArgc, 2 );
  VerifyElementType( 1, DT_SQLLITE_2_DB );
  VerifyElementType( 0, DT_STRING       );
  
  VMSqlLiteDatabase*    poMiniDB = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_sqllite2db;
  char*                 pchExec  = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_string->str_data;
  VMSqlLiteQueryResult* poQuery  = new VMSqlLiteQueryResult( poMiniDB );
  
  bool bResult = poQuery->Execute( pchExec );

  // all heap based variables are tracked separately in an allocation tracker
  // 
  // the work below is how that is accomplished. All heap based variable types
  // are tracked the same way, so you will see similar code in many other 
  // object allocation routines in this file.
  //
  VMTrackedAllocs* poAlloc   = new VMTrackedAllocs;
  poAlloc->v.v_sqllite2rowset = poQuery;
  poAlloc->v_type            = DT_SQLLITE_2_ROWSET;
  m_oTrackedAllocs.push_back( poAlloc );

  set_sqllite2rowset( &m_poVirtualChip->m_psStackPointer[ iArgc ], poQuery );
  m_poVirtualChip->m_psStackPointer += iArgc;

  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerSqlLite2ExecQuery"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerSqlLite3ExecQuery

       DESCRIPTION:  execute a query against a mini (sql lite) database

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerSqlLite3ExecQuery( int iArgc )
{
  m_poInterpreter->SetLastCall( "SqlLite3ExecQuery" );

  VerifyRunLineArguments( iArgc, 2 );
  VerifyElementType( 1, DT_SQLLITE_3_DB );
  VerifyElementType( 0, DT_STRING       );
  
  VMSqlite3xDatabase*   poMiniDB = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_sqllite3db;
  char*                 pchExec  = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_string->str_data;
  VMSqlite3xTable       oResult  = poMiniDB->GetTableByName( pchExec );

  VMSqlite3xTable*      poResult = new VMSqlite3xTable( oResult );

  // all heap based variables are tracked separately in an allocation tracker
  // 
  // the work below is how that is accomplished. All heap based variable types
  // are tracked the same way, so you will see similar code in many other 
  // object allocation routines in this file.
  //
  VMTrackedAllocs* poAlloc    = new VMTrackedAllocs;
  poAlloc->v.v_sqllite3rowset = poResult;
  poAlloc->v_type             = DT_SQLLITE_3_ROWSET;
  m_oTrackedAllocs.push_back( poAlloc );

  set_sqllite3rowset( &m_poVirtualChip->m_psStackPointer[ iArgc ], poResult );
  m_poVirtualChip->m_psStackPointer += iArgc;

  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerSqlLite3ExecQuery"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerSqlLite3QueryCopy

       DESCRIPTION:  execute a query against a mini (sql lite) database

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerSqlLite3QueryCopy( int iArgc )
{
  m_poInterpreter->SetLastCall( "SqlLite3QueryCopy" );

  VerifyRunLineArguments( iArgc, 4 );
  VerifyElementType( 3, DT_SQLLITE_3_DB );
  VerifyElementType( 2, DT_SQLLITE_3_DB );
  VerifyElementType( 1, DT_STRING       );
  VerifyElementType( 0, DT_STRING       );
  
  VMSqlite3xDatabase*   poSourceDB = m_poVirtualChip->m_psStackPointer[ 3 ].v.v_sqllite3db;
  VMSqlite3xDatabase*   poTargetDB = m_poVirtualChip->m_psStackPointer[ 2 ].v.v_sqllite3db;
  char*                 pchTable   = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_string->str_data;
  char*                 pchQuery   = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_string->str_data;
  char                  achInsert[ 5000 ];
  int                   iColumnCount;
  const char*           pchColumnDataType;

  // gather up the source data
  //
  VMSqlite3xQuery oTable = poSourceDB->ExecuteQuery( pchQuery );

  // now generate a statement query based on the footprint
  // of the source data
  //
  sprintf( achInsert, "insert into %s values( ", pchTable );

  iColumnCount = oTable.GetColumnCount();
  for ( int iLoop = 0; iLoop < iColumnCount; iLoop++ )
  {
    if ( iLoop < iColumnCount - 1 )
    {
      strcat( achInsert, " ? , " );
    }
    else
    {
      strcat( achInsert, " ? ) " );
    }  
  }  

  // compile the statement
  //
  VMSqlite3xStatement oStatement = poTargetDB->PrepareStatement( achInsert );

  // for speed
  //
  poTargetDB->ExecuteDML( "begin transaction" );

  // for each row in the source data set
  //
  while ( !oTable.IsEOF() )
  {
    std::vector< char* > oAllocs;

    // bind each column to the statement compiled above
    //
    for ( int iLoop = 0; iLoop < iColumnCount; iLoop++ )
    {
      pchColumnDataType = oTable.GetColumnDataTypeNameAtIndex( iLoop );

      // bind based on data type
      //
      if ( NULL == pchColumnDataType )
      {
        oStatement.BindNullParameter( iLoop + 1 );
      }
      else
      if (  NULL != strstr( pchColumnDataType, "integer" ) 
         || NULL != strstr( pchColumnDataType, "short" )
         || NULL != strstr( pchColumnDataType, "long" ) )
      {
        char* pchValue = new char[ sizeof( int ) ];
        oAllocs.push_back( pchValue );
        
        *( (int*)pchValue ) = oTable.GetColumnValueAtIndexAsInt( iLoop );	
        oStatement.BindParameter( iLoop + 1, *( (int*)pchValue ) );
      }
      else
      if ( NULL != strstr( pchColumnDataType, "double" ) )
      {
        char* pchValue = new char[ sizeof( double ) ];
        oAllocs.push_back( pchValue );

        *( (double*)pchValue ) = oTable.GetColumnValueAtIndexAsDouble( iLoop );	
        oStatement.BindParameter( iLoop + 1, *( (double*)pchValue ) );
      }
      else
      {
        const char* pchColValue = oTable.GetColumnValueAtIndexAsString( iLoop  );
        char* pchValue = new char[ strlen( pchColValue ) + 1 ];
        oAllocs.push_back( pchValue );

        strcpy( pchValue, pchColValue );
        oStatement.BindParameter( iLoop + 1, pchValue );
      }
    }
  
    // commit the data to the target, then move to next row in source
    //
    oStatement.ExecuteDML();
    oTable.MoveToNextRow();

    // clear all allocations on each row
    //
    std::vector< char* >::iterator oIter;
    for ( oIter  = oAllocs.begin();
          oIter != oAllocs.end();
          oIter++ )
    {
      char* pchDelete = (*oIter);
      delete[] pchDelete;
    }
    oAllocs.clear();
  }

  // complete the transaction and clean up
  //
  poTargetDB->ExecuteDML( "commit transaction" );

  oStatement.Close();
  oTable.Close();

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], true );
  m_poVirtualChip->m_psStackPointer += iArgc;

  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerSqlLite3QueryCopy"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerSqlLite3TableCopy

       DESCRIPTION:  execute a query against a mini (sql lite) database

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerSqlLite3TableCopy( int iArgc )
{
  m_poInterpreter->SetLastCall( "SqlLite3TableCopy" );

  VerifyRunLineArguments( iArgc, 3 );
  VerifyElementType( 2, DT_SQLLITE_3_DB );
  VerifyElementType( 1, DT_SQLLITE_3_DB );
  VerifyElementType( 0, DT_STRING       );
  
  VMSqlite3xDatabase*   poSourceDB = m_poVirtualChip->m_psStackPointer[ 2 ].v.v_sqllite3db;
  VMSqlite3xDatabase*   poTargetDB = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_sqllite3db;
  char*                 pchTable   = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_string->str_data;
  char                  achQuery[ 500 ];
  char                  achInsert[ 5000 ];
  int                   iColumnCount;
  const char*           pchColumnDataType;

  // gather up the source data
  //
  sprintf( achQuery, "select * from %s", pchTable );
  VMSqlite3xQuery oTable = poSourceDB->ExecuteQuery( achQuery );

  // now generate a statement query based on the footprint
  // of the source data
  //
  sprintf( achInsert, "insert into %s values( ", pchTable );

  iColumnCount = oTable.GetColumnCount();
  for ( int iLoop = 0; iLoop < iColumnCount; iLoop++ )
  {
    if ( iLoop < iColumnCount - 1 )
    {
      strcat( achInsert, " ? , " );
    }
    else
    {
      strcat( achInsert, " ? ) " );
    }  
  }  

  // compile the statement
  //
  VMSqlite3xStatement oStatement = poTargetDB->PrepareStatement( achInsert );

  // for speed
  //
  poTargetDB->ExecuteDML( "begin transaction" );

  // for each row in the source data set
  //
  while ( !oTable.IsEOF() )
  {
    std::vector< char* > oAllocs;

    // bind each column to the statement compiled above
    //
    for ( int iLoop = 0; iLoop < iColumnCount; iLoop++ )
    {
      pchColumnDataType = oTable.GetColumnDataTypeNameAtIndex( iLoop );

      // bind based on data type
      //
      if ( NULL == pchColumnDataType )
      {
        oStatement.BindNullParameter( iLoop + 1 );
      }
      else
      if ( NULL != strstr( pchColumnDataType, "integer" ) 
         || NULL != strstr( pchColumnDataType, "short" )
         || NULL != strstr( pchColumnDataType, "long" ) )
      {
        char* pchValue = new char[ sizeof( int ) ];
        oAllocs.push_back( pchValue );
        
        *( (int*)pchValue ) = oTable.GetColumnValueAtIndexAsInt( iLoop );	
        oStatement.BindParameter( iLoop + 1, *( (int*)pchValue ) );
      }
      else
      if ( NULL != strstr( pchColumnDataType, "double" ) )
      {
        char* pchValue = new char[ sizeof( double ) ];
        oAllocs.push_back( pchValue );

        *( (double*)pchValue ) = oTable.GetColumnValueAtIndexAsDouble( iLoop );	
        oStatement.BindParameter( iLoop + 1, *( (double*)pchValue ) );
      }
      else
      {
        const char* pchColValue = oTable.GetColumnValueAtIndexAsString( iLoop  );
        char* pchValue = new char[ strlen( pchColValue ) + 1 ];
        oAllocs.push_back( pchValue );

        strcpy( pchValue, pchColValue );
        oStatement.BindParameter( iLoop + 1, pchValue );
      }
    }
  
    // commit the data to the target, then move to next row in source
    //
    oStatement.ExecuteDML();
    oTable.MoveToNextRow();

    // clear all allocations on each row
    //
    std::vector< char* >::iterator oIter;
    for ( oIter  = oAllocs.begin();
          oIter != oAllocs.end();
          oIter++ )
    {
      char* pchDelete = (*oIter);
      delete[] pchDelete;
    }
    oAllocs.clear();
  }

  // complete the transaction and clean up
  //
  poTargetDB->ExecuteDML( "commit transaction" );

  oStatement.Close();
  oTable.Close();

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], true );
  m_poVirtualChip->m_psStackPointer += iArgc;

  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerSqlLite3TableCopy"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerSqlLite2ExecStatement

       DESCRIPTION:  execute a query against a mini (sql lite) database but
                     return no results

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerSqlLite2ExecStatement( int iArgc )
{
  m_poInterpreter->SetLastCall( "SqlLite2ExecStatement" );

  VerifyRunLineArguments( iArgc, 2 );
  VerifyElementType( 1, DT_SQLLITE_2_DB );
  VerifyElementType( 0, DT_STRING       );
  
  VMSqlLiteDatabase*    poMiniDB = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_sqllite2db;
  char*                 pchExec  = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_string->str_data;
  VMSqlLiteQuery        oQuery( poMiniDB );
  
  bool bResult = oQuery.Execute( pchExec );

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], bResult );
  m_poVirtualChip->m_psStackPointer += iArgc;

  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerSqlLite2ExecStatement"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerSqlLite3ExecStatement

       DESCRIPTION:  execute a query against a mini (sql lite) database but
                     return no results

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerSqlLite3ExecStatement( int iArgc )
{
  m_poInterpreter->SetLastCall( "SqlLite3ExecStatement" );

  VerifyRunLineArguments( iArgc, 2 );
  VerifyElementType( 1, DT_SQLLITE_3_DB );
  VerifyElementType( 0, DT_STRING       );
  
  VMSqlite3xDatabase*   poMiniDB = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_sqllite3db;
  char*                 pchExec  = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_string->str_data;
  
  bool bResult = poMiniDB->ExecuteDML( pchExec );

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], bResult );
  m_poVirtualChip->m_psStackPointer += iArgc;

  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerSqlLite3ExecStatement"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerSqlLite2IsEmptySet

       DESCRIPTION:  is there any results in the rowset object?

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerSqlLite2IsEmptySet( int iArgc )
{
  m_poInterpreter->SetLastCall( "SqlLite2RowSetIsEmptySet" );

  VerifyRunLineArguments( iArgc, 1 );
  VerifyElementType( 0, DT_SQLLITE_2_ROWSET );
  
  VMSqlLiteQueryResult* poQuery  = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_sqllite2rowset;
  
  bool bResult = ( poQuery->GetRowCount() == 0 ) ? true : false;

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], bResult );
  m_poVirtualChip->m_psStackPointer += iArgc;

  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerSqlLite2IsEmptySet"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerSqlLite3IsEmptySet

       DESCRIPTION:  is there any results in the rowset object?

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerSqlLite3IsEmptySet( int iArgc )
{
  m_poInterpreter->SetLastCall( "SqlLite3RowSetIsEmptySet" );

  VerifyRunLineArguments( iArgc, 1 );
  VerifyElementType( 0, DT_SQLLITE_3_ROWSET );
  
  VMSqlite3xTable* poQuery  = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_sqllite3rowset;
  
  bool bResult = ( poQuery->GetRowCount() == 0 ) ? true : false;

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], bResult );
  m_poVirtualChip->m_psStackPointer += iArgc;

  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerSqlLite3IsEmptySet"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerSqlLite2IsEOF

       DESCRIPTION:  is there more data available in the rowset object?

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerSqlLite2IsEOF( int iArgc )
{
  m_poInterpreter->SetLastCall( "SqlLite2RowSetIsEOF" );

  VerifyRunLineArguments( iArgc, 1 );
  VerifyElementType( 0, DT_SQLLITE_2_ROWSET );
  
  VMSqlLiteQueryResult* poQuery  = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_sqllite2rowset;
  
  bool bResult = poQuery->IsEOF();

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], bResult );
  m_poVirtualChip->m_psStackPointer += iArgc;

  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerSqlLite2IsEOF"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerSqlLite3IsEOF

       DESCRIPTION:  is there more data available in the rowset object?

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerSqlLite3IsEOF( int iArgc )
{
  m_poInterpreter->SetLastCall( "SqlLite3RowSetIsEOF" );

  VerifyRunLineArguments( iArgc, 1 );
  VerifyElementType( 0, DT_SQLLITE_3_ROWSET );
  
  VMSqlite3xTable* poQuery  = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_sqllite3rowset;
  
  bool bResult = ( poQuery->GetCurrentRowIndex() == poQuery->GetRowCount() ) ? true : false;

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], bResult );
  m_poVirtualChip->m_psStackPointer += iArgc;

  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerSqlLite3IsEOF"
/*****************************************************************************/

/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerSqlLite2IsBOF

       DESCRIPTION:  is the cursor at the beginning of the rowset object?

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerSqlLite2IsBOF( int iArgc )
{
  m_poInterpreter->SetLastCall( "SqlLite2RowSetIsBOF" );

  VerifyRunLineArguments( iArgc, 1 );
  VerifyElementType( 0, DT_SQLLITE_2_ROWSET );
  
  VMSqlLiteQueryResult* poQuery  = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_sqllite2rowset;
  
  bool bResult = poQuery->IsBOF();

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], bResult );
  m_poVirtualChip->m_psStackPointer += iArgc;

  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerSqlLite2IsBOF"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerSqlLite3IsBOF

       DESCRIPTION:  is the cursor at the beginning of the rowset object?

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerSqlLite3IsBOF( int iArgc )
{
  m_poInterpreter->SetLastCall( "SqlLite3RowSetIsBOF" );

  VerifyRunLineArguments( iArgc, 1 );
  VerifyElementType( 0, DT_SQLLITE_3_ROWSET );
  
  VMSqlite3xTable* poQuery  = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_sqllite3rowset;
  
  bool bResult = ( poQuery->GetCurrentRowIndex() == 0 ) ? true : false;

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], bResult );
  m_poVirtualChip->m_psStackPointer += iArgc;

  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerSqlLite3IsBOF"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerSqlLite2MoveNext

       DESCRIPTION:  move rowset cursor ahead one row

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerSqlLite2MoveNext( int iArgc )
{
  m_poInterpreter->SetLastCall( "SqlLite2RowSetMoveNext" );

  VerifyRunLineArguments( iArgc, 1 );
  VerifyElementType( 0, DT_SQLLITE_2_ROWSET );
  
  VMSqlLiteQueryResult* poQuery  = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_sqllite2rowset;
  
  bool bResult = poQuery->MoveNextRow();

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], bResult );
  m_poVirtualChip->m_psStackPointer += iArgc;

  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerSqlLite2MoveNext"
/*****************************************************************************/

/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerSqlLite3MoveNext

       DESCRIPTION:  move rowset cursor ahead one row

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerSqlLite3MoveNext( int iArgc )
{
  m_poInterpreter->SetLastCall( "SqlLite3RowSetMoveNext" );

  VerifyRunLineArguments( iArgc, 1 );
  VerifyElementType( 0, DT_SQLLITE_3_ROWSET );
  
  VMSqlite3xTable* poQuery  = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_sqllite3rowset;

  bool bResult;
  int  iCurrent = poQuery->GetCurrentRowIndex();
  if ( iCurrent <= poQuery->GetRowCount() - 2 )
  {
    bResult = true;
    poQuery->MoveToRow( ++iCurrent );
  }
  else
  {
    bResult = false;
  }

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], bResult );
  m_poVirtualChip->m_psStackPointer += iArgc;

  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerSqlLite3MoveNext"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerSqlLite2MovePrev

       DESCRIPTION:  move rowset cursor back one row

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerSqlLite2MovePrev( int iArgc )
{
  m_poInterpreter->SetLastCall( "SqlLite2RowSetMovePrev" );

  VerifyRunLineArguments( iArgc, 1 );
  VerifyElementType( 0, DT_SQLLITE_2_ROWSET );
  
  VMSqlLiteQueryResult* poQuery  = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_sqllite2rowset;
  
  bool bResult = poQuery->MovePrevRow();

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], bResult );
  m_poVirtualChip->m_psStackPointer += iArgc;

  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerSqlLite2MovePrev"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerSqlLite3MovePrev

       DESCRIPTION:  move rowset cursor back one row

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerSqlLite3MovePrev( int iArgc )
{
  m_poInterpreter->SetLastCall( "SqlLite3RowSetMovePrev" );

  VerifyRunLineArguments( iArgc, 1 );
  VerifyElementType( 0, DT_SQLLITE_3_ROWSET );
  
  VMSqlite3xTable* poQuery  = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_sqllite3rowset;

  bool bResult;
  int  iCurrent = poQuery->GetCurrentRowIndex();
  if ( iCurrent == 0 )
  {
    bResult = false;
  }
  else
  {
    bResult = true;
    poQuery->MoveToRow( --iCurrent );
  }

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], bResult );
  m_poVirtualChip->m_psStackPointer += iArgc;

  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerSqlLite3MovePrev"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerSqlLite2GetFieldByIndex

       DESCRIPTION:  retrieves value at current row for given column index

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerSqlLite2GetFieldByIndex( int iArgc )
{
  m_poInterpreter->SetLastCall( "SqlLite2RowSetGetFieldByIndex" );

  VerifyRunLineArguments( iArgc, 3 );
  VerifyElementType( 2, DT_SQLLITE_2_ROWSET );
  VerifyElementType( 1, DT_INTEGER          );
  VerifyElementType( 0, DT_STRING           );
  
  VMSqlLiteQueryResult* poQuery  = m_poVirtualChip->m_psStackPointer[ 2 ].v.v_sqllite2rowset;
  int                   iColumn  = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_integer;
  char*                 pchCast  = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_string->str_data;

  VMSqlLiteQueryBase::CDBField oValue = poQuery->GetValueAt( iColumn );

  if ( 0 == strcmp( pchCast, "AsString" ) )
  {
    VMString oText = oValue.AsString();
    vmstring* pxResult = AllocateNewString( oText.Length() + 4, true );
    strcpy( pxResult->str_data, oText.Buffer() );
    SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], pxResult );
  }
  else
  if ( 0 == strcmp( pchCast, "AsLong" ) )
  {
    long lResult = oValue.AsLong();
    SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], lResult );
  }
  else
  if ( 0 == strcmp( pchCast, "AsBool" ) )
  {
    bool bResult = oValue.AsBool();
    SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], bResult );
  }
  else
  if ( 0 == strcmp( pchCast, "AsDate" ) )
  {
    VMDateTime oDate = oValue.AsDate();
    SYSTEMTIME xDate = oDate.GetTime(); 
    SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], xDate );
  }
  else
  if ( 0 == strcmp( pchCast, "AsDouble" ) )
  {
    double dblResult = oValue.AsDouble();
    SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], dblResult );
  }
  else
  {
    VMString oText = oValue.AsString();
    vmstring* pxResult = AllocateNewString( oText.Length() + 4, true );
    strcpy( pxResult->str_data, oText.Buffer() );
    SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], pxResult );
  }

  m_poVirtualChip->m_psStackPointer += iArgc;

  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerSqlLite2GetFieldByIndex"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerSqlLite3GetFieldByIndex

       DESCRIPTION:  retrieves value at current row for given column index

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerSqlLite3GetFieldByIndex( int iArgc )
{
  m_poInterpreter->SetLastCall( "SqlLite3RowSetGetFieldByIndex" );

  VerifyRunLineArguments( iArgc, 3 );
  VerifyElementType( 2, DT_SQLLITE_3_ROWSET );
  VerifyElementType( 1, DT_INTEGER          );
  VerifyElementType( 0, DT_STRING           );
  
  VMSqlite3xTable* poQuery  = m_poVirtualChip->m_psStackPointer[ 2 ].v.v_sqllite3rowset;
  int              iColumn  = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_integer;
  char*            pchCast  = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_string->str_data;

  if ( 0 == strcmp( pchCast, "AsString" ) )
  {
    const char* pchValue = poQuery->GetColumnValueAtIndexAsString( iColumn );
    vmstring* pxResult = AllocateNewString( strlen( pchValue ) + 4, true );
    strcpy( pxResult->str_data, pchValue );
    SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], pxResult );
  }
  else
  if ( 0 == strcmp( pchCast, "AsLong" ) )
  {
    long lResult = poQuery->GetColumnValueAtIndexAsInt( iColumn );
    SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], lResult );
  }
  else
  if ( 0 == strcmp( pchCast, "AsBool" ) )
  {
    long lResult = poQuery->GetColumnValueAtIndexAsInt( iColumn );
    SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], lResult != 0 ? true : false );
  }
  else
  if ( 0 == strcmp( pchCast, "AsDate" ) )
  {
    const char* pchValue = poQuery->GetColumnValueAtIndexAsString( iColumn );
    VMDateTime oDate( pchValue );
    SYSTEMTIME xDate = oDate.GetTime(); 
    SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], xDate );
  }
  else
  if ( 0 == strcmp( pchCast, "AsDouble" ) )
  {
    double dblResult = poQuery->GetColumnValueAtIndexAsDouble( iColumn );
    SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], dblResult );
  }
  else
  {
    const char* pchValue = poQuery->GetColumnValueAtIndexAsString( iColumn );
    vmstring* pxResult = AllocateNewString( strlen( pchValue ) + 4, true );
    strcpy( pxResult->str_data, pchValue );
    SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], pxResult );
  }

  m_poVirtualChip->m_psStackPointer += iArgc;

  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerSqlLite3GetFieldByIndex"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerSqlLite2GetFieldByName

       DESCRIPTION:  retrieves value at current row for given column name

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerSqlLite2GetFieldByName( int iArgc )
{
  m_poInterpreter->SetLastCall( "SqlLite2RowSetGetFieldByName" );

  VerifyRunLineArguments( iArgc, 3 );
  VerifyElementType( 2, DT_SQLLITE_2_ROWSET );
  VerifyElementType( 1, DT_STRING           );
  VerifyElementType( 0, DT_STRING           );
  
  VMSqlLiteQueryResult* poQuery   = m_poVirtualChip->m_psStackPointer[ 2 ].v.v_sqllite2rowset;
  char*                 pchColumn = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_string->str_data;
  char*                 pchCast   = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_string->str_data;

  VMString oColumn;
  oColumn = pchColumn;

  VMSqlLiteQueryBase::CDBField oValue = poQuery->FieldByName( oColumn );

  if ( 0 == strcmp( pchCast, "AsString" ) )
  {
    VMString oText = oValue.AsString();
    vmstring* pxResult = AllocateNewString( oText.Length() + 4, true );
    strcpy( pxResult->str_data, oText.Buffer() );
    SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], pxResult );
  }
  else
  if ( 0 == strcmp( pchCast, "AsLong" ) )
  {
    long lResult = oValue.AsLong();
    SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], lResult );
  }
  else
  if ( 0 == strcmp( pchCast, "AsBool" ) )
  {
    bool bResult = oValue.AsBool();
    SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], bResult );
  }
  else
  if ( 0 == strcmp( pchCast, "AsDate" ) )
  {
    VMDateTime oDate = oValue.AsDate();
    SYSTEMTIME xDate = oDate.GetTime(); 
    SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], xDate );
  }
  else
  if ( 0 == strcmp( pchCast, "AsDouble" ) )
  {
    double dblResult = oValue.AsDouble();
    SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], dblResult );
  }
  else
  {
    VMString oText = oValue.AsString();
    vmstring* pxResult = AllocateNewString( oText.Length() + 4, true );
    strcpy( pxResult->str_data, oText.Buffer() );
    SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], pxResult );
  }

  m_poVirtualChip->m_psStackPointer += iArgc;

  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerSqlLite2GetFieldByName"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerSqlLite3GetFieldByName

       DESCRIPTION:  retrieves value at current row for given column name

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerSqlLite3GetFieldByName( int iArgc )
{
  m_poInterpreter->SetLastCall( "SqlLite3RowSetGetFieldByName" );

  VerifyRunLineArguments( iArgc, 3 );
  VerifyElementType( 2, DT_SQLLITE_3_ROWSET );
  VerifyElementType( 1, DT_STRING           );
  VerifyElementType( 0, DT_STRING           );
  
  VMSqlite3xTable* poQuery   = m_poVirtualChip->m_psStackPointer[ 2 ].v.v_sqllite3rowset;
  char*            pchColumn = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_string->str_data;
  char*            pchCast   = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_string->str_data;

  if ( 0 == strcmp( pchCast, "AsString" ) )
  {
    const char* pchValue = poQuery->GetColumnValueByNameAsString( pchColumn );
    vmstring* pxResult = AllocateNewString( strlen( pchValue ) + 4, true );
    strcpy( pxResult->str_data, pchValue );
    SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], pxResult );
  }
  else
  if ( 0 == strcmp( pchCast, "AsLong" ) )
  {
    long lResult = poQuery->GetColumnValueByNameAsInt( pchColumn );
    SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], lResult );
  }
  else
  if ( 0 == strcmp( pchCast, "AsBool" ) )
  {
    long lResult = poQuery->GetColumnValueByNameAsInt( pchColumn );
    SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], lResult != 0 ? true : false );
  }
  else
  if ( 0 == strcmp( pchCast, "AsDate" ) )
  {
    const char* pchValue = poQuery->GetColumnValueByNameAsString( pchColumn );
    VMDateTime oDate( pchValue );
    SYSTEMTIME xDate = oDate.GetTime(); 
    SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], xDate );
  }
  else
  if ( 0 == strcmp( pchCast, "AsDouble" ) )
  {
    double dblResult = poQuery->GetColumnValueByNameAsDouble( pchColumn );
    SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], dblResult );
  }
  else
  {
    const char* pchValue = poQuery->GetColumnValueByNameAsString( pchColumn );
    vmstring* pxResult = AllocateNewString( strlen( pchValue ) + 4, true );
    strcpy( pxResult->str_data, pchValue );
    SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], pxResult );
  }

  m_poVirtualChip->m_psStackPointer += iArgc;

  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerSqlLite3GetFieldByName"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerSqlLite2GetColumnCount

       DESCRIPTION:  gets column count in the rowset

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerSqlLite2GetColumnCount( int iArgc )
{
  m_poInterpreter->SetLastCall( "SqlLite2RowSetGetColumnCount" );

  VerifyRunLineArguments( iArgc, 1 );
  VerifyElementType( 0, DT_SQLLITE_2_ROWSET );
  
  VMSqlLiteQueryResult* poQuery  = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_sqllite2rowset;
  
  long lResult = poQuery->GetColumnCount();

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], lResult );
  m_poVirtualChip->m_psStackPointer += iArgc;

  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerSqlLite2GetColumnCount"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerSqlLite3GetColumnCount

       DESCRIPTION:  gets column count in the rowset

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerSqlLite3GetColumnCount( int iArgc )
{
  m_poInterpreter->SetLastCall( "SqlLite3RowSetGetColumnCount" );

  VerifyRunLineArguments( iArgc, 1 );
  VerifyElementType( 0, DT_SQLLITE_3_ROWSET );
  
  VMSqlite3xTable* poQuery  = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_sqllite3rowset;
  
  long lResult = poQuery->GetColumnCount();

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], lResult );
  m_poVirtualChip->m_psStackPointer += iArgc;

  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerSqlLite3GetColumnCount"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerSqlLite2GetRowCount

       DESCRIPTION:  gets row count in the rowset

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerSqlLite2GetRowCount( int iArgc )
{
  m_poInterpreter->SetLastCall( "SqlLite2RowSetGetRowCount" );

  VerifyRunLineArguments( iArgc, 1 );
  VerifyElementType( 0, DT_SQLLITE_2_ROWSET );
  
  VMSqlLiteQueryResult* poQuery  = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_sqllite2rowset;
  
  long lResult = poQuery->GetRowCount();

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], lResult );
  m_poVirtualChip->m_psStackPointer += iArgc;

  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerSqlLite2GetRowCount"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerSqlLite3GetRowCount

       DESCRIPTION:  gets row count in the rowset

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerSqlLite3GetRowCount( int iArgc )
{
  m_poInterpreter->SetLastCall( "SqlLite3RowSetGetRowCount" );

  VerifyRunLineArguments( iArgc, 1 );
  VerifyElementType( 0, DT_SQLLITE_3_ROWSET );
  
  VMSqlite3xTable* poQuery  = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_sqllite3rowset;
  
  long lResult = poQuery->GetRowCount();

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], lResult );
  m_poVirtualChip->m_psStackPointer += iArgc;

  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerSqlLite3GetRowCount"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerSqlLite2GetLastError

       DESCRIPTION:  gets row count in the rowset

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerSqlLite2GetLastError( int iArgc )
{
  m_poInterpreter->SetLastCall( "SqlLite2GetLastError" );

  VerifyRunLineArguments( iArgc, 1 );

  VMString oErrText;

  if ( m_poVirtualChip->m_psStackPointer[ 0 ].v_type == DT_SQLLITE_2_DB )
  {
    VMSqlLiteDatabase* poMiniDB = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_sqllite2db;

    oErrText = poMiniDB->m_oErrorMessage;
  }
  else
  if ( m_poVirtualChip->m_psStackPointer[ 0 ].v_type == DT_SQLLITE_2_ROWSET )
  {
    VMSqlLiteQueryResult* poQuery  = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_sqllite2rowset;  

    oErrText = poQuery->m_oLastError;
  }
  else
  {
    VerifyElementType( 0, DT_SQLLITE_2_DB );
  }
  
  vmstring* pxResult = AllocateNewString( oErrText.Length() + 4, true );
  strcpy( pxResult->str_data, oErrText.Buffer() );

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], pxResult );
  m_poVirtualChip->m_psStackPointer += iArgc;

  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerSqlLite2GetLastError"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerFileBuilderGetCount

       DESCRIPTION:  gets line count from the file builder

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerFileBuilderGetCount( int iArgc )
{
  m_poInterpreter->SetLastCall( "FileBuilderGetCount" );

  VerifyRunLineArguments( iArgc, 1 );
  VerifyElementType( 0, DT_FILE_BUILDER );
  
  VMStringFileBuilder* poFB = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_filebuilder;
  
  long lResult = poFB->GetCount();

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], lResult );
  m_poVirtualChip->m_psStackPointer += iArgc;

  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerFileBuilderGetCount"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerFileBuilderAddTail

       DESCRIPTION:  adds a new line to the end of the file builder

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerFileBuilderAddTail( int iArgc )
{
  m_poInterpreter->SetLastCall( "FileBuilderAddTail" );

  VerifyRunLineArguments( iArgc, 2 );
  VerifyElementType( 1, DT_FILE_BUILDER );
  VerifyElementType( 0, DT_STRING       );
  
  VMStringFileBuilder* poFB    = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_filebuilder;
  char*                pchTail = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_string->str_data;
  
  bool bResult = poFB->AddTail( pchTail );

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], bResult );
  m_poVirtualChip->m_psStackPointer += iArgc;

  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerFileBuilderAddTail"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerFileBuilderSetAtIndex

       DESCRIPTION:  gets row count in the rowset

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerFileBuilderSetAtIndex( int iArgc )
{
  m_poInterpreter->SetLastCall( "FileBuilderSetAtIndex" );

  VerifyRunLineArguments( iArgc, 3 );
  VerifyElementType( 2, DT_FILE_BUILDER );
  VerifyElementType( 1, DT_INTEGER      );
  VerifyElementType( 0, DT_STRING       );
  
  VMStringFileBuilder* poFB    = m_poVirtualChip->m_psStackPointer[ 2 ].v.v_filebuilder;
  int                  iIndex  = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_integer;
  char*                pchTail = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_string->str_data;
  
  bool bResult = poFB->SetAt( iIndex, pchTail );

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], bResult );
  m_poVirtualChip->m_psStackPointer += iArgc;

  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerFileBuilderSetAtIndex"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerFileBuilderDelAtIndex

       DESCRIPTION:  gets row count in the rowset

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerFileBuilderDelAtIndex( int iArgc )
{
  m_poInterpreter->SetLastCall( "FileBuilderDelAtIndex" );

  VerifyRunLineArguments( iArgc, 2 );
  VerifyElementType( 1, DT_FILE_BUILDER );
  VerifyElementType( 0, DT_INTEGER      );
  
  VMStringFileBuilder* poFB    = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_filebuilder;
  int                  iIndex  = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_integer;

  bool bResult = poFB->RemoveAt( iIndex );

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], bResult );

  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerFileBuilderDelAtIndex"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerFileBuilderGetAtIndex

       DESCRIPTION:  gets row count in the rowset

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerFileBuilderGetAtIndex( int iArgc )
{
  m_poInterpreter->SetLastCall( "FileBuilderGetAtIndex" );

  VerifyRunLineArguments( iArgc, 2 );
  VerifyElementType( 1, DT_FILE_BUILDER );
  VerifyElementType( 0, DT_INTEGER      );
  
  VMStringFileBuilder* poFB    = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_filebuilder;
  int                  iIndex  = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_integer;
  std::string          oText;

  bool bResult = poFB->GetAt( iIndex, oText );

  vmstring* pxResult = AllocateNewString( oText.length() + 4, true );
  strcpy( pxResult->str_data, oText.c_str() );

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], pxResult );

  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerFileBuilderGetAtIndex"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerFileBuilderRemoveAll

       DESCRIPTION:  gets row count in the rowset

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerFileBuilderRemoveAll( int iArgc )
{
  m_poInterpreter->SetLastCall( "FileBuilderRemoveAll" );

  VerifyRunLineArguments( iArgc, 1 );
  VerifyElementType( 0, DT_FILE_BUILDER );
  
  VMStringFileBuilder* poFB = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_filebuilder;
  
  bool bResult = poFB->RemoveAll();

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], bResult );
  m_poVirtualChip->m_psStackPointer += iArgc;

  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerFileBuilderRemoveAll"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerFileBuilderSendToFile

       DESCRIPTION:  gets row count in the rowset

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerFileBuilderSendToFile( int iArgc )
{
  m_poInterpreter->SetLastCall( "FileBuilderSendToFile" );

  VerifyRunLineArguments( iArgc, 2 );
  VerifyElementType( 1, DT_FILE_BUILDER );
  VerifyElementType( 0, DT_STRING       );
  
  VMStringFileBuilder* poFB    = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_filebuilder;
  char*                pchFile = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_string->str_data;

  std::string          oLine;
  int                  iCount;
  HANDLE               hFile = NULL;

  iCount = poFB->GetCount();

  if ( iCount > 0 )
  {
    hFile = CreateFile( pchFile, 
                        GENERIC_WRITE | GENERIC_READ,
                        0,  // exclusive access
                        NULL,
                        CREATE_ALWAYS,
                        FILE_ATTRIBUTE_NORMAL,
                        NULL );
 
    if ( INVALID_HANDLE_VALUE == hFile )
    {
      CloseHandle( hFile );
      iCount = 0;
    }
  }

  if ( iCount > 0 && hFile != NULL )
  {
    for ( int iLoop = 0; iLoop < iCount; iLoop++ )
    {
      if ( poFB->GetAt( iLoop, oLine ) )
      {
        int         iLength = oLine.length();
        const char* pchLine = oLine.c_str();   
        DWORD       dwBytesWritten;

        if ( WriteFile( hFile,
                        pchLine,
                        strlen( pchLine ),
                        &dwBytesWritten,
                        NULL ) )
        {
          if ( strlen( pchLine ) != dwBytesWritten )
          {
            CloseHandle( hFile );
            break;
            iCount = iLoop;
          }
        }
      }
    }
    CloseHandle( hFile );
  } 

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], iCount );

  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerFileBuilderSendToFile"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerDelimFileSetValueAt

       DESCRIPTION:  sets the value at the specified location in the delim obj

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerDelimFileSetValueAt( int iArgc )
{
  m_poInterpreter->SetLastCall( "DelimFileSetValueAt" );

  VerifyRunLineArguments( iArgc, 4 );
  VerifyElementType( 3, DT_DELIMITED_FILE );
  VerifyElementType( 2, DT_INTEGER        );
  VerifyElementType( 1, DT_INTEGER        );  

  VMFileParser* poDelimFile = m_poVirtualChip->m_psStackPointer[ 3 ].v.v_delimitedfile;
  int           iRow        = m_poVirtualChip->m_psStackPointer[ 2 ].v.v_integer;
  int           iCol        = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_integer;
  int           iType       = m_poVirtualChip->m_psStackPointer[ 0 ].v_type;

  char          achToAppend[ 1024 ];

  switch ( iType )
  {
    case DT_NIL:
    {
      strcpy( achToAppend, "nil" );
    }
    break;

    case DT_INTEGER:
    {
      sprintf( achToAppend, 
               "%ld", 
               m_poVirtualChip->m_psStackPointer[ 0 ].v.v_integer );
    }
    break;

    case DT_STRING:
    {
      char* pChar  = strgetdata( &m_poVirtualChip->m_psStackPointer[ 0 ] );
      int   len    = strgetsize( &m_poVirtualChip->m_psStackPointer[ 0 ] );
      strncpy( achToAppend, pChar, len );
      achToAppend[ len ] = 0;
    }
    break;

    case DT_DWORD:
    {
      sprintf( achToAppend,
               "%ld",
                m_poVirtualChip->m_psStackPointer[ 0 ].v.v_dword );
    }
    break;

    case DT_DOUBLE:
    {
      sprintf( achToAppend,
               "% 10.10f",
               m_poVirtualChip->m_psStackPointer[ 0 ].v.v_double );
    }
    break;

    case DT_BYTE:
    {
      sprintf( achToAppend,
              "%s",
              ( m_poVirtualChip->m_psStackPointer[ 0 ].v.v_byte != 0 ) ? "true" : "false" );
    }
    break;

    case DT_DATETIME:
    {
      SYSTEMTIME xTime = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_datetime; 

      sprintf( achToAppend, 
               "%02u/%02u/%04u %02u:%02u:%02u %s",
               xTime.wMonth,
               xTime.wDay,
               xTime.wYear,
               xTime.wHour,
               xTime.wMinute,
               xTime.wSecond,
               xTime.wHour > 12 ? "PM" : "AM" );
    }
    break;
  }
  
  bool bResult = poDelimFile->SetData( iCol, iRow, achToAppend );

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], bResult );
  m_poVirtualChip->m_psStackPointer += iArgc;

  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerDelimFileSetValueAt"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerDelimFileClearData

       DESCRIPTION:  clears the data from the delimiter object

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerDelimFileClearData( int iArgc )
{
  m_poInterpreter->SetLastCall( "DelimFileClearData" );

  VerifyRunLineArguments( iArgc, 1 );
  VerifyElementType( 0, DT_DELIMITED_FILE );
  
  VMFileParser* poDelimFile = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_delimitedfile;

  poDelimFile->ClearData();

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], true );
  m_poVirtualChip->m_psStackPointer += iArgc;

  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerDelimFileClearData"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerDelimFileCreateVariable

       DESCRIPTION:  gets row count in the rowset

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerDelimFileCreateVariable( int iArgc )
{
  m_poInterpreter->SetLastCall( "DelimFileCreateColumn" );

  VerifyRunLineArguments( iArgc, 4 );
  VerifyElementType( 3, DT_DELIMITED_FILE );
  VerifyElementType( 2, DT_STRING         );
  VerifyElementType( 1, DT_STRING         );
  VerifyElementType( 0, DT_INTEGER        );
  
  VMFileParser* poDelimFile  = m_poVirtualChip->m_psStackPointer[ 3 ].v.v_delimitedfile;
  char*         pchColName   = m_poVirtualChip->m_psStackPointer[ 2 ].v.v_string->str_data;       
  char*         pchInitValue = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_string->str_data;
  int           iRows        = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_integer;       
  std::string   oInitValue;

  oInitValue.assign( pchInitValue );
  bool bResult = poDelimFile->CreateVariable( pchColName, oInitValue, iRows );

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], bResult );
  m_poVirtualChip->m_psStackPointer += iArgc;

  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerDelimFileCreateVariable"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerDelimFileDeleteVariable

       DESCRIPTION:  deletes a column from the delimiter object

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerDelimFileDeleteVariable( int iArgc )
{
  m_poInterpreter->SetLastCall( "DelimFileDeleteColumn" );

  VerifyRunLineArguments( iArgc, 2 );
  VerifyElementType( 1, DT_DELIMITED_FILE );
  VerifyElementType( 0, DT_INTEGER        );
  
  VMFileParser* poDelimFile = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_delimitedfile;
  int           iIndex      = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_integer;

  bool bResult = poDelimFile->DeleteVariable( iIndex );

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], bResult );
  m_poVirtualChip->m_psStackPointer += iArgc;

  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerDelimFileDeleteVariable"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerDelimFileGetValueAt

       DESCRIPTION:  gets the value at the specified location in the delim obj
                     the data is returned in the requested value type

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerDelimFileGetValueAt( int iArgc )
{
  m_poInterpreter->SetLastCall( "DelimFileGetValueAt" );

  VerifyRunLineArguments( iArgc, 4 );
  VerifyElementType( 3, DT_DELIMITED_FILE );
  VerifyElementType( 2, DT_INTEGER        );
  VerifyElementType( 1, DT_INTEGER        );
  VerifyElementType( 0, DT_STRING         );

  VMFileParser* poDelimFile  = m_poVirtualChip->m_psStackPointer[ 3 ].v.v_delimitedfile;
  int           iRow         = m_poVirtualChip->m_psStackPointer[ 2 ].v.v_integer;
  int           iCol         = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_integer;
  char*         pchCast      = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_string->str_data;

  std::string   oValue; 
  int           iResult      = poDelimFile->GetData( iCol, iRow, oValue );

  if ( -1 == iResult )
  {
    set_nil( &m_poVirtualChip->m_psStackPointer[ iArgc ] );
  }
  else
  if ( 0 == strcmp( pchCast, "AsString" ) )
  {
    vmstring* pxResult = AllocateNewString( oValue.length() + 1, true );
    strcpy( pxResult->str_data, oValue.c_str() );
    SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], pxResult );
  }
  else
  if ( 0 == strcmp( pchCast, "AsLong" ) )
  {
    long lResult = atoi( oValue.c_str() );
    SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], lResult );
  }
  else
  if ( 0 == strcmp( pchCast, "AsBool" ) )
  {
    bool bResult = oValue == "1" 
                || oValue == "TRUE" 
                || oValue == "true" 
                || oValue == "YES" 
                || oValue == "yes" 
                || oValue == "ON" 
                || oValue == "on";
    SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], bResult );
  }
  else
  if ( 0 == strcmp( pchCast, "AsDate" ) )
  {
    VMDateTime oDate( oValue.c_str() );
    SYSTEMTIME xDate = oDate.GetTime(); 
    SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], xDate );
  }
  else
  if ( 0 == strcmp( pchCast, "AsDouble" ) )
  {
    double dblResult = atof( oValue.c_str() );
    SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], dblResult );
  }
  else
  {
    vmstring* pxResult = AllocateNewString( oValue.length() + 1, true );
    strcpy( pxResult->str_data, oValue.c_str() );
    SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], pxResult );
  }

  m_poVirtualChip->m_psStackPointer += iArgc;
  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerDelimFileGetValueAt"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerDelimFileGetLastError

       DESCRIPTION:  gets last error stored in the delimiter object

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerDelimFileGetLastError( int iArgc )
{
  m_poInterpreter->SetLastCall( "DelimFileGetLastError" );

  VerifyRunLineArguments( iArgc, 1 );
  VerifyElementType( 0, DT_FILE_BUILDER );
  
  VMFileParser* poDelimFile = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_delimitedfile;
  vmstring*     pxResult;
	const char*   pchValue = poDelimFile->GetLastError();

  pxResult = AllocateNewString( strlen( pchValue ) + 1, true );
  strcpy( pxResult->str_data, pchValue );

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], pxResult );
  m_poVirtualChip->m_psStackPointer += iArgc;

  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerDelimFileGetLastError"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerDelimFileGetSampleCount

       DESCRIPTION:  gets row count in the rowset

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerDelimFileGetSampleCount( int iArgc )
{
  m_poInterpreter->SetLastCall( "DelimFileGetRowCount" );

  VerifyRunLineArguments( iArgc, 1 );
  VerifyElementType( 1, DT_FILE_BUILDER );
  
  VMFileParser* poDelimFile = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_delimitedfile;
  int           iColIndex   = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_integer;

	int iResult = poDelimFile->GetNumberOfSamples( iColIndex );

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], iResult );
  m_poVirtualChip->m_psStackPointer += iArgc;

  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerDelimFileGetSampleCount"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerDelimFileGetVariableCount

       DESCRIPTION:  gets column count in the delim file object

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerDelimFileGetVariableCount( int iArgc )
{
  m_poInterpreter->SetLastCall( "DelimFileGetColCount" );

  VerifyRunLineArguments( iArgc, 1 );
  VerifyElementType( 0, DT_FILE_BUILDER );
  
  VMFileParser* poDelimFile = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_delimitedfile;

	int iResult = poDelimFile->GetNumberOfVariables();

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], iResult );
  m_poVirtualChip->m_psStackPointer += iArgc;

  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerDelimFileGetVariableCount"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerDelimFileGetVariableIndex

       DESCRIPTION:  gets the column index for the named column

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerDelimFileGetVariableIndex( int iArgc )
{
  m_poInterpreter->SetLastCall( "DelimFileGetColIndexByName" );

  VerifyRunLineArguments( iArgc, 2 );
  VerifyElementType( 1, DT_FILE_BUILDER );
  VerifyElementType( 0, DT_STRING       );
  
  VMFileParser* poDelimFile = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_delimitedfile;
  char*         pchColName  = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_string->str_data;

	int iResult = poDelimFile->GetVariableIndex( pchColName );

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], iResult );
  m_poVirtualChip->m_psStackPointer += iArgc;

  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerDelimFileGetVariableIndex"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerDelimFileGetVariableName

       DESCRIPTION:  gets the user assigned name to a specific column

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerDelimFileGetVariableName( int iArgc )
{
  m_poInterpreter->SetLastCall( "DelimFileGetColNameByIndex" );

  VerifyRunLineArguments( iArgc, 2 );
  VerifyElementType( 1, DT_FILE_BUILDER );
  VerifyElementType( 0, DT_INTEGER      );
  
  VMFileParser* poDelimFile = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_delimitedfile;
  int           iIndex      = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_integer;
  std::string   oName;
  vmstring*     pxResult;

  bool bResult = ( -1 != poDelimFile->GetVariableName( iIndex, oName ) );

  if ( bResult )
  {
    pxResult = AllocateNewString( oName.length() + 1, true );
    strcpy( pxResult->str_data, oName.c_str() );
  }
  else
  {
    pxResult = AllocateNewString( 2, true );
    strcpy( pxResult->str_data, "" );
  }

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], pxResult );
  m_poVirtualChip->m_psStackPointer += iArgc;

  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerDelimFileGetVariableName"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerDelimFileLoadFile

       DESCRIPTION:  loads the delim object from a file

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerDelimFileLoadFile( int iArgc )
{
  m_poInterpreter->SetLastCall( "DelimFileLoad" );

  VerifyRunLineArguments( iArgc, 2 );
  VerifyElementType( 1, DT_DELIMITED_FILE );
  VerifyElementType( 0, DT_STRING         );

  VMFileParser* poDelimFile  = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_delimitedfile;
  char*         pchFileName  = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_string->str_data;
  
  bool bResult = poDelimFile->ReadFile( pchFileName );

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], bResult );
  m_poVirtualChip->m_psStackPointer += iArgc;

  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerDelimFileLoadFile"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerDelimFileSetDelimiter

       DESCRIPTION:  sets the field delimiter in place in the delimiter obj

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerDelimFileSetDelimiter( int iArgc )
{
  m_poInterpreter->SetLastCall( "DelimFileSetDelimiter" );

  VerifyRunLineArguments( iArgc, 2 );
  VerifyElementType( 1, DT_DELIMITED_FILE );
  VerifyElementType( 0, DT_STRING         );

  VMFileParser* poDelimFile  = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_delimitedfile;
  char*         pchDelimiter = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_string->str_data;
  
  poDelimFile->SetDelimiter( pchDelimiter );

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], true );
  m_poVirtualChip->m_psStackPointer += iArgc;

  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerDelimFileSetDelimiter"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerDelimFileSetReadFlags

       DESCRIPTION:  sets the flags in force in the delim object

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerDelimFileSetReadFlags( int iArgc )
{
  m_poInterpreter->SetLastCall( "DelimFileSetFlags" );

  VerifyRunLineArguments( iArgc, 2 );
  VerifyElementType( 1, DT_DELIMITED_FILE );
  VerifyElementType( 0, DT_INTEGER        );

  VMFileParser* poDelimFile = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_delimitedfile;
  int           iNewFlags   = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_integer;
  
  poDelimFile->SetReadFlags( iNewFlags );

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], true );
  m_poVirtualChip->m_psStackPointer += iArgc;

  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerDelimFileSetReadFlags"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerDelimFileWriteToFile

       DESCRIPTION:  writes contents of delim file to disk

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerDelimFileWriteToFile( int iArgc )
{
  m_poInterpreter->SetLastCall( "DelimFileWriteToFile" );

  VerifyRunLineArguments( iArgc, 3 );
  VerifyElementType( 2, DT_DELIMITED_FILE );
  VerifyElementType( 1, DT_STRING         );
  VerifyElementType( 0, DT_STRING         );

  VMFileParser* poDelimFile  = m_poVirtualChip->m_psStackPointer[ 2 ].v.v_delimitedfile;
  char*         pchFileName  = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_string->str_data;
  char*         pchDelimiter = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_string->str_data;
  
  bool bResult = poDelimFile->WriteFile( pchFileName, pchDelimiter );

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], bResult );
  m_poVirtualChip->m_psStackPointer += iArgc;

  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerDelimFileWriteToFile"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerDelimFileSetReserveBuffer

       DESCRIPTION:  sets the amount of reserved memory in the delim file obj

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerDelimFileSetReserveBuffer( int iArgc )
{
  m_poInterpreter->SetLastCall( "DelimFileSetReserveBuffer" );

  VerifyRunLineArguments( iArgc, 2 );
  VerifyElementType( 1, DT_DELIMITED_FILE );
  VerifyElementType( 0, DT_INTEGER        );

  VMFileParser* poDelimFile = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_delimitedfile;
  int           iSize       = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_integer;
  
  poDelimFile->SetReserve( iSize );

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], true );
  m_poVirtualChip->m_psStackPointer += iArgc;

  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerDelimFileSetReserveBuffer"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerExcelExportSetValueAt

       DESCRIPTION:  sets value at specified cell location

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerExcelExportSetValueAt( int iArgc )
{
  m_poInterpreter->SetLastCall( "ExcelExporterSetValueAt" );

  VerifyRunLineArguments( iArgc, 4 );
  VerifyElementType( 3, DT_EXCEL_EXPORTER );
  VerifyElementType( 2, DT_INTEGER        );
  VerifyElementType( 1, DT_INTEGER        );  

  VMExcelExporter* poExcel  = m_poVirtualChip->m_psStackPointer[ 3 ].v.v_excelwriter;
  int           iRow        = m_poVirtualChip->m_psStackPointer[ 2 ].v.v_integer;
  int           iCol        = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_integer;
  int           iType       = m_poVirtualChip->m_psStackPointer[ 0 ].v_type;

  char          achToAppend[ 257 ];

  switch ( iType )
  {
    case DT_NIL:
    {
      strcpy( achToAppend, "nil" );
      poExcel->operator()( iRow, iCol ) = achToAppend;
    }
    break;

    case DT_INTEGER:
    {
      poExcel->operator()( iRow, iCol ) = (double)m_poVirtualChip->m_psStackPointer[ 0 ].v.v_integer;
    }
    break;

    case DT_STRING:
    {
      char* pChar  = strgetdata( &m_poVirtualChip->m_psStackPointer[ 0 ] );
      int   len    = strgetsize( &m_poVirtualChip->m_psStackPointer[ 0 ] );
      strncpy( achToAppend, pChar, len );
      achToAppend[ len ] = 0;
      poExcel->operator()( iRow, iCol ) = achToAppend;
    }
    break;

    case DT_DOUBLE:
    {
      poExcel->operator()( iRow, iCol ) =  m_poVirtualChip->m_psStackPointer[ 0 ].v.v_double;
    }
    break;

    case DT_BYTE:
    {
      sprintf( achToAppend,
              "%s",
              ( m_poVirtualChip->m_psStackPointer[ 0 ].v.v_byte != 0 ) ? "true" : "false" );
      poExcel->operator()( iRow, iCol ) = achToAppend;
    }
    break;

    case DT_DATETIME:
    {
      SYSTEMTIME xTime = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_datetime; 

      sprintf( achToAppend, 
               "%02u/%02u/%04u %02u:%02u:%02u %s",
               xTime.wMonth,
               xTime.wDay,
               xTime.wYear,
               xTime.wHour,
               xTime.wMinute,
               xTime.wSecond,
               xTime.wHour > 12 ? "PM" : "AM" );
      poExcel->operator()( iRow, iCol ) = achToAppend;
    }
    break;
  }
  
  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], true );
  m_poVirtualChip->m_psStackPointer += iArgc;

  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerExcelExportSetValueAt"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerExcelExportGetValueAt

       DESCRIPTION:  gets the value at the specified location in the excel
                     exporter
                     the data is returned in the requested value type

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerExcelExportGetValueAt( int iArgc )
{
  m_poInterpreter->SetLastCall( "ExcelExporterGetValueAt" );

  VerifyRunLineArguments( iArgc, 4 );
  VerifyElementType( 3, DT_EXCEL_EXPORTER );
  VerifyElementType( 2, DT_INTEGER        );
  VerifyElementType( 1, DT_INTEGER        );
  VerifyElementType( 0, DT_STRING         );

  VMExcelExporter* poExcel  = m_poVirtualChip->m_psStackPointer[ 3 ].v.v_excelwriter;
  int             iRow      = m_poVirtualChip->m_psStackPointer[ 2 ].v.v_integer;
  int             iCol      = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_integer;
  char*           pchCast   = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_string->str_data;

  if ( 0 == strcmp( pchCast, "AsString" ) )
  {
    VMExcelCellVariant oValue   = poExcel->operator()( iRow, iCol );
    const char*        pchValue = ( const char*) oValue;

    vmstring* pxResult = AllocateNewString( strlen( pchValue ) + 1, true );
    strcpy( pxResult->str_data, pchValue );
    SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], pxResult );
  }
  else
  if ( 0 == strcmp( pchCast, "AsDouble" ) )
  {
    VMExcelCellVariant oValue = poExcel->operator()( iRow, iCol );
    double dblResult = (double)oValue;
    SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], dblResult );
  }
  else
  {
    VMExcelCellVariant oValue   = poExcel->operator()( iRow, iCol );
    const char*        pchValue = ( const char*) oValue;

    vmstring* pxResult = AllocateNewString( strlen( pchValue ) + 1, true );
    strcpy( pxResult->str_data, pchValue );
    SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], pxResult );
  }

  m_poVirtualChip->m_psStackPointer += iArgc;
  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerExcelExportGetValueAt"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerExcelExportWriteFile

       DESCRIPTION:  pushes the given excel exporter to the file specified

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerExcelExportWriteFile( int iArgc )
{
  m_poInterpreter->SetLastCall( "ExcelExporterWriteToFile" );

  VerifyRunLineArguments( iArgc, 2 );
  VerifyElementType( 1, DT_EXCEL_EXPORTER );
  VerifyElementType( 0, DT_STRING         );

  VMExcelExporter* poExcel  = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_excelwriter;
  char*            pchFile  = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_string->str_data;

  FILE* pFile = fopen( pchFile, "wb" );
  poExcel->Write( pFile );
  fclose( pFile );

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], true );

  m_poVirtualChip->m_psStackPointer += iArgc;
  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerExcelExportWriteFile"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerExcelExportSetCellStyle

       DESCRIPTION:  sets the cell style for the specified cell

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerExcelExportSetCellStyle( int iArgc )
{
  m_poInterpreter->SetLastCall( "ExcelExporterSetCellStyle" );

  VerifyRunLineArguments( iArgc, 4 );
  VerifyElementType( 3, DT_EXCEL_EXPORTER );
  VerifyElementType( 2, DT_INTEGER        );
  VerifyElementType( 1, DT_INTEGER        );
  VerifyElementType( 0, DT_INTEGER        );

  VMExcelExporter* poExcel = m_poVirtualChip->m_psStackPointer[ 3 ].v.v_excelwriter;
  int              iRow    = m_poVirtualChip->m_psStackPointer[ 2 ].v.v_integer;
  int              iCol    = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_integer;
  int              iStyle  = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_integer;

  poExcel->operator()( iRow, iCol ).setBorder( iStyle );

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], true );
  m_poVirtualChip->m_psStackPointer += iArgc;
  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerExcelExportSetCellStyle"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerExcelExportSetCellAlign

       DESCRIPTION:  sets the cell style for the specified cell

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerExcelExportSetCellAlign( int iArgc )
{
  m_poInterpreter->SetLastCall( "ExcelExporterSetCellAlign" );

  VerifyRunLineArguments( iArgc, 4 );
  VerifyElementType( 3, DT_EXCEL_EXPORTER );
  VerifyElementType( 2, DT_INTEGER        );
  VerifyElementType( 1, DT_INTEGER        );
  VerifyElementType( 0, DT_INTEGER        );

  VMExcelExporter* poExcel = m_poVirtualChip->m_psStackPointer[ 3 ].v.v_excelwriter;
  int              iRow    = m_poVirtualChip->m_psStackPointer[ 2 ].v.v_integer;
  int              iCol    = m_poVirtualChip->m_psStackPointer[ 1 ].v.v_integer;
  int              iStyle  = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_integer;

  poExcel->operator()( iRow, iCol ).setAlignament( iStyle );

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], true );
  m_poVirtualChip->m_psStackPointer += iArgc;
  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerExcelExportSetCellAlign"
/*****************************************************************************/


/*****************************************************************************/
/*

     FUNCTION NAME:  VMVirtualOpSys::HandlerDiskFreeBytes

       DESCRIPTION:  gets free bytes on a drive

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerDiskFreeBytes( int iArgc )
{
  m_poInterpreter->SetLastCall( "DiskFreeBytes" );

  VerifyRunLineArguments( iArgc, 1 );
  VerifyElementType( 0, DT_STRING );

  char* pchDisk = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_string->str_data;
  
  DWORD   dwSectorsPerCluster = 0;
  DWORD   dwBytesPerSector    = 0;
  DWORD   dwFreeClusters      = 0;
  DWORD   dwTotalClusters     = 0;
  double  dblFreeBytes        = 0;
  double  dblTotalBytes       = 0;
  double  dblPercent          = 0;

  if ( ::GetDiskFreeSpace( pchDisk, 
                           &dwSectorsPerCluster, 
                           &dwBytesPerSector, 
                           &dwFreeClusters, 
                           &dwTotalClusters ) )
  {
    __int64 iBytesPerCluster = dwBytesPerSector * dwSectorsPerCluster;
    dblFreeBytes   = static_cast< double >( iBytesPerCluster * dwFreeClusters );
  } 

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], dblFreeBytes );
  m_poVirtualChip->m_psStackPointer += iArgc;
  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerDiskFreeBytes"
/*****************************************************************************/


/*****************************************************************************/
/*

     FUNCTION NAME:  VMVirtualOpSys::HandlerDiskTotalBytes

       DESCRIPTION:  gets total bytes on a drive

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerDiskTotalBytes( int iArgc )
{
  m_poInterpreter->SetLastCall( "DiskTotalBytes" );

  VerifyRunLineArguments( iArgc, 1 );
  VerifyElementType( 0, DT_STRING );

  char* pchDisk = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_string->str_data;

  DWORD   dwSectorsPerCluster = 0;
  DWORD   dwBytesPerSector    = 0;
  DWORD   dwFreeClusters      = 0;
  DWORD   dwTotalClusters     = 0;
  double  dblFreeBytes        = 0;
  double  dblTotalBytes       = 0;

  if ( ::GetDiskFreeSpace( pchDisk, 
                           &dwSectorsPerCluster, 
                           &dwBytesPerSector, 
                           &dwFreeClusters, 
                           &dwTotalClusters ) )
  {
    __int64 iBytesPerCluster = dwBytesPerSector * dwSectorsPerCluster;
    dblFreeBytes   = static_cast< double >( iBytesPerCluster * dwFreeClusters  );
    dblTotalBytes  = static_cast< double >( iBytesPerCluster * dwTotalClusters );
  } 

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], dblTotalBytes );
  m_poVirtualChip->m_psStackPointer += iArgc;
  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerDiskTotalBytes"
/*****************************************************************************/


/*****************************************************************************/
/*

     FUNCTION NAME:  VMVirtualOpSys::HandlerDiskPercentFree

       DESCRIPTION:  

             INPUT:  int iArgc - 
            OUTPUT:  none

           RETURNS:  int  - 
*/
int VMVirtualOpSys::HandlerDiskPercentFree( int iArgc )
{
  m_poInterpreter->SetLastCall( "DiskPercentFree" );

  VerifyRunLineArguments( iArgc, 1 );
  VerifyElementType( 0, DT_STRING );

  char* pchDisk = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_string->str_data;

  DWORD   dwSectorsPerCluster = 0;
  DWORD   dwBytesPerSector    = 0;
  DWORD   dwFreeClusters      = 0;
  DWORD   dwTotalClusters     = 0;
  __int64 iFreeBytes          = 0;
  __int64 iTotalBytes         = 0;
  bool    bStatus             = true;
  double  dblPercent          = 0;

  if ( ::GetDiskFreeSpace( pchDisk, 
                           &dwSectorsPerCluster, 
                           &dwBytesPerSector, 
                           &dwFreeClusters, 
                           &dwTotalClusters ) )
  {
    __int64 iBytesPerCluster = dwBytesPerSector * dwSectorsPerCluster;
    iFreeBytes   = iBytesPerCluster * dwFreeClusters;
    iTotalBytes  = iBytesPerCluster * dwTotalClusters;
    dblPercent   = ( (double) dwFreeClusters / dwTotalClusters ) * 100.0;
  } 

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], dblPercent );
  m_poVirtualChip->m_psStackPointer += iArgc;
  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerDiskPercentFree"
/*****************************************************************************/


/*****************************************************************************/
/*

     FUNCTION NAME:  VMVirtualOpSys::HandlerDiskPercentFull

       DESCRIPTION:  

             INPUT:  int iArgc - 
            OUTPUT:  none

           RETURNS:  int  - 
*/
int VMVirtualOpSys::HandlerDiskPercentFull( int iArgc )
{
  m_poInterpreter->SetLastCall( "DiskPercentFull" );

  VerifyRunLineArguments( iArgc, 1 );
  VerifyElementType( 0, DT_STRING );

  char* pchDisk = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_string->str_data;

  DWORD   dwSectorsPerCluster = 0;
  DWORD   dwBytesPerSector    = 0;
  DWORD   dwFreeClusters      = 0;
  DWORD   dwTotalClusters     = 0;
  __int64 iFreeBytes          = 0;
  __int64 iTotalBytes         = 0;
  bool    bStatus             = true;
  double  dblPercent          = 0;

  if ( ::GetDiskFreeSpace( pchDisk, 
                           &dwSectorsPerCluster, 
                           &dwBytesPerSector, 
                           &dwFreeClusters, 
                           &dwTotalClusters ) )
  {
    __int64 iBytesPerCluster = dwBytesPerSector * dwSectorsPerCluster;
    iFreeBytes   = iBytesPerCluster * dwFreeClusters;
    iTotalBytes  = iBytesPerCluster * dwTotalClusters;
    dblPercent   = ( (double) dwFreeClusters / dwTotalClusters ) * 100.0;
  } 

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], 100.00 - dblPercent );
  m_poVirtualChip->m_psStackPointer += iArgc;
  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerDiskPercentFull"
/*****************************************************************************/


/*****************************************************************************/
/*

     FUNCTION NAME:  VMVirtualOpSys::HandlerDiskIsRemovable

       DESCRIPTION:  

             INPUT:  int iArgc - 
            OUTPUT:  none

           RETURNS:  int  - 
*/
int VMVirtualOpSys::HandlerDiskIsRemovable( int iArgc )
{
  m_poInterpreter->SetLastCall( "DiskIsRemovable" );

  VerifyRunLineArguments( iArgc, 1 );
  VerifyElementType( 0, DT_STRING );

  char* pchDisk = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_string->str_data;

  UINT uiType = GetDriveType( pchDisk );

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], uiType == DRIVE_REMOVABLE );
  m_poVirtualChip->m_psStackPointer += iArgc;
  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerDiskIsRemovable"
/*****************************************************************************/


/*****************************************************************************/
/*

     FUNCTION NAME:  VMVirtualOpSys::HandlerDiskIsFixedDrive

       DESCRIPTION:  

             INPUT:  int iArgc - 
            OUTPUT:  none

           RETURNS:  int  - 
*/
int VMVirtualOpSys::HandlerDiskIsFixedDrive( int iArgc )
{
  m_poInterpreter->SetLastCall( "DiskIsFixedDrive" );

  VerifyRunLineArguments( iArgc, 1 );
  VerifyElementType( 0, DT_STRING );

  char* pchDisk = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_string->str_data;

  UINT uiType = GetDriveType( pchDisk );

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], uiType == DRIVE_FIXED );
  m_poVirtualChip->m_psStackPointer += iArgc;
  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerDiskIsFixedDrive"
/*****************************************************************************/


/*****************************************************************************/
/*

     FUNCTION NAME:  VMVirtualOpSys::HandlerDiskIsRemoteDrive

       DESCRIPTION:  

             INPUT:  int iArgc - 
            OUTPUT:  none

           RETURNS:  int  - 
*/
int VMVirtualOpSys::HandlerDiskIsRemoteDrive( int iArgc )
{
  m_poInterpreter->SetLastCall( "DiskIsRemoteDrive" );

  VerifyRunLineArguments( iArgc, 1 );
  VerifyElementType( 0, DT_STRING );

  char* pchDisk = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_string->str_data;

  UINT uiType = GetDriveType( pchDisk );

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], uiType == DRIVE_REMOTE );
  m_poVirtualChip->m_psStackPointer += iArgc;
  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerDiskIsRemoteDrive"
/*****************************************************************************/


/*****************************************************************************/
/*

     FUNCTION NAME:  VMVirtualOpSys::HandlerDiskIsCdROM

       DESCRIPTION:  

             INPUT:  int iArgc - 
            OUTPUT:  none

           RETURNS:  int  - 
*/
int VMVirtualOpSys::HandlerDiskIsCdROM( int iArgc )
{
  m_poInterpreter->SetLastCall( "DiskIsCDROM" );

  VerifyRunLineArguments( iArgc, 1 );
  VerifyElementType( 0, DT_STRING );

  char* pchDisk = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_string->str_data;

  UINT uiType = GetDriveType( pchDisk );

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], uiType == DRIVE_CDROM );
  m_poVirtualChip->m_psStackPointer += iArgc;
  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerDiskIsCdROM"
/*****************************************************************************/


/*****************************************************************************/
/*

     FUNCTION NAME:  VMVirtualOpSys::HandlerDiskIsRamDrive

       DESCRIPTION:  

             INPUT:  int iArgc - 
            OUTPUT:  none

           RETURNS:  int  - 
*/
int VMVirtualOpSys::HandlerDiskIsRamDrive( int iArgc )
{
  m_poInterpreter->SetLastCall( "DiskIsRAMDrive" );

  VerifyRunLineArguments( iArgc, 1 );
  VerifyElementType( 0, DT_STRING );

  char* pchDisk = m_poVirtualChip->m_psStackPointer[ 0 ].v.v_string->str_data;

  UINT uiType = GetDriveType( pchDisk );

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], uiType == DRIVE_RAMDISK );
  m_poVirtualChip->m_psStackPointer += iArgc;
  return( 0 );
}
/* End of function "VMVirtualOpSys::HandlerDiskIsRamDrive"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerRebootHost

       DESCRIPTION:  initiates a system shutdown

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerRebootHost( int iArgc )
{
  m_poInterpreter->SetLastCall( "RebootHost" );

  HANDLE           hToken;        // handle to process token 
  TOKEN_PRIVILEGES psPriviledges; // pointer to token structure  
  BOOL             bResult;       // system shutdown flag  
  int              iDelay = 0;
  char             achMsg[ 256 ];

  VerifyRunLineArguments( iArgc, 2 );
  VerifyElementType( 1, DT_INTEGER );
  VerifyElementType( 0, DT_STRING );

  memset( achMsg, 0, sizeof( achMsg ) );
  GetCStyleString( achMsg, 
                   sizeof( achMsg ), 
                   &m_poVirtualChip->m_psStackPointer[0] );
  iDelay = m_poVirtualChip->m_psStackPointer[1].v.v_integer;

  // Get the current process token handle so that this process
  // can gain the shutdown privilege.  
  //
  if ( OpenProcessToken( GetCurrentProcess(), 
                         TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, 
                         &hToken ) )
  {
    // Get the LUID for shutdown privilege.  
    //
    LookupPrivilegeValue( NULL, 
                          SE_SHUTDOWN_NAME,         
                          &psPriviledges.Privileges[0].Luid );  

    psPriviledges.PrivilegeCount = 1;  // one privilege to set    
    psPriviledges.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;  

    // Get shutdown privilege for this process.  
    //
    AdjustTokenPrivileges( hToken, 
                           FALSE, 
                           &psPriviledges, 
                           0,     
                           (PTOKEN_PRIVILEGES) NULL, 
                           0 );
      
    // make sure that this can AdjustTokenPrivileges.  
    //
    if ( GetLastError() == ERROR_SUCCESS ) 
    {
      // Display the shutdown dialog box and start 
      // the time-out countdown.  
      //
      bResult = InitiateSystemShutdown( NULL,          // local maching
                                        achMsg,        // user message
                                        (DWORD)iDelay, // wait for iDelay seconds
                                        FALSE,         // force closed
                                        TRUE );        // reboot....

      if ( bResult ) 
      {
        // Disable shutdown privilege.  
        psPriviledges.Privileges[0].Attributes = 0; 
        AdjustTokenPrivileges( hToken, 
                               FALSE, 
                               &psPriviledges, 
                               0, 
                               (PTOKEN_PRIVILEGES) NULL, 
                               0 );  
      }
    }
  }

  SetValue( &m_poVirtualChip->m_psStackPointer[ iArgc ], true );
  m_poVirtualChip->m_psStackPointer += iArgc;

  return 0;
}
/* End of function "VMVirtualOpSys::HandlerRebootHost"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerExitWindows

       DESCRIPTION:  user wants to close out windows. so let 'em

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerExitWindows( int iArgc )
{
  m_poInterpreter->SetLastCall( "ExitWindows" );

  VerifyRunLineArguments( iArgc, 0 );

  long lReturn = (long)ExitWindows( 0, 0 );

  // send back the return code
  //
  SetValue( &m_poVirtualChip->m_psStackPointer[iArgc], lReturn );
  m_poVirtualChip->m_psStackPointer += iArgc;
  return 0;
}
/* End of function "VMVirtualOpSys::HandlerExitWindows"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMVirtualOpSys::HandlerBeep

       DESCRIPTION:  beeps the box

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerBeep( int iArgc )
{
  m_poInterpreter->SetLastCall( "Beep" );

  VerifyRunLineArguments( iArgc, 2 );
  VerifyElementType( 1, DT_INTEGER );
  VerifyElementType( 0, DT_INTEGER );

  long lBeepTime  = m_poVirtualChip->m_psStackPointer[1].v.v_integer;
  long lBeepFreq  = m_poVirtualChip->m_psStackPointer[0].v.v_integer;

  // Windows NT: Specifies the frequency, in hertz, of the sound. 
  // This parameter must be in the range 37 through 32,767
  //
  if ( lBeepFreq < 37 )
  {
    lBeepFreq = 37;
  }
  else
  if ( lBeepFreq > 32767 )
  {
    lBeepFreq = 32767;
  }

  BOOL bReturn = Beep( (DWORD)lBeepFreq, (DWORD)lBeepTime );

  // send back the return code
  //
  SetValue( &m_poVirtualChip->m_psStackPointer[iArgc], bReturn );
  m_poVirtualChip->m_psStackPointer += iArgc;

  return 0;
}
/* End of function "VMVirtualOpSys::HandlerBeep"
/*****************************************************************************/


/*****************************************************************************/
/*

     FUNCTION NAME:  VMVirtualOpSys::HandlerShellExecute

       DESCRIPTION:  runs shell execute function

             INPUT:  iArgc - the stacked parameter count for this method
            OUTPUT:  

           RETURNS:  0 
*/
int VMVirtualOpSys::HandlerShellExecute( int iArgc )
{
  m_poInterpreter->SetLastCall( "ShellExecute" );

  VerifyRunLineArguments( iArgc, 1 );
  VerifyElementType( 0, DT_STRING );

  const char* pchFile = m_poVirtualChip->m_psStackPointer[1].v.v_string->str_data;

  HINSTANCE result = ::ShellExecute( NULL, _T( "open" ), pchFile, NULL,NULL, SW_SHOW );

  if ( (UINT)result <= HINSTANCE_ERROR )
  {
    TCHAR key[ MAX_PATH + MAX_PATH ] = { _T( '\0' ) };
    TCHAR ext[ _MAX_EXT ] = { _T( '\0' ) };

    _splitpath( pchFile, NULL, NULL, NULL, ext );
			
    VMRegistry oRegistry;
    VMString   oKey;
    VMString   oKey2;

    oRegistry.Connect( HKEY_CLASSES_ROOT );
    oRegistry.GetValue( ext, oKey );

    if ( oRegistry.GetValue( ext, oKey ) ) 
    {
      oKey += "\\shell\\open\\command";

      if ( oRegistry.GetValue( oKey, oKey2 ) == ERROR_SUCCESS ) 
      {
        char   achKey[ (_MAX_PATH + 1 ) * 2 ];
        char*  pos;

        strcpy( achKey, oKey2.Buffer() );

        pos = _tcsstr( achKey, _T( "\"%1\"" ) );

        if ( pos == NULL ) 
        {                       
          pos = strstr( achKey, _T( "%1" ) );
          if ( pos == NULL )
            pos = achKey + strlen( achKey ) - 1;
          else
            *pos = '\0';            
        }
        else
          *pos = '\0';                

        lstrcat( pos, _T( " " ) );
        lstrcat( pos, pchFile );

        ::WinExec( key, SW_SHOW );
      }
    }
    oRegistry.Close();
  }

  // send back the return code
  //
  SetValue( &m_poVirtualChip->m_psStackPointer[iArgc], true );
  m_poVirtualChip->m_psStackPointer += iArgc;

  return 0;
}
/* End of function "VMVirtualOpSys::HandlerShellExecute"
/*****************************************************************************/


/*****************************************************************************/
/* Check-in history */
/*
 *$Log: $
*/
/*****************************************************************************/


By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Web Developer
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions