/// <summary>
    /// Drops the item.
    /// </summary>
    /// <param name="context">The propositional context</param>
    /// <param name="items">The direct objects,  indirect objects, and other noun phrase</param>
    /// <param name="src">The line number it was invoked</param>
    /// <param name="err">Where to place any descriptive error messages</param>
    /// <returns>True if was able interpret (it was sensible, even though can't be done), or false if not syntactically sensible</returns>
    bool drop(propositionContext context, List<object> items, SrcInFile src, Err err)
    {
        var from = (ZObject) player;
          // Check that we are holding the items
          List<ZObject> notHolding = new List<ZObject>();
          foreach (var item in items)
          {
         if (item is ZObject)
         {
            if (!((ZObject)item).isDescendentOf(from))
               notHolding.Add((ZObject)item);
         }
         else
         {
            // Format an error message
            err . linkTo(src);
            err.SB.AppendFormat("That doesn't makes sense... it isn't even a thing we can hold..");
            return false;
         }
          }
          if (notHolding.Count > 0)
          {
         // Not all of the items is there
         // Format an error message
         err . linkTo(src);
         err . SB . AppendFormat("{0} is not holding ", from.shortDescription);
         bool needComma = false;
         foreach (var item in notHolding)
         {
            // todo: add and
            err.SB.AppendFormat(needComma?", {0}":"{0}", item.shortDescription);
            needComma = true;
         }
         return false;
          }

          // Drop each of the items;
          // we do this by moving each of the items to the parent
          return move(((ZObject) player).Parent, items, src, err);
    }
   /// <summary>
   /// This is used to invoked the handler for the verb
   /// </summary>
   /// <param name="stmt">The statment to interpret</param>
   /// <param name="line">The line number it was invoked</param>
   /// <param name="err">Where to place any descriptive error messages</param>
   /// <returns>True on success, false on error</returns>
   bool interp(propositionContext ctxt,Lexer lexer, Err err)
   {
      // A reference to where the statement was made
      var src = new SrcInFile(null, lexer.Line);
      // See if there is a first noun, to whom the message is addressed
      var addressedTo = player;
      int matchLength  = 0;
      LexState lexerState = null;
      var tmp = matchInContext(((ZObject) player), lexer, out matchLength,
         ref lexerState);
      if (null != tmp && tmp is ZObject)
      {
         // Use the new object as the item to be commanded
         addressedTo = (ZObject) tmp;
         // Move past the words in that subphrase
         if (null != lexerState)
            lexer.Restore(lexerState);
      }

      // The handler for the different number of arguments
      dStatement[] handlers = null;

      // Find a matching verb phrase
      var phrase = findVerbPhrase(lexer);

      // Get the noun phrases
      var args = getNounPhrases(lexer, (ZObject) player, err);
      var n = null == args? 0: args.Count;

      // See if we need to guess the handler for the noun
      if (null == phrase)
      {
         // If there was nothing resolved about the nouns
         if (null == args)
            args = new List<object>();
         if (addressedTo != player)
         {
            // Move the "addressed to" back to the front
            addressedTo = player;
            args.Insert(0, tmp);
            n = args.Count;
         }

         // See if it said nothing
         if (0 == args.Count)
            return false;

         // See if the first item is a 
         tmp = args[0];

         // If it is a direction roll it around
         if (tmp is ZObject && !isKind((ZObject) tmp, dirKind))
         {
            // Format an error message
            err . linkTo(src);
            err . SB . AppendFormat("What do you mean?");
            return false;
         }

         // It is a direction 
         // Ok, lets just make it go?
         phrase = findVerbPhrase("go");
      }

      // If can't find the verb at all, complain
      if (null == phrase || !verbs.TryGetValue(phrase, out handlers))
      {
         // Format an error message
         err . linkTo(src);
         err . SB . AppendFormat("The verb isn't understood.");
         return false;
      }

      // If there isn't a form for that number of verbs, complain
      var h = n >= handlers . Length ? null : handlers[n];
      if (null == h)
      {
         err . linkTo(src);
         err . SB . AppendFormat("Verb '{0}' isn't known for that arity.", phrase);
         return false;
      }

      // Call the delegate
      return h(ctxt, args, src, err);
   }
    bool move(ZObject to, List<object> items, SrcInFile src, Err err)
    {
        // Check that we have items that we can move
          if (null == items || items.Count < 1)
          {
         // Didn't specify the items to move
         // Format an error message
         err . linkTo(src);
         err . SB . AppendFormat("What should be moved?");
         return false;
          }

          // An array to hold the items that we can move
          var movables = new List<ZObject>();

          // Check that the movement is sane
          foreach (var item in items)
          {
         // Check that it is an item that we can move
         if (!(item is ZObject) || isKind((ZObject)item, cellKind) || isKind((ZObject)item, dirKind))
         {
            // Format an error message
            err . linkTo(src);
            err . SB . AppendFormat("That makes no sense.. we can't move that");
            return true;
         }
         var movable = (ZObject) item;
         if (movable . Parent == to)
         {
            // Format an error message
            err . linkTo(src);
            err . SB . AppendFormat("That makes no sense.. that doesn't really move an item anywhere!");
            return true;
         }
         movables.Add(movable);
          }

          // Reparent each of the items now
          foreach (var item in movables)
          {
         item.Parent.RemoveChild(item);
         to.AddChild(item);
          }

          return true;
    }
 /// <summary>
 /// Would "go" if a direction had been specified
 /// </summary>
 /// <param name="context">The propositional context</param>
 /// <param name="items">The direct objects,  indirect objects, and other noun phrase</param>
 /// <param name="src">The line number it was invoked</param>
 /// <param name="err">Where to place any descriptive error messages</param>
 /// <returns>True if was able interpret (it was sensible, even though can't be don), or false if not syntactically sensible</returns>
 bool goWhere(propositionContext context, List<object> items, SrcInFile src, Err err)
 {
     // Format an error message
       err . linkTo(src);
       err . SB . AppendFormat("Go where?");
       return true;
 }
    /// <summary>
    /// Would "go" if a direction had been specified
    /// </summary>
    /// <param name="context">The propositional context</param>
    /// <param name="items">The direct objects,  indirect objects, and other noun phrase</param>
    /// <param name="src">The line number it was invoked</param>
    /// <param name="err">Where to place any descriptive error messages</param>
    /// <returns>True if was able interpret (it was sensible, even though can't be don), or false if not syntactically sensible</returns>
    bool go(propositionContext context, List<object> items, SrcInFile src, Err err)
    {
        var dest = items[0];
          // Check that the destination is not the same as the current
          if (((ZObject)player).Parent == dest)
          {
         // Format an error message
         err . linkTo(src);
         err . SB . AppendFormat("We are already there.");
         return true;
          }

          // If it is an edge, get the door part
          if (dest is Edge<ZObject>)
          {
         var edge = (Edge<ZObject>) dest;
         // See if we can go into the room
         if (!canTraverseTo(edge))
         {
            // Format an error message
            err . linkTo(src);
            err . SB . AppendFormat("We can't go there.");
            return true;
         }
         dest = edge.sink;
          }

          // Check that the destination is a room
          if (isKind((ZObject)dest, cellKind))
          {
         // Make the move
         ((ZObject)player).Parent.RemoveChild((ZObject)player);
         ((ZObject)dest).AddChild(player);
         return true;
          }
          // See if it refers to a direction
          if (isKind((ZObject)dest, dirKind))
          {
         // Format an error message
         err . linkTo(src);
         err . SB . AppendFormat("There is nothing in the {0} direction!", ((ZObject)dest).shortDescription);
         return true;
          }
          // Format an error message
          err . linkTo(src);
          err . SB . AppendFormat("{0} is not a place!", dest);
          return true;
    }
 /// <summary>
 /// Would drop an item if one had been specified
 /// </summary>
 /// <param name="context">The propositional context</param>
 /// <param name="items">The direct objects,  indirect objects, and other noun phrase</param>
 /// <param name="src">The line number it was invoked</param>
 /// <param name="err">Where to place any descriptive error messages</param>
 /// <returns>True if was able interpret (it was sensible, even though can't be don), or false if not syntactically sensible</returns>
 bool dropWhat(propositionContext context, List<object> items, SrcInFile src, Err err)
 {
     // Format an error message
       err . linkTo(src);
       err . SB . AppendFormat("Drop what?");
       return true;
 }