/// <summary>
 /// Convert a argument to a cut (a single "term") into a IValueBase
 /// </summary>
 /// <param name="cut_argContext"></param>
 /// <returns></returns>
 private IValueBase Convert(FinalStatePatternParser.Cut_argContext cut_argContext)
 {
     if (cut_argContext.cut_name() != null)
     {
         return Convert(cut_argContext.cut_name());
     }
     else if (cut_argContext.cut_number() != null)
     {
         return Convert(cut_argContext.cut_number());
     }
     else if (cut_argContext.function() != null)
     {
         // Should have already been parsed.
         return _parsed_functions.Dequeue();
     }
     else
     {
         throw new InvalidOperationException();
     }
 }
 /// TODO: This extraction code is horrible, and is already discovered by parsing. We should be able to just
 /// AVOID IT. Make the parser better when we learn how to do it.
 /// <summary>
 /// Given an argument, see if there are any FSO's in there.
 /// </summary>
 /// <param name="fa"></param>
 /// <returns></returns>
 private IEnumerable<FinalStateObject> ExtractFSOReferences(FinalStatePatternParser.Function_argContext fa)
 {
     if (fa.cut() != null)
     {
         return ExtractFSOReferences(fa.cut());
     }
     else if (fa.cut_name() != null)
     {
         return ExtractFSOReferences(fa.cut_name());
     }
     else
     {
         throw new InvalidOperationException("Unable to extra information from a function argument.");
     }
 }
        /// <summary>
        /// The user has given us a range cut
        /// </summary>
        /// <param name="context"></param>
        public override void ExitCutRange(FinalStatePatternParser.CutRangeContext context)
        {
            var c1 = new SelectionCriteria();
            var c2 = new SelectionCriteria();

            c1.BinaryRelation = context.BINARY_OP(0).GetText();
            c2.BinaryRelation = context.BINARY_OP(1).GetText();

            c1.FirstArgument = Convert(context.cut_number(0));
            c1.SecondArgument = Convert(context.cut_name());

            c2.FirstArgument = Convert(context.cut_name());
            c2.SecondArgument = Convert(context.cut_number(1));

            _current_criteria.Peek().Add(c1);
            _current_criteria.Peek().Add(c2);

            base.ExitCutRange(context);
        }