/// <summary> TCL.Tcl_UntraceVar2 -> untraceVar
    /// 
    /// Untrace a variable, given a two-part name consisting of array
    /// name and element within array. This will Remove a
    /// previously-created trace for a variable.
    /// 
    /// </summary>
    /// <param name="interp">Interpreter containing variable.
    /// </param>
    /// <param name="part1">1st part of the variable name.
    /// </param>
    /// <param name="part2">2nd part of the variable name.
    /// </param>
    /// <param name="flags">misc flags that control the actions of this method.
    /// </param>
    /// <param name="proc">the trace to delete.
    /// </param>

    internal static void untraceVar( Interp interp, string part1, string part2, TCL.VarFlag flags, VarTrace proc )
    {
      Var[] result = null;
      Var var;

      try
      {
        result = lookupVar( interp, part1, part2, flags & ( TCL.VarFlag.GLOBAL_ONLY | TCL.VarFlag.NAMESPACE_ONLY ), null, false, false );
        if ( result == null )
        {
          return;
        }
      }
      catch ( TclException e )
      {
        // FIXME: check for problems in exception in lookupVar

        // We have set throwException argument to false in the
        // lookupVar() call, so an exception should never be
        // thrown.

        throw new TclRuntimeError( "unexpected TclException: " + e.Message, e );
      }

      var = result[0];

      if ( var.traces != null )
      {
        int len = var.traces.Count;
        for ( int i = 0; i < len; i++ )
        {
          TraceRecord rec = (TraceRecord)var.traces[i];
          if ( rec.trace == proc )
          {
            var.traces.RemoveAt( i );
            break;
          }
        }
      }

      // If this is the last trace on the variable, and the variable is
      // unset and unused, then free up the variable.

      if ( var.isVarUndefined() )
      {
        cleanupVar( var, null );
      }
    }
    /// <summary> Untrace a variable whose name is stored in a Tcl object.
    /// 
    /// </summary>
    /// <param name="nameObj">name of the variable.
    /// </param>
    /// <param name="trace">the trace to delete.
    /// </param>
    /// <param name="flags">misc flags that control the actions of this method.
    /// </param>

    internal static void untraceVar( Interp interp, TclObject nameObj, TCL.VarFlag flags, VarTrace proc )
    {

      untraceVar( interp, nameObj.ToString(), null, flags, proc );
    }
    /// <summary> Untrace a variable.
    /// 
    /// </summary>
    /// <param name="name">name of the variable.
    /// </param>
    /// <param name="trace">the trace to delete.
    /// </param>
    /// <param name="flags">misc flags that control the actions of this method.
    /// </param>

    internal static void untraceVar( Interp interp, string name, TCL.VarFlag flags, VarTrace proc )
    {
      untraceVar( interp, name, null, flags, proc );
    }
    /// <summary> TCL.Tcl_TraceVar2 -> traceVar
    /// 
    /// Trace a variable, given a two-part name consisting of array
    /// name and element within array.
    /// 
    /// </summary>
    /// <param name="part1">1st part of the variable name.
    /// </param>
    /// <param name="part2">2nd part of the variable name.
    /// </param>
    /// <param name="flags">misc flags that control the actions of this method.
    /// </param>
    /// <param name="trace">the trace to comand to add.
    /// </param>

    internal static void traceVar( Interp interp, string part1, string part2, TCL.VarFlag flags, VarTrace proc )
    {
      Var[] result;
      Var var, array;

      // FIXME: what about the exception problem here?
      result = lookupVar( interp, part1, part2, ( flags | TCL.VarFlag.LEAVE_ERR_MSG ), "trace", true, true );
      if ( result == null )
      {
        throw new TclException( interp, "" );
      }

      var = result[0];
      array = result[1];

      // Set up trace information.

      if ( var.traces == null )
      {
        var.traces = new ArrayList( 10 );
      }

      var rec = new TraceRecord();
      rec.trace = proc;
      rec.flags = flags & ( TCL.VarFlag.TRACE_READS | TCL.VarFlag.TRACE_WRITES | TCL.VarFlag.TRACE_UNSETS | TCL.VarFlag.TRACE_ARRAY );

      var.traces.Insert( 0, rec );


      // FIXME: is this needed ?? It was in Jacl but not 8.1

      /*
      // When inserting a trace for an array on an UNDEFINED variable,
      // the search IDs for that array are reset.

      if (array != null && var.isVarUndefined()) {
      array.sidVec = null;
      }
      */
    }
 public void untraceVar( string part1, string part2, VarTrace trace, TCL.VarFlag flags )
 // OR-ed collection of bits describing current
 // trace, including any of TCL.VarFlag.TRACE_READS,
 // TCL.VarFlag.TRACE_WRITES, TCL.VarFlag.TRACE_UNSETS,
 // TCL.VarFlag.GLOBAL_ONLY and TCL.VarFlag.NAMESPACE_ONLY.
 {
   Var.untraceVar( this, part1, part2, flags, trace );
 }
 public void traceVar( string part1, string part2, VarTrace trace, TCL.VarFlag flags )
 {
   Var.traceVar( this, part1, part2, flags, trace );
 }
 public void traceVar( string name, VarTrace trace, TCL.VarFlag flags )
 {
   Var.traceVar( this, name, flags, trace );
 }
 public void traceVar( TclObject nameObj, VarTrace trace, TCL.VarFlag flags )
 {
   Var.traceVar( this, nameObj, flags, trace );
 }