From 5f58cc8770b028174797748c71d0f74feff6f786 Mon Sep 17 00:00:00 2001
From: "Kevin P. Fleming" <kpfleming@digium.com>
Date: Mon, 24 Apr 2006 17:41:27 +0000
Subject: [PATCH] Merge Steve Murphy's (murf) complete re-implementation of
 AEL, which is now no longer considered experimental :-)

git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@22273 65c4cc65-6c06-0410-ace0-fbb531ad65f3
---
 CREDITS                                   |    2 +-
 ast_expr2.c                               | 1230 ++++--
 ast_expr2.fl                              |  137 +-
 ast_expr2.h                               |   20 +-
 ast_expr2.y                               |   79 +-
 ast_expr2f.c                              |  841 ++--
 configs/extensions.ael.sample             |  386 +-
 doc/ael.txt                               | 1359 +++++-
 include/asterisk/ael_structs.h            |  178 +
 mxml/configure                            |  640 ++-
 pbx/Makefile                              |   17 +
 pbx/ael/ael-test/ael-test1/extensions.ael |  163 +
 pbx/ael/ael-test/ael-test2/apptest.ael2   |  146 +
 pbx/ael/ael-test/ael-test2/extensions.ael |    8 +
 pbx/ael/ael-test/ael-test3/extensions.ael | 3183 ++++++++++++++
 pbx/ael/ael-test/ael-test3/include1.ael2  |    3 +
 pbx/ael/ael-test/ael-test3/include2.ael2  |    4 +
 pbx/ael/ael-test/ael-test3/include3.ael2  |    2 +
 pbx/ael/ael-test/ael-test3/include4.ael2  |    2 +
 pbx/ael/ael-test/ael-test3/include5.ael2  |    1 +
 pbx/ael/ael-test/ael-test4/apptest.ael2   |  146 +
 pbx/ael/ael-test/ael-test4/extensions.ael |    8 +
 pbx/ael/ael-test/ael-test5/extensions.ael |  833 ++++
 pbx/ael/ael-test/ael-test6/extensions.ael |  833 ++++
 pbx/ael/ael-test/ael-test7/extensions.ael |  460 ++
 pbx/ael/ael-test/ref.ael-test1            |   11 +
 pbx/ael/ael-test/ref.ael-test2            |   15 +
 pbx/ael/ael-test/ref.ael-test3            |   18 +
 pbx/ael/ael-test/ref.ael-test4            |   15 +
 pbx/ael/ael-test/ref.ael-test5            |    9 +
 pbx/ael/ael-test/ref.ael-test6            |   20 +
 pbx/ael/ael-test/ref.ael-test7            |   13 +
 pbx/ael/ael-test/runtests                 |   14 +
 pbx/ael/ael-test/setref                   |    7 +
 pbx/ael/ael.flex                          |  633 +++
 pbx/ael/ael.tab.c                         | 3192 ++++++++++++++
 pbx/ael/ael.tab.h                         |  147 +
 pbx/ael/ael.y                             |  705 +++
 pbx/ael/ael_lex.c                         | 2996 +++++++++++++
 pbx/pbx_ael.c                             | 4708 ++++++++++++++++-----
 utils/Makefile                            |   16 +
 utils/ael_main.c                          |  264 ++
 utils/expr2.testinput                     |   92 +
 43 files changed, 21282 insertions(+), 2274 deletions(-)
 create mode 100644 include/asterisk/ael_structs.h
 create mode 100644 pbx/ael/ael-test/ael-test1/extensions.ael
 create mode 100644 pbx/ael/ael-test/ael-test2/apptest.ael2
 create mode 100644 pbx/ael/ael-test/ael-test2/extensions.ael
 create mode 100755 pbx/ael/ael-test/ael-test3/extensions.ael
 create mode 100644 pbx/ael/ael-test/ael-test3/include1.ael2
 create mode 100644 pbx/ael/ael-test/ael-test3/include2.ael2
 create mode 100644 pbx/ael/ael-test/ael-test3/include3.ael2
 create mode 100644 pbx/ael/ael-test/ael-test3/include4.ael2
 create mode 100644 pbx/ael/ael-test/ael-test3/include5.ael2
 create mode 100644 pbx/ael/ael-test/ael-test4/apptest.ael2
 create mode 100644 pbx/ael/ael-test/ael-test4/extensions.ael
 create mode 100644 pbx/ael/ael-test/ael-test5/extensions.ael
 create mode 100644 pbx/ael/ael-test/ael-test6/extensions.ael
 create mode 100644 pbx/ael/ael-test/ael-test7/extensions.ael
 create mode 100644 pbx/ael/ael-test/ref.ael-test1
 create mode 100644 pbx/ael/ael-test/ref.ael-test2
 create mode 100644 pbx/ael/ael-test/ref.ael-test3
 create mode 100644 pbx/ael/ael-test/ref.ael-test4
 create mode 100644 pbx/ael/ael-test/ref.ael-test5
 create mode 100644 pbx/ael/ael-test/ref.ael-test6
 create mode 100644 pbx/ael/ael-test/ref.ael-test7
 create mode 100755 pbx/ael/ael-test/runtests
 create mode 100755 pbx/ael/ael-test/setref
 create mode 100644 pbx/ael/ael.flex
 create mode 100644 pbx/ael/ael.tab.c
 create mode 100644 pbx/ael/ael.tab.h
 create mode 100644 pbx/ael/ael.y
 create mode 100644 pbx/ael/ael_lex.c
 create mode 100644 utils/ael_main.c
 create mode 100644 utils/expr2.testinput

diff --git a/CREDITS b/CREDITS
index 809e7b44e3..4a24a7af8d 100644
--- a/CREDITS
+++ b/CREDITS
@@ -76,7 +76,7 @@ Olle E. Johansson - SIP RFC compliance, documentation and testing, testing, test
 Steve Kann - new jitter buffer for IAX2
 	stevek@stevek.com
 Constantine Filin - major contributions to the Asterisk Realtime Architecture
-Steve Murphy - privacy support
+Steve Murphy - privacy support, $[ ] parser upgrade, AEL2 parser upgrade
 Claude Patry - bug fixes, feature enhancements, and bug marshalling
 	cpatry@gmail.com
 
diff --git a/ast_expr2.c b/ast_expr2.c
index 6b2bd603b3..0ddb1e4ff9 100644
--- a/ast_expr2.c
+++ b/ast_expr2.c
@@ -1,7 +1,7 @@
-/* A Bison parser, made by GNU Bison 2.1.  */
+/* A Bison parser, made by GNU Bison 2.1a.  */
 
 /* Skeleton parser for Yacc-like parsing with Bison,
-   Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+   Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -23,8 +23,8 @@
    This special exception was added by the Free Software Foundation
    in version 1.24 of Bison.  */
 
-/* Written by Richard Stallman by simplifying the original so called
-   ``semantic'' parser.  */
+/* C LALR(1) parser skeleton written by Richard Stallman, by
+   simplifying the original so-called "semantic" parser.  */
 
 /* All symbols defined below should begin with yy or YY, to avoid
    infringing on user name space.  This should be done even for local
@@ -37,7 +37,7 @@
 #define YYBISON 1
 
 /* Bison version.  */
-#define YYBISON_VERSION "2.1"
+#define YYBISON_VERSION "2.1a"
 
 /* Skeleton name.  */
 #define YYSKELETON_NAME "yacc.c"
@@ -134,6 +134,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <locale.h>
+#include <unistd.h>
 #include <ctype.h>
 #if !defined(SOLARIS) && !defined(__CYGWIN__)
 #include <err.h>
@@ -168,6 +169,8 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
 #define YYPARSE_PARAM parseio
 #define YYLEX_PARAM ((struct parse_io *)parseio)->scanner
 #define YYERROR_VERBOSE 1
+extern char extra_error_message[4095];
+extern int extra_error_message_supplied;
 
 enum valtype {
 	AST_EXPR_integer, AST_EXPR_numeric_string, AST_EXPR_string
@@ -246,12 +249,7 @@ int		ast_yyerror(const char *,YYLTYPE *, struct parse_io *);
    some useful info about the error. Not as easy as it looks, but it
    is possible. */
 #define ast_yyerror(x) ast_yyerror(x,&yyloc,parseio)
-#define DESTROY(x) { \
-if ((x)->type == AST_EXPR_numeric_string || (x)->type == AST_EXPR_string) \
-	free((x)->u.s); \
-	(x)->u.s = 0; \
-	free(x); \
-}
+#define DESTROY(x) {if((x)->type == AST_EXPR_numeric_string || (x)->type == AST_EXPR_string) free((x)->u.s); (x)->u.s = 0; free(x);}
 
 
 /* Enabling traces.  */
@@ -272,19 +270,21 @@ if ((x)->type == AST_EXPR_numeric_string || (x)->type == AST_EXPR_string) \
 # define YYTOKEN_TABLE 0
 #endif
 
-#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED)
-#line 142 "ast_expr2.y"
-typedef union YYSTYPE {
+#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
+typedef union YYSTYPE
+#line 140 "ast_expr2.y"
+{
 	struct val *val;
-} YYSTYPE;
-/* Line 196 of yacc.c.  */
-#line 277 "ast_expr2.c"
+}
+/* Line 198 of yacc.c.  */
+#line 276 "ast_expr2.c"
+	YYSTYPE;
 # define yystype YYSTYPE /* obsolescent; will be withdrawn */
 # define YYSTYPE_IS_DECLARED 1
 # define YYSTYPE_IS_TRIVIAL 1
 #endif
 
-#if ! defined (YYLTYPE) && ! defined (YYLTYPE_IS_DECLARED)
+#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED
 typedef struct YYLTYPE
 {
   int first_line;
@@ -299,28 +299,61 @@ typedef struct YYLTYPE
 
 
 /* Copy the second part of user declarations.  */
-#line 146 "ast_expr2.y"
+#line 144 "ast_expr2.y"
 
 extern int		ast_yylex __P((YYSTYPE *, YYLTYPE *, yyscan_t));
 
 
-/* Line 219 of yacc.c.  */
+/* Line 221 of yacc.c.  */
 #line 304 "ast_expr2.c"
 
-#if ! defined (YYSIZE_T) && defined (__SIZE_TYPE__)
-# define YYSIZE_T __SIZE_TYPE__
+#ifdef short
+# undef short
+#endif
+
+#ifdef YYTYPE_UINT8
+typedef YYTYPE_UINT8 yytype_uint8;
+#else
+typedef unsigned char yytype_uint8;
+#endif
+
+#ifdef YYTYPE_INT8
+typedef YYTYPE_INT8 yytype_int8;
+#elif (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+typedef signed char yytype_int8;
+#else
+typedef short int yytype_int8;
 #endif
-#if ! defined (YYSIZE_T) && defined (size_t)
-# define YYSIZE_T size_t
+
+#ifdef YYTYPE_UINT16
+typedef YYTYPE_UINT16 yytype_uint16;
+#else
+typedef unsigned short int yytype_uint16;
 #endif
-#if ! defined (YYSIZE_T) && (defined (__STDC__) || defined (__cplusplus))
-# include <stddef.h> /* INFRINGES ON USER NAME SPACE */
-# define YYSIZE_T size_t
+
+#ifdef YYTYPE_INT16
+typedef YYTYPE_INT16 yytype_int16;
+#else
+typedef short int yytype_int16;
 #endif
-#if ! defined (YYSIZE_T)
-# define YYSIZE_T unsigned int
+
+#ifndef YYSIZE_T
+# ifdef __SIZE_TYPE__
+#  define YYSIZE_T __SIZE_TYPE__
+# elif defined size_t
+#  define YYSIZE_T size_t
+# elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+#  include <stddef.h> /* INFRINGES ON USER NAME SPACE */
+#  define YYSIZE_T size_t
+# else
+#  define YYSIZE_T unsigned int
+# endif
 #endif
 
+#define YYSIZE_MAXIMUM ((YYSIZE_T) -1)
+
 #ifndef YY_
 # if YYENABLE_NLS
 #  if ENABLE_NLS
@@ -333,7 +366,32 @@ extern int		ast_yylex __P((YYSTYPE *, YYLTYPE *, yyscan_t));
 # endif
 #endif
 
-#if ! defined (yyoverflow) || YYERROR_VERBOSE
+/* Suppress unused-variable warnings by "using" E.  */
+#if ! defined lint || defined __GNUC__
+# define YYUSE(e) ((void) (e))
+#else
+# define YYUSE(e) /* empty */
+#endif
+
+/* Identity function, used to suppress warnings about constant conditions.  */
+#ifndef lint
+# define YYID(n) (n)
+#else
+#if (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+static int
+YYID (int i)
+#else
+static int
+YYID (i)
+    int i;
+#endif
+{
+  return i;
+}
+#endif
+
+#if ! defined yyoverflow || YYERROR_VERBOSE
 
 /* The parser invokes alloca or malloc; define the necessary symbols.  */
 
@@ -341,46 +399,56 @@ extern int		ast_yylex __P((YYSTYPE *, YYLTYPE *, yyscan_t));
 #  if YYSTACK_USE_ALLOCA
 #   ifdef __GNUC__
 #    define YYSTACK_ALLOC __builtin_alloca
+#   elif defined __BUILTIN_VA_ARG_INCR
+#    include <alloca.h> /* INFRINGES ON USER NAME SPACE */
+#   elif defined _AIX
+#    define YYSTACK_ALLOC __alloca
+#   elif defined _MSC_VER
+#    include <malloc.h> /* INFRINGES ON USER NAME SPACE */
+#    define alloca _alloca
 #   else
 #    define YYSTACK_ALLOC alloca
-#    if defined (__STDC__) || defined (__cplusplus)
+#    if ! defined _ALLOCA_H && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
 #     include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
-#     define YYINCLUDED_STDLIB_H
+#     ifndef _STDLIB_H
+#      define _STDLIB_H 1
+#     endif
 #    endif
 #   endif
 #  endif
 # endif
 
 # ifdef YYSTACK_ALLOC
-   /* Pacify GCC's `empty if-body' warning. */
-#  define YYSTACK_FREE(Ptr) do { /* empty */; } while (0)
+   /* Pacify GCC's `empty if-body' warning.  */
+#  define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0))
 #  ifndef YYSTACK_ALLOC_MAXIMUM
     /* The OS might guarantee only one guard page at the bottom of the stack,
        and a page size can be as small as 4096 bytes.  So we cannot safely
        invoke alloca (N) if N exceeds 4096.  Use a slightly smaller number
        to allow for a few compiler-allocated temporary stack slots.  */
-#   define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2005 */
+#   define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */
 #  endif
 # else
 #  define YYSTACK_ALLOC YYMALLOC
 #  define YYSTACK_FREE YYFREE
 #  ifndef YYSTACK_ALLOC_MAXIMUM
-#   define YYSTACK_ALLOC_MAXIMUM ((YYSIZE_T) -1)
+#   define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM
 #  endif
 #  ifdef __cplusplus
 extern "C" {
 #  endif
 #  ifndef YYMALLOC
 #   define YYMALLOC malloc
-#   if (! defined (malloc) && ! defined (YYINCLUDED_STDLIB_H) \
-	&& (defined (__STDC__) || defined (__cplusplus)))
+#   if ! defined malloc && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
 void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */
 #   endif
 #  endif
 #  ifndef YYFREE
 #   define YYFREE free
-#   if (! defined (free) && ! defined (YYINCLUDED_STDLIB_H) \
-	&& (defined (__STDC__) || defined (__cplusplus)))
+#   if ! defined free && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
 void free (void *); /* INFRINGES ON USER NAME SPACE */
 #   endif
 #  endif
@@ -388,18 +456,18 @@ void free (void *); /* INFRINGES ON USER NAME SPACE */
 }
 #  endif
 # endif
-#endif /* ! defined (yyoverflow) || YYERROR_VERBOSE */
+#endif /* ! defined yyoverflow || YYERROR_VERBOSE */
 
 
-#if (! defined (yyoverflow) \
-     && (! defined (__cplusplus) \
-	 || (defined (YYLTYPE_IS_TRIVIAL) && YYLTYPE_IS_TRIVIAL \
-             && defined (YYSTYPE_IS_TRIVIAL) && YYSTYPE_IS_TRIVIAL)))
+#if (! defined yyoverflow \
+     && (! defined __cplusplus \
+	 || (defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL \
+	     && defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL)))
 
 /* A type that is properly aligned for any stack member.  */
 union yyalloc
 {
-  short int yyss;
+  yytype_int16 yyss;
   YYSTYPE yyvs;
     YYLTYPE yyls;
 };
@@ -410,13 +478,13 @@ union yyalloc
 /* The size of an array large to enough to hold all stacks, each with
    N elements.  */
 # define YYSTACK_BYTES(N) \
-     ((N) * (sizeof (short int) + sizeof (YYSTYPE) + sizeof (YYLTYPE))	\
+     ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE) + sizeof (YYLTYPE)) \
       + 2 * YYSTACK_GAP_MAXIMUM)
 
 /* Copy COUNT objects from FROM to TO.  The source and destination do
    not overlap.  */
 # ifndef YYCOPY
-#  if defined (__GNUC__) && 1 < __GNUC__
+#  if defined __GNUC__ && 1 < __GNUC__
 #   define YYCOPY(To, From, Count) \
       __builtin_memcpy (To, From, (Count) * sizeof (*(From)))
 #  else
@@ -427,7 +495,7 @@ union yyalloc
 	  for (yyi = 0; yyi < (Count); yyi++)	\
 	    (To)[yyi] = (From)[yyi];		\
 	}					\
-      while (0)
+      while (YYID (0))
 #  endif
 # endif
 
@@ -445,28 +513,22 @@ union yyalloc
 	yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
 	yyptr += yynewbytes / sizeof (*yyptr);				\
       }									\
-    while (0)
-
-#endif
+    while (YYID (0))
 
-#if defined (__STDC__) || defined (__cplusplus)
-   typedef signed char yysigned_char;
-#else
-   typedef short int yysigned_char;
 #endif
 
-/* YYFINAL -- State number of the termination state. */
+/* YYFINAL -- State number of the termination state.  */
 #define YYFINAL  10
 /* YYLAST -- Last index in YYTABLE.  */
 #define YYLAST   140
 
-/* YYNTOKENS -- Number of terminals. */
+/* YYNTOKENS -- Number of terminals.  */
 #define YYNTOKENS  24
-/* YYNNTS -- Number of nonterminals. */
+/* YYNNTS -- Number of nonterminals.  */
 #define YYNNTS  3
-/* YYNRULES -- Number of rules. */
-#define YYNRULES  22
-/* YYNRULES -- Number of states. */
+/* YYNRULES -- Number of rules.  */
+#define YYNRULES  23
+/* YYNRULES -- Number of states.  */
 #define YYNSTATES  46
 
 /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX.  */
@@ -477,7 +539,7 @@ union yyalloc
   ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
 
 /* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX.  */
-static const unsigned char yytranslate[] =
+static const yytype_uint8 yytranslate[] =
 {
        0,     2,     2,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
@@ -512,39 +574,39 @@ static const unsigned char yytranslate[] =
 #if YYDEBUG
 /* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
    YYRHS.  */
-static const unsigned char yyprhs[] =
+static const yytype_uint8 yyprhs[] =
 {
-       0,     0,     3,     5,     7,    11,    15,    19,    23,    27,
-      31,    35,    39,    43,    47,    51,    54,    57,    61,    65,
-      69,    73,    77
+       0,     0,     3,     5,     6,     8,    12,    16,    20,    24,
+      28,    32,    36,    40,    44,    48,    52,    55,    58,    62,
+      66,    70,    74,    78
 };
 
-/* YYRHS -- A `-1'-separated list of the rules' RHS. */
-static const yysigned_char yyrhs[] =
+/* YYRHS -- A `-1'-separated list of the rules' RHS.  */
+static const yytype_int8 yyrhs[] =
 {
-      25,     0,    -1,    26,    -1,    23,    -1,    21,    26,    22,
-      -1,    26,     5,    26,    -1,    26,     6,    26,    -1,    26,
-      12,    26,    -1,    26,    11,    26,    -1,    26,    10,    26,
-      -1,    26,     9,    26,    -1,    26,     8,    26,    -1,    26,
-       7,    26,    -1,    26,    14,    26,    -1,    26,    13,    26,
-      -1,    13,    26,    -1,    18,    26,    -1,    26,    17,    26,
-      -1,    26,    16,    26,    -1,    26,    15,    26,    -1,    26,
-      20,    26,    -1,    26,    19,    26,    -1,    26,     4,    26,
-       3,    26,    -1
+      25,     0,    -1,    26,    -1,    -1,    23,    -1,    21,    26,
+      22,    -1,    26,     5,    26,    -1,    26,     6,    26,    -1,
+      26,    12,    26,    -1,    26,    11,    26,    -1,    26,    10,
+      26,    -1,    26,     9,    26,    -1,    26,     8,    26,    -1,
+      26,     7,    26,    -1,    26,    14,    26,    -1,    26,    13,
+      26,    -1,    13,    26,    -1,    18,    26,    -1,    26,    17,
+      26,    -1,    26,    16,    26,    -1,    26,    15,    26,    -1,
+      26,    20,    26,    -1,    26,    19,    26,    -1,    26,     4,
+      26,     3,    26,    -1
 };
 
 /* YYRLINE[YYN] -- source line where rule number YYN was defined.  */
-static const unsigned char yyrline[] =
+static const yytype_uint16 yyrline[] =
 {
-       0,   165,   165,   175,   176,   180,   184,   188,   192,   196,
-     200,   204,   208,   212,   216,   220,   224,   228,   232,   236,
-     240,   244,   248
+       0,   168,   168,   176,   183,   184,   188,   192,   196,   200,
+     204,   208,   212,   216,   220,   224,   228,   232,   236,   240,
+     244,   248,   252,   256
 };
 #endif
 
 #if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE
 /* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
-   First, the terminals, then, starting at YYNTOKENS, nonterminals. */
+   First, the terminals, then, starting at YYNTOKENS, nonterminals.  */
 static const char *const yytname[] =
 {
   "$end", "error", "$undefined", "TOK_COLONCOLON", "TOK_COND", "TOK_OR",
@@ -558,7 +620,7 @@ static const char *const yytname[] =
 # ifdef YYPRINT
 /* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to
    token YYLEX-NUM.  */
-static const unsigned short int yytoknum[] =
+static const yytype_uint16 yytoknum[] =
 {
        0,   256,   257,   258,   259,   260,   261,   262,   263,   264,
      265,   266,   267,   268,   269,   270,   271,   272,   273,   274,
@@ -567,35 +629,35 @@ static const unsigned short int yytoknum[] =
 # endif
 
 /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives.  */
-static const unsigned char yyr1[] =
+static const yytype_uint8 yyr1[] =
 {
-       0,    24,    25,    26,    26,    26,    26,    26,    26,    26,
+       0,    24,    25,    25,    26,    26,    26,    26,    26,    26,
       26,    26,    26,    26,    26,    26,    26,    26,    26,    26,
-      26,    26,    26
+      26,    26,    26,    26
 };
 
 /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN.  */
-static const unsigned char yyr2[] =
+static const yytype_uint8 yyr2[] =
 {
-       0,     2,     1,     1,     3,     3,     3,     3,     3,     3,
-       3,     3,     3,     3,     3,     2,     2,     3,     3,     3,
-       3,     3,     5
+       0,     2,     1,     0,     1,     3,     3,     3,     3,     3,
+       3,     3,     3,     3,     3,     3,     2,     2,     3,     3,
+       3,     3,     3,     5
 };
 
 /* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
    STATE-NUM when YYTABLE doesn't specify something else to do.  Zero
    means the default is an error.  */
-static const unsigned char yydefact[] =
+static const yytype_uint8 yydefact[] =
 {
-       0,     0,     0,     0,     3,     0,     2,    15,    16,     0,
+       3,     0,     0,     0,     4,     0,     2,    16,    17,     0,
        1,     0,     0,     0,     0,     0,     0,     0,     0,     0,
-       0,     0,     0,     0,     0,     0,     0,     4,     0,     5,
-       6,    12,    11,    10,     9,     8,     7,    14,    13,    19,
-      18,    17,    21,    20,     0,    22
+       0,     0,     0,     0,     0,     0,     0,     5,     0,     6,
+       7,    13,    12,    11,    10,     9,     8,    15,    14,    20,
+      19,    18,    22,    21,     0,    23
 };
 
-/* YYDEFGOTO[NTERM-NUM]. */
-static const yysigned_char yydefgoto[] =
+/* YYDEFGOTO[NTERM-NUM].  */
+static const yytype_int8 yydefgoto[] =
 {
       -1,     5,     6
 };
@@ -603,7 +665,7 @@ static const yysigned_char yydefgoto[] =
 /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
    STATE-NUM.  */
 #define YYPACT_NINF -13
-static const yysigned_char yypact[] =
+static const yytype_int8 yypact[] =
 {
      109,   109,   109,   109,   -13,     6,    59,   106,   106,    22,
      -13,   109,   109,   109,   109,   109,   109,   109,   109,   109,
@@ -613,7 +675,7 @@ static const yysigned_char yypact[] =
 };
 
 /* YYPGOTO[NTERM-NUM].  */
-static const yysigned_char yypgoto[] =
+static const yytype_int8 yypgoto[] =
 {
      -13,   -13,    -1
 };
@@ -623,7 +685,7 @@ static const yysigned_char yypgoto[] =
    number is the opposite.  If zero, do what YYDEFACT says.
    If YYTABLE_NINF, syntax error.  */
 #define YYTABLE_NINF -1
-static const unsigned char yytable[] =
+static const yytype_uint8 yytable[] =
 {
        7,     8,     9,    22,    23,    24,    10,    25,    26,     0,
       28,    29,    30,    31,    32,    33,    34,    35,    36,    37,
@@ -642,7 +704,7 @@ static const unsigned char yytable[] =
       26
 };
 
-static const yysigned_char yycheck[] =
+static const yytype_int8 yycheck[] =
 {
        1,     2,     3,    15,    16,    17,     0,    19,    20,    -1,
       11,    12,    13,    14,    15,    16,    17,    18,    19,    20,
@@ -663,7 +725,7 @@ static const yysigned_char yycheck[] =
 
 /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
    symbol of state STATE-NUM.  */
-static const unsigned char yystos[] =
+static const yytype_uint8 yystos[] =
 {
        0,    13,    18,    21,    23,    25,    26,    26,    26,    26,
        0,     4,     5,     6,     7,     8,     9,    10,    11,    12,
@@ -697,7 +759,7 @@ do								\
       yychar = (Token);						\
       yylval = (Value);						\
       yytoken = YYTRANSLATE (yychar);				\
-      YYPOPSTACK;						\
+      YYPOPSTACK (1);						\
       goto yybackup;						\
     }								\
   else								\
@@ -705,7 +767,7 @@ do								\
       yyerror (YY_("syntax error: cannot back up")); \
       YYERROR;							\
     }								\
-while (0)
+while (YYID (0))
 
 
 #define YYTERROR	1
@@ -720,7 +782,7 @@ while (0)
 #ifndef YYLLOC_DEFAULT
 # define YYLLOC_DEFAULT(Current, Rhs, N)				\
     do									\
-      if (N)								\
+      if (YYID (N))                                                    \
 	{								\
 	  (Current).first_line   = YYRHSLOC (Rhs, 1).first_line;	\
 	  (Current).first_column = YYRHSLOC (Rhs, 1).first_column;	\
@@ -734,7 +796,7 @@ while (0)
 	  (Current).first_column = (Current).last_column =		\
 	    YYRHSLOC (Rhs, 0).last_column;				\
 	}								\
-    while (0)
+    while (YYID (0))
 #endif
 
 
@@ -746,8 +808,8 @@ while (0)
 # if YYLTYPE_IS_TRIVIAL
 #  define YY_LOCATION_PRINT(File, Loc)			\
      fprintf (File, "%d.%d-%d.%d",			\
-              (Loc).first_line, (Loc).first_column,	\
-              (Loc).last_line,  (Loc).last_column)
+	      (Loc).first_line, (Loc).first_column,	\
+	      (Loc).last_line,  (Loc).last_column)
 # else
 #  define YY_LOCATION_PRINT(File, Loc) ((void) 0)
 # endif
@@ -774,36 +836,101 @@ while (0)
 do {						\
   if (yydebug)					\
     YYFPRINTF Args;				\
-} while (0)
+} while (YYID (0))
+
+# define YY_SYMBOL_PRINT(Title, Type, Value, Location)			  \
+do {									  \
+  if (yydebug)								  \
+    {									  \
+      YYFPRINTF (stderr, "%s ", Title);					  \
+      yy_symbol_print (stderr,						  \
+		  Type, Value, Location); \
+      YYFPRINTF (stderr, "\n");						  \
+    }									  \
+} while (YYID (0))
 
-# define YY_SYMBOL_PRINT(Title, Type, Value, Location)		\
-do {								\
-  if (yydebug)							\
-    {								\
-      YYFPRINTF (stderr, "%s ", Title);				\
-      yysymprint (stderr,					\
-                  Type, Value, Location);	\
-      YYFPRINTF (stderr, "\n");					\
-    }								\
-} while (0)
+
+/*--------------------------------.
+| Print this symbol on YYOUTPUT.  |
+`--------------------------------*/
+
+/*ARGSUSED*/
+#if (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+static void
+yy_symbol_value_print (FILE *yyoutput, int yytype, const YYSTYPE * const yyvaluep, const YYLTYPE * const yylocationp)
+#else
+static void
+yy_symbol_value_print (yyoutput, yytype, yyvaluep, yylocationp)
+    FILE *yyoutput;
+    int yytype;
+    const YYSTYPE * const yyvaluep;
+    const YYLTYPE * const yylocationp;
+#endif
+{
+  if (!yyvaluep)
+    return;
+  YYUSE (yylocationp);
+# ifdef YYPRINT
+  if (yytype < YYNTOKENS)
+    YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
+# else
+  YYUSE (yyoutput);
+# endif
+  switch (yytype)
+    {
+      default:
+	break;
+    }
+}
+
+
+/*--------------------------------.
+| Print this symbol on YYOUTPUT.  |
+`--------------------------------*/
+
+#if (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+static void
+yy_symbol_print (FILE *yyoutput, int yytype, const YYSTYPE * const yyvaluep, const YYLTYPE * const yylocationp)
+#else
+static void
+yy_symbol_print (yyoutput, yytype, yyvaluep, yylocationp)
+    FILE *yyoutput;
+    int yytype;
+    const YYSTYPE * const yyvaluep;
+    const YYLTYPE * const yylocationp;
+#endif
+{
+  if (yytype < YYNTOKENS)
+    YYFPRINTF (yyoutput, "token %s (", yytname[yytype]);
+  else
+    YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]);
+
+  YY_LOCATION_PRINT (yyoutput, *yylocationp);
+  YYFPRINTF (yyoutput, ": ");
+  yy_symbol_value_print (yyoutput, yytype, yyvaluep, yylocationp);
+  YYFPRINTF (yyoutput, ")");
+}
 
 /*------------------------------------------------------------------.
 | yy_stack_print -- Print the state stack from its BOTTOM up to its |
 | TOP (included).                                                   |
 `------------------------------------------------------------------*/
 
-#if defined (__STDC__) || defined (__cplusplus)
+#if (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
 static void
-yy_stack_print (short int *bottom, short int *top)
+yy_stack_print (yytype_int16 *bottom, yytype_int16 *top)
 #else
 static void
 yy_stack_print (bottom, top)
-    short int *bottom;
-    short int *top;
+    yytype_int16 *bottom;
+    yytype_int16 *top;
 #endif
 {
   YYFPRINTF (stderr, "Stack now");
-  for (/* Nothing. */; bottom <= top; ++bottom)
+  for (; bottom <= top; ++bottom)
     YYFPRINTF (stderr, " %d", *bottom);
   YYFPRINTF (stderr, "\n");
 }
@@ -812,37 +939,47 @@ yy_stack_print (bottom, top)
 do {								\
   if (yydebug)							\
     yy_stack_print ((Bottom), (Top));				\
-} while (0)
+} while (YYID (0))
 
 
 /*------------------------------------------------.
 | Report that the YYRULE is going to be reduced.  |
 `------------------------------------------------*/
 
-#if defined (__STDC__) || defined (__cplusplus)
+#if (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
 static void
-yy_reduce_print (int yyrule)
+yy_reduce_print (YYSTYPE *yyvsp, YYLTYPE *yylsp, int yyrule)
 #else
 static void
-yy_reduce_print (yyrule)
+yy_reduce_print (yyvsp, yylsp, yyrule
+		   )
+    YYSTYPE *yyvsp;
+    YYLTYPE *yylsp;
     int yyrule;
 #endif
 {
+  int yynrhs = yyr2[yyrule];
   int yyi;
   unsigned long int yylno = yyrline[yyrule];
-  YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu), ",
-             yyrule - 1, yylno);
-  /* Print the symbols being reduced, and their result.  */
-  for (yyi = yyprhs[yyrule]; 0 <= yyrhs[yyi]; yyi++)
-    YYFPRINTF (stderr, "%s ", yytname[yyrhs[yyi]]);
-  YYFPRINTF (stderr, "-> %s\n", yytname[yyr1[yyrule]]);
+  YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n",
+	     yyrule - 1, yylno);
+  /* The symbols being reduced.  */
+  for (yyi = 0; yyi < yynrhs; yyi++)
+    {
+      fprintf (stderr, "   $%d = ", yyi + 1);
+      yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi],
+		       &(yyvsp[(yyi + 1) - (yynrhs)])
+		       , &(yylsp[(yyi + 1) - (yynrhs)])		       );
+      fprintf (stderr, "\n");
+    }
 }
 
 # define YY_REDUCE_PRINT(Rule)		\
 do {					\
   if (yydebug)				\
-    yy_reduce_print (Rule);		\
-} while (0)
+    yy_reduce_print (yyvsp, yylsp, Rule); \
+} while (YYID (0))
 
 /* Nonzero means print parse trace.  It is left uninitialized so that
    multiple parsers can coexist.  */
@@ -876,42 +1013,44 @@ int yydebug;
 #if YYERROR_VERBOSE
 
 # ifndef yystrlen
-#  if defined (__GLIBC__) && defined (_STRING_H)
+#  if defined __GLIBC__ && defined _STRING_H
 #   define yystrlen strlen
 #  else
 /* Return the length of YYSTR.  */
+#if (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
 static YYSIZE_T
-#   if defined (__STDC__) || defined (__cplusplus)
 yystrlen (const char *yystr)
-#   else
+#else
+static YYSIZE_T
 yystrlen (yystr)
-     const char *yystr;
-#   endif
+    const char *yystr;
+#endif
 {
-  const char *yys = yystr;
-
-  while (*yys++ != '\0')
+  YYSIZE_T yylen;
+  for (yylen = 0; yystr[yylen]; yylen++)
     continue;
-
-  return yys - yystr - 1;
+  return yylen;
 }
 #  endif
 # endif
 
 # ifndef yystpcpy
-#  if defined (__GLIBC__) && defined (_STRING_H) && defined (_GNU_SOURCE)
+#  if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE
 #   define yystpcpy stpcpy
 #  else
 /* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in
    YYDEST.  */
+#if (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
 static char *
-#   if defined (__STDC__) || defined (__cplusplus)
 yystpcpy (char *yydest, const char *yysrc)
-#   else
+#else
+static char *
 yystpcpy (yydest, yysrc)
-     char *yydest;
-     const char *yysrc;
-#   endif
+    char *yydest;
+    const char *yysrc;
+#endif
 {
   char *yyd = yydest;
   const char *yys = yysrc;
@@ -972,57 +1111,123 @@ yytnamerr (char *yyres, const char *yystr)
 }
 # endif
 
-#endif /* YYERROR_VERBOSE */
-
-
-
-#if YYDEBUG
-/*--------------------------------.
-| Print this symbol on YYOUTPUT.  |
-`--------------------------------*/
-
-#if defined (__STDC__) || defined (__cplusplus)
-static void
-yysymprint (FILE *yyoutput, int yytype, YYSTYPE *yyvaluep, YYLTYPE *yylocationp)
-#else
-static void
-yysymprint (yyoutput, yytype, yyvaluep, yylocationp)
-    FILE *yyoutput;
-    int yytype;
-    YYSTYPE *yyvaluep;
-    YYLTYPE *yylocationp;
-#endif
+/* Copy into YYRESULT an error message about the unexpected token
+   YYCHAR while in state YYSTATE.  Return the number of bytes copied,
+   including the terminating null byte.  If YYRESULT is null, do not
+   copy anything; just return the number of bytes that would be
+   copied.  As a special case, return 0 if an ordinary "syntax error"
+   message will do.  Return YYSIZE_MAXIMUM if overflow occurs during
+   size calculation.  */
+static YYSIZE_T
+yysyntax_error (char *yyresult, int yystate, int yychar)
 {
-  /* Pacify ``unused variable'' warnings.  */
-  (void) yyvaluep;
-  (void) yylocationp;
+  int yyn = yypact[yystate];
 
-  if (yytype < YYNTOKENS)
-    YYFPRINTF (yyoutput, "token %s (", yytname[yytype]);
+  if (! (YYPACT_NINF < yyn && yyn < YYLAST))
+    return 0;
   else
-    YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]);
+    {
+      int yytype = YYTRANSLATE (yychar);
+      YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]);
+      YYSIZE_T yysize = yysize0;
+      YYSIZE_T yysize1;
+      int yysize_overflow = 0;
+      enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
+      char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
+      int yyx;
+
+# if 0
+      /* This is so xgettext sees the translatable formats that are
+	 constructed on the fly.  */
+      YY_("syntax error, unexpected %s");
+      YY_("syntax error, unexpected %s, expecting %s");
+      YY_("syntax error, unexpected %s, expecting %s or %s");
+      YY_("syntax error, unexpected %s, expecting %s or %s or %s");
+      YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s");
+# endif
+      char *yyfmt;
+      char const *yyf;
+      static char const yyunexpected[] = "syntax error, unexpected %s";
+      static char const yyexpecting[] = ", expecting %s";
+      static char const yyor[] = " or %s";
+      char yyformat[sizeof yyunexpected
+		    + sizeof yyexpecting - 1
+		    + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2)
+		       * (sizeof yyor - 1))];
+      char const *yyprefix = yyexpecting;
+
+      /* Start YYX at -YYN if negative to avoid negative indexes in
+	 YYCHECK.  */
+      int yyxbegin = yyn < 0 ? -yyn : 0;
+
+      /* Stay within bounds of both yycheck and yytname.  */
+      int yychecklim = YYLAST - yyn;
+      int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
+      int yycount = 1;
+
+      yyarg[0] = yytname[yytype];
+      yyfmt = yystpcpy (yyformat, yyunexpected);
+
+      for (yyx = yyxbegin; yyx < yyxend; ++yyx)
+	if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
+	  {
+	    if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
+	      {
+		yycount = 1;
+		yysize = yysize0;
+		yyformat[sizeof yyunexpected - 1] = '\0';
+		break;
+	      }
+	    yyarg[yycount++] = yytname[yyx];
+	    yysize1 = yysize + yytnamerr (0, yytname[yyx]);
+	    yysize_overflow |= (yysize1 < yysize);
+	    yysize = yysize1;
+	    yyfmt = yystpcpy (yyfmt, yyprefix);
+	    yyprefix = yyor;
+	  }
 
-  YY_LOCATION_PRINT (yyoutput, *yylocationp);
-  YYFPRINTF (yyoutput, ": ");
+      yyf = YY_(yyformat);
+      yysize1 = yysize + yystrlen (yyf);
+      yysize_overflow |= (yysize1 < yysize);
+      yysize = yysize1;
 
-# ifdef YYPRINT
-  if (yytype < YYNTOKENS)
-    YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
-# endif
-  switch (yytype)
-    {
-      default:
-        break;
+      if (yysize_overflow)
+	return YYSIZE_MAXIMUM;
+
+      if (yyresult)
+	{
+	  /* Avoid sprintf, as that infringes on the user's name space.
+	     Don't have undefined behavior even if the translation
+	     produced a string with the wrong number of "%s"s.  */
+	  char *yyp = yyresult;
+	  int yyi = 0;
+	  while ((*yyp = *yyf) != '\0')
+	    {
+	      if (*yyp == '%' && yyf[1] == 's' && yyi < yycount)
+		{
+		  yyp += yytnamerr (yyp, yyarg[yyi++]);
+		  yyf += 2;
+		}
+	      else
+		{
+		  yyp++;
+		  yyf++;
+		}
+	    }
+	}
+      return yysize;
     }
-  YYFPRINTF (yyoutput, ")");
 }
+#endif /* YYERROR_VERBOSE */
+
 
-#endif /* ! YYDEBUG */
 /*-----------------------------------------------.
 | Release the memory associated to this symbol.  |
 `-----------------------------------------------*/
 
-#if defined (__STDC__) || defined (__cplusplus)
+/*ARGSUSED*/
+#if (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
 static void
 yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep, YYLTYPE *yylocationp)
 #else
@@ -1034,9 +1239,8 @@ yydestruct (yymsg, yytype, yyvaluep, yylocationp)
     YYLTYPE *yylocationp;
 #endif
 {
-  /* Pacify ``unused variable'' warnings.  */
-  (void) yyvaluep;
-  (void) yylocationp;
+  YYUSE (yyvaluep);
+  YYUSE (yylocationp);
 
   if (!yymsg)
     yymsg = "Deleting";
@@ -1044,9 +1248,119 @@ yydestruct (yymsg, yytype, yyvaluep, yylocationp)
 
   switch (yytype)
     {
+      case 3: /* "TOK_COLONCOLON" */
+#line 162 "ast_expr2.y"
+	{  free_value((yyvaluep->val)); };
+#line 1250 "ast_expr2.c"
+	break;
+      case 4: /* "TOK_COND" */
+#line 162 "ast_expr2.y"
+	{  free_value((yyvaluep->val)); };
+#line 1255 "ast_expr2.c"
+	break;
+      case 5: /* "TOK_OR" */
+#line 162 "ast_expr2.y"
+	{  free_value((yyvaluep->val)); };
+#line 1260 "ast_expr2.c"
+	break;
+      case 6: /* "TOK_AND" */
+#line 162 "ast_expr2.y"
+	{  free_value((yyvaluep->val)); };
+#line 1265 "ast_expr2.c"
+	break;
+      case 7: /* "TOK_NE" */
+#line 162 "ast_expr2.y"
+	{  free_value((yyvaluep->val)); };
+#line 1270 "ast_expr2.c"
+	break;
+      case 8: /* "TOK_LE" */
+#line 162 "ast_expr2.y"
+	{  free_value((yyvaluep->val)); };
+#line 1275 "ast_expr2.c"
+	break;
+      case 9: /* "TOK_GE" */
+#line 162 "ast_expr2.y"
+	{  free_value((yyvaluep->val)); };
+#line 1280 "ast_expr2.c"
+	break;
+      case 10: /* "TOK_LT" */
+#line 162 "ast_expr2.y"
+	{  free_value((yyvaluep->val)); };
+#line 1285 "ast_expr2.c"
+	break;
+      case 11: /* "TOK_GT" */
+#line 162 "ast_expr2.y"
+	{  free_value((yyvaluep->val)); };
+#line 1290 "ast_expr2.c"
+	break;
+      case 12: /* "TOK_EQ" */
+#line 162 "ast_expr2.y"
+	{  free_value((yyvaluep->val)); };
+#line 1295 "ast_expr2.c"
+	break;
+      case 13: /* "TOK_MINUS" */
+#line 162 "ast_expr2.y"
+	{  free_value((yyvaluep->val)); };
+#line 1300 "ast_expr2.c"
+	break;
+      case 14: /* "TOK_PLUS" */
+#line 162 "ast_expr2.y"
+	{  free_value((yyvaluep->val)); };
+#line 1305 "ast_expr2.c"
+	break;
+      case 15: /* "TOK_MOD" */
+#line 162 "ast_expr2.y"
+	{  free_value((yyvaluep->val)); };
+#line 1310 "ast_expr2.c"
+	break;
+      case 16: /* "TOK_DIV" */
+#line 162 "ast_expr2.y"
+	{  free_value((yyvaluep->val)); };
+#line 1315 "ast_expr2.c"
+	break;
+      case 17: /* "TOK_MULT" */
+#line 162 "ast_expr2.y"
+	{  free_value((yyvaluep->val)); };
+#line 1320 "ast_expr2.c"
+	break;
+      case 18: /* "TOK_COMPL" */
+#line 162 "ast_expr2.y"
+	{  free_value((yyvaluep->val)); };
+#line 1325 "ast_expr2.c"
+	break;
+      case 19: /* "TOK_EQTILDE" */
+#line 162 "ast_expr2.y"
+	{  free_value((yyvaluep->val)); };
+#line 1330 "ast_expr2.c"
+	break;
+      case 20: /* "TOK_COLON" */
+#line 162 "ast_expr2.y"
+	{  free_value((yyvaluep->val)); };
+#line 1335 "ast_expr2.c"
+	break;
+      case 21: /* "TOK_LP" */
+#line 162 "ast_expr2.y"
+	{  free_value((yyvaluep->val)); };
+#line 1340 "ast_expr2.c"
+	break;
+      case 22: /* "TOK_RP" */
+#line 162 "ast_expr2.y"
+	{  free_value((yyvaluep->val)); };
+#line 1345 "ast_expr2.c"
+	break;
+      case 23: /* "TOKEN" */
+#line 162 "ast_expr2.y"
+	{  free_value((yyvaluep->val)); };
+#line 1350 "ast_expr2.c"
+	break;
+      case 26: /* "expr" */
+#line 162 "ast_expr2.y"
+	{  free_value((yyvaluep->val)); };
+#line 1355 "ast_expr2.c"
+	break;
 
       default:
-        break;
+	break;
     }
 }
 
@@ -1054,13 +1368,13 @@ yydestruct (yymsg, yytype, yyvaluep, yylocationp)
 /* Prevent warnings from -Wmissing-prototypes.  */
 
 #ifdef YYPARSE_PARAM
-# if defined (__STDC__) || defined (__cplusplus)
+#if defined __STDC__ || defined __cplusplus
 int yyparse (void *YYPARSE_PARAM);
-# else
+#else
 int yyparse ();
-# endif
+#endif
 #else /* ! YYPARSE_PARAM */
-#if defined (__STDC__) || defined (__cplusplus)
+#if defined __STDC__ || defined __cplusplus
 int yyparse (void);
 #else
 int yyparse ();
@@ -1077,20 +1391,24 @@ int yyparse ();
 `----------*/
 
 #ifdef YYPARSE_PARAM
-# if defined (__STDC__) || defined (__cplusplus)
-int yyparse (void *YYPARSE_PARAM)
-# else
-int yyparse (YYPARSE_PARAM)
-  void *YYPARSE_PARAM;
-# endif
+#if (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+int
+yyparse (void *YYPARSE_PARAM)
+#else
+int
+yyparse (YYPARSE_PARAM)
+    void *YYPARSE_PARAM;
+#endif
 #else /* ! YYPARSE_PARAM */
-#if defined (__STDC__) || defined (__cplusplus)
+#if (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
 int
 yyparse (void)
 #else
 int
 yyparse ()
-    ;
+
 #endif
 #endif
 {
@@ -1112,6 +1430,12 @@ YYLTYPE yylloc;
   int yyerrstatus;
   /* Look-ahead token as an internal (translated) token number.  */
   int yytoken = 0;
+#if YYERROR_VERBOSE
+  /* Buffer for error messages, and its allocated size.  */
+  char yymsgbuf[128];
+  char *yymsg = yymsgbuf;
+  YYSIZE_T yymsg_alloc = sizeof yymsgbuf;
+#endif
 
   /* Three stacks and their tools:
      `yyss': related to states,
@@ -1122,9 +1446,9 @@ YYLTYPE yylloc;
      to reallocate them elsewhere.  */
 
   /* The state stack.  */
-  short int yyssa[YYINITDEPTH];
-  short int *yyss = yyssa;
-  short int *yyssp;
+  yytype_int16 yyssa[YYINITDEPTH];
+  yytype_int16 *yyss = yyssa;
+  yytype_int16 *yyssp;
 
   /* The semantic value stack.  */
   YYSTYPE yyvsa[YYINITDEPTH];
@@ -1135,10 +1459,10 @@ YYLTYPE yylloc;
   YYLTYPE yylsa[YYINITDEPTH];
   YYLTYPE *yyls = yylsa;
   YYLTYPE *yylsp;
-  /* The locations where the error started and ended. */
+  /* The locations where the error started and ended.  */
   YYLTYPE yyerror_range[2];
 
-#define YYPOPSTACK   (yyvsp--, yyssp--, yylsp--)
+#define YYPOPSTACK(N)   (yyvsp -= (N), yyssp -= (N), yylsp -= (N))
 
   YYSIZE_T yystacksize = YYINITDEPTH;
 
@@ -1147,9 +1471,9 @@ YYLTYPE yylloc;
   YYSTYPE yyval;
   YYLTYPE yyloc;
 
-  /* When reducing, the number of symbols on the RHS of the reduced
-     rule.  */
-  int yylen;
+  /* The number of symbols on the RHS of the reduced rule.
+     Keep to zero when no symbol should be popped.  */
+  int yylen = 0;
 
   YYDPRINTF ((stderr, "Starting parse\n"));
 
@@ -1179,8 +1503,7 @@ YYLTYPE yylloc;
 `------------------------------------------------------------*/
  yynewstate:
   /* In all cases, when you get here, the value and location stacks
-     have just been pushed. so pushing a state here evens the stacks.
-     */
+     have just been pushed.  So pushing a state here evens the stacks.  */
   yyssp++;
 
  yysetstate:
@@ -1193,11 +1516,11 @@ YYLTYPE yylloc;
 
 #ifdef yyoverflow
       {
-	/* Give user a chance to reallocate the stack. Use copies of
+	/* Give user a chance to reallocate the stack.  Use copies of
 	   these so that the &'s don't force the real ones into
 	   memory.  */
 	YYSTYPE *yyvs1 = yyvs;
-	short int *yyss1 = yyss;
+	yytype_int16 *yyss1 = yyss;
 	YYLTYPE *yyls1 = yyls;
 
 	/* Each stack pointer address is followed by the size of the
@@ -1225,7 +1548,7 @@ YYLTYPE yylloc;
 	yystacksize = YYMAXDEPTH;
 
       {
-	short int *yyss1 = yyss;
+	yytype_int16 *yyss1 = yyss;
 	union yyalloc *yyptr =
 	  (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
 	if (! yyptr)
@@ -1260,12 +1583,10 @@ YYLTYPE yylloc;
 `-----------*/
 yybackup:
 
-/* Do appropriate processing given the current state.  */
-/* Read a look-ahead token if we need one and don't already have one.  */
-/* yyresume: */
+  /* Do appropriate processing given the current state.  Read a
+     look-ahead token if we need one and don't already have one.  */
 
   /* First try to decide what to do without reference to look-ahead token.  */
-
   yyn = yypact[yystate];
   if (yyn == YYPACT_NINF)
     goto yydefault;
@@ -1307,22 +1628,21 @@ yybackup:
   if (yyn == YYFINAL)
     YYACCEPT;
 
+  /* Count tokens shifted since error; after three, turn off error
+     status.  */
+  if (yyerrstatus)
+    yyerrstatus--;
+
   /* Shift the look-ahead token.  */
   YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc);
 
-  /* Discard the token being shifted unless it is eof.  */
+  /* Discard the shifted token unless it is eof.  */
   if (yychar != YYEOF)
     yychar = YYEMPTY;
 
+  yystate = yyn;
   *++yyvsp = yylval;
   *++yylsp = yylloc;
-
-  /* Count tokens shifted since error; after three, turn off error
-     status.  */
-  if (yyerrstatus)
-    yyerrstatus--;
-
-  yystate = yyn;
   goto yynewstate;
 
 
@@ -1353,192 +1673,198 @@ yyreduce:
      GCC warning that YYVAL may be used uninitialized.  */
   yyval = yyvsp[1-yylen];
 
-  /* Default location. */
-  YYLLOC_DEFAULT (yyloc, yylsp - yylen, yylen);
+  /* Default location.  */
+  YYLLOC_DEFAULT (yyloc, (yylsp - yylen), yylen);
   YY_REDUCE_PRINT (yyn);
   switch (yyn)
     {
         case 2:
-#line 165 "ast_expr2.y"
+#line 168 "ast_expr2.y"
     { ((struct parse_io *)parseio)->val = (struct val *)calloc(sizeof(struct val),1);
-              ((struct parse_io *)parseio)->val->type = (yyvsp[0].val)->type;
-              if( (yyvsp[0].val)->type == AST_EXPR_integer )
-				  ((struct parse_io *)parseio)->val->u.i = (yyvsp[0].val)->u.i;
+              ((struct parse_io *)parseio)->val->type = (yyvsp[(1) - (1)].val)->type;
+              if( (yyvsp[(1) - (1)].val)->type == AST_EXPR_integer )
+				  ((struct parse_io *)parseio)->val->u.i = (yyvsp[(1) - (1)].val)->u.i;
               else
-				  ((struct parse_io *)parseio)->val->u.s = (yyvsp[0].val)->u.s; 
-			  free((yyvsp[0].val));
+				  ((struct parse_io *)parseio)->val->u.s = (yyvsp[(1) - (1)].val)->u.s; 
+			  free((yyvsp[(1) - (1)].val));
 			;}
     break;
 
   case 3:
-#line 175 "ast_expr2.y"
-    { (yyval.val)= (yyvsp[0].val);;}
+#line 176 "ast_expr2.y"
+    {/* nothing */ ((struct parse_io *)parseio)->val = (struct val *)calloc(sizeof(struct val),1);
+              ((struct parse_io *)parseio)->val->type = AST_EXPR_string;
+			  ((struct parse_io *)parseio)->val->u.s = strdup(""); 
+			;}
     break;
 
   case 4:
-#line 176 "ast_expr2.y"
-    { (yyval.val) = (yyvsp[-1].val); 
-	                       (yyloc).first_column = (yylsp[-2]).first_column; (yyloc).last_column = (yylsp[0]).last_column; 
-						   (yyloc).first_line=0; (yyloc).last_line=0;
-							DESTROY((yyvsp[-2].val)); DESTROY((yyvsp[0].val)); ;}
+#line 183 "ast_expr2.y"
+    { (yyval.val)= (yyvsp[(1) - (1)].val);;}
     break;
 
   case 5:
-#line 180 "ast_expr2.y"
-    { (yyval.val) = op_or ((yyvsp[-2].val), (yyvsp[0].val));
-						DESTROY((yyvsp[-1].val));	
-                         (yyloc).first_column = (yylsp[-2]).first_column; (yyloc).last_column = (yylsp[0]).last_column; 
-						 (yyloc).first_line=0; (yyloc).last_line=0;;}
+#line 184 "ast_expr2.y"
+    { (yyval.val) = (yyvsp[(2) - (3)].val); 
+	                       (yyloc).first_column = (yylsp[(1) - (3)]).first_column; (yyloc).last_column = (yylsp[(3) - (3)]).last_column; 
+						   (yyloc).first_line=0; (yyloc).last_line=0;
+							DESTROY((yyvsp[(1) - (3)].val)); DESTROY((yyvsp[(3) - (3)].val)); ;}
     break;
 
   case 6:
-#line 184 "ast_expr2.y"
-    { (yyval.val) = op_and ((yyvsp[-2].val), (yyvsp[0].val)); 
-						DESTROY((yyvsp[-1].val));	
-	                      (yyloc).first_column = (yylsp[-2]).first_column; (yyloc).last_column = (yylsp[0]).last_column; 
-                          (yyloc).first_line=0; (yyloc).last_line=0;;}
+#line 188 "ast_expr2.y"
+    { (yyval.val) = op_or ((yyvsp[(1) - (3)].val), (yyvsp[(3) - (3)].val));
+						DESTROY((yyvsp[(2) - (3)].val));	
+                         (yyloc).first_column = (yylsp[(1) - (3)]).first_column; (yyloc).last_column = (yylsp[(3) - (3)]).last_column; 
+						 (yyloc).first_line=0; (yyloc).last_line=0;;}
     break;
 
   case 7:
-#line 188 "ast_expr2.y"
-    { (yyval.val) = op_eq ((yyvsp[-2].val), (yyvsp[0].val));
-						DESTROY((yyvsp[-1].val));	
-	                     (yyloc).first_column = (yylsp[-2]).first_column; (yyloc).last_column = (yylsp[0]).last_column;
-						 (yyloc).first_line=0; (yyloc).last_line=0;;}
+#line 192 "ast_expr2.y"
+    { (yyval.val) = op_and ((yyvsp[(1) - (3)].val), (yyvsp[(3) - (3)].val)); 
+						DESTROY((yyvsp[(2) - (3)].val));	
+	                      (yyloc).first_column = (yylsp[(1) - (3)]).first_column; (yyloc).last_column = (yylsp[(3) - (3)]).last_column; 
+                          (yyloc).first_line=0; (yyloc).last_line=0;;}
     break;
 
   case 8:
-#line 192 "ast_expr2.y"
-    { (yyval.val) = op_gt ((yyvsp[-2].val), (yyvsp[0].val));
-						DESTROY((yyvsp[-1].val));	
-                         (yyloc).first_column = (yylsp[-2]).first_column; (yyloc).last_column = (yylsp[0]).last_column;
+#line 196 "ast_expr2.y"
+    { (yyval.val) = op_eq ((yyvsp[(1) - (3)].val), (yyvsp[(3) - (3)].val));
+						DESTROY((yyvsp[(2) - (3)].val));	
+	                     (yyloc).first_column = (yylsp[(1) - (3)]).first_column; (yyloc).last_column = (yylsp[(3) - (3)]).last_column;
 						 (yyloc).first_line=0; (yyloc).last_line=0;;}
     break;
 
   case 9:
-#line 196 "ast_expr2.y"
-    { (yyval.val) = op_lt ((yyvsp[-2].val), (yyvsp[0].val)); 
-						DESTROY((yyvsp[-1].val));	
-	                     (yyloc).first_column = (yylsp[-2]).first_column; (yyloc).last_column = (yylsp[0]).last_column; 
+#line 200 "ast_expr2.y"
+    { (yyval.val) = op_gt ((yyvsp[(1) - (3)].val), (yyvsp[(3) - (3)].val));
+						DESTROY((yyvsp[(2) - (3)].val));	
+                         (yyloc).first_column = (yylsp[(1) - (3)]).first_column; (yyloc).last_column = (yylsp[(3) - (3)]).last_column;
 						 (yyloc).first_line=0; (yyloc).last_line=0;;}
     break;
 
   case 10:
-#line 200 "ast_expr2.y"
-    { (yyval.val) = op_ge ((yyvsp[-2].val), (yyvsp[0].val)); 
-						DESTROY((yyvsp[-1].val));	
-	                      (yyloc).first_column = (yylsp[-2]).first_column; (yyloc).last_column = (yylsp[0]).last_column; 
-						  (yyloc).first_line=0; (yyloc).last_line=0;;}
+#line 204 "ast_expr2.y"
+    { (yyval.val) = op_lt ((yyvsp[(1) - (3)].val), (yyvsp[(3) - (3)].val)); 
+						DESTROY((yyvsp[(2) - (3)].val));	
+	                     (yyloc).first_column = (yylsp[(1) - (3)]).first_column; (yyloc).last_column = (yylsp[(3) - (3)]).last_column; 
+						 (yyloc).first_line=0; (yyloc).last_line=0;;}
     break;
 
   case 11:
-#line 204 "ast_expr2.y"
-    { (yyval.val) = op_le ((yyvsp[-2].val), (yyvsp[0].val)); 
-						DESTROY((yyvsp[-1].val));	
-	                      (yyloc).first_column = (yylsp[-2]).first_column; (yyloc).last_column = (yylsp[0]).last_column; 
+#line 208 "ast_expr2.y"
+    { (yyval.val) = op_ge ((yyvsp[(1) - (3)].val), (yyvsp[(3) - (3)].val)); 
+						DESTROY((yyvsp[(2) - (3)].val));	
+	                      (yyloc).first_column = (yylsp[(1) - (3)]).first_column; (yyloc).last_column = (yylsp[(3) - (3)]).last_column; 
 						  (yyloc).first_line=0; (yyloc).last_line=0;;}
     break;
 
   case 12:
-#line 208 "ast_expr2.y"
-    { (yyval.val) = op_ne ((yyvsp[-2].val), (yyvsp[0].val)); 
-						DESTROY((yyvsp[-1].val));	
-	                      (yyloc).first_column = (yylsp[-2]).first_column; (yyloc).last_column = (yylsp[0]).last_column; 
+#line 212 "ast_expr2.y"
+    { (yyval.val) = op_le ((yyvsp[(1) - (3)].val), (yyvsp[(3) - (3)].val)); 
+						DESTROY((yyvsp[(2) - (3)].val));	
+	                      (yyloc).first_column = (yylsp[(1) - (3)]).first_column; (yyloc).last_column = (yylsp[(3) - (3)]).last_column; 
 						  (yyloc).first_line=0; (yyloc).last_line=0;;}
     break;
 
   case 13:
-#line 212 "ast_expr2.y"
-    { (yyval.val) = op_plus ((yyvsp[-2].val), (yyvsp[0].val)); 
-						DESTROY((yyvsp[-1].val));	
-	                       (yyloc).first_column = (yylsp[-2]).first_column; (yyloc).last_column = (yylsp[0]).last_column; 
-						   (yyloc).first_line=0; (yyloc).last_line=0;;}
+#line 216 "ast_expr2.y"
+    { (yyval.val) = op_ne ((yyvsp[(1) - (3)].val), (yyvsp[(3) - (3)].val)); 
+						DESTROY((yyvsp[(2) - (3)].val));	
+	                      (yyloc).first_column = (yylsp[(1) - (3)]).first_column; (yyloc).last_column = (yylsp[(3) - (3)]).last_column; 
+						  (yyloc).first_line=0; (yyloc).last_line=0;;}
     break;
 
   case 14:
-#line 216 "ast_expr2.y"
-    { (yyval.val) = op_minus ((yyvsp[-2].val), (yyvsp[0].val)); 
-						DESTROY((yyvsp[-1].val));	
-	                        (yyloc).first_column = (yylsp[-2]).first_column; (yyloc).last_column = (yylsp[0]).last_column; 
-							(yyloc).first_line=0; (yyloc).last_line=0;;}
+#line 220 "ast_expr2.y"
+    { (yyval.val) = op_plus ((yyvsp[(1) - (3)].val), (yyvsp[(3) - (3)].val)); 
+						DESTROY((yyvsp[(2) - (3)].val));	
+	                       (yyloc).first_column = (yylsp[(1) - (3)]).first_column; (yyloc).last_column = (yylsp[(3) - (3)]).last_column; 
+						   (yyloc).first_line=0; (yyloc).last_line=0;;}
     break;
 
   case 15:
-#line 220 "ast_expr2.y"
-    { (yyval.val) = op_negate ((yyvsp[0].val)); 
-						DESTROY((yyvsp[-1].val));	
-	                        (yyloc).first_column = (yylsp[-1]).first_column; (yyloc).last_column = (yylsp[0]).last_column; 
+#line 224 "ast_expr2.y"
+    { (yyval.val) = op_minus ((yyvsp[(1) - (3)].val), (yyvsp[(3) - (3)].val)); 
+						DESTROY((yyvsp[(2) - (3)].val));	
+	                        (yyloc).first_column = (yylsp[(1) - (3)]).first_column; (yyloc).last_column = (yylsp[(3) - (3)]).last_column; 
 							(yyloc).first_line=0; (yyloc).last_line=0;;}
     break;
 
   case 16:
-#line 224 "ast_expr2.y"
-    { (yyval.val) = op_compl ((yyvsp[0].val)); 
-						DESTROY((yyvsp[-1].val));	
-	                        (yyloc).first_column = (yylsp[-1]).first_column; (yyloc).last_column = (yylsp[0]).last_column; 
+#line 228 "ast_expr2.y"
+    { (yyval.val) = op_negate ((yyvsp[(2) - (2)].val)); 
+						DESTROY((yyvsp[(1) - (2)].val));	
+	                        (yyloc).first_column = (yylsp[(1) - (2)]).first_column; (yyloc).last_column = (yylsp[(2) - (2)]).last_column; 
 							(yyloc).first_line=0; (yyloc).last_line=0;;}
     break;
 
   case 17:
-#line 228 "ast_expr2.y"
-    { (yyval.val) = op_times ((yyvsp[-2].val), (yyvsp[0].val)); 
-						DESTROY((yyvsp[-1].val));	
-	                       (yyloc).first_column = (yylsp[-2]).first_column; (yyloc).last_column = (yylsp[0]).last_column; 
-						   (yyloc).first_line=0; (yyloc).last_line=0;;}
+#line 232 "ast_expr2.y"
+    { (yyval.val) = op_compl ((yyvsp[(2) - (2)].val)); 
+						DESTROY((yyvsp[(1) - (2)].val));	
+	                        (yyloc).first_column = (yylsp[(1) - (2)]).first_column; (yyloc).last_column = (yylsp[(2) - (2)]).last_column; 
+							(yyloc).first_line=0; (yyloc).last_line=0;;}
     break;
 
   case 18:
-#line 232 "ast_expr2.y"
-    { (yyval.val) = op_div ((yyvsp[-2].val), (yyvsp[0].val)); 
-						DESTROY((yyvsp[-1].val));	
-	                      (yyloc).first_column = (yylsp[-2]).first_column; (yyloc).last_column = (yylsp[0]).last_column; 
-						  (yyloc).first_line=0; (yyloc).last_line=0;;}
+#line 236 "ast_expr2.y"
+    { (yyval.val) = op_times ((yyvsp[(1) - (3)].val), (yyvsp[(3) - (3)].val)); 
+						DESTROY((yyvsp[(2) - (3)].val));	
+	                       (yyloc).first_column = (yylsp[(1) - (3)]).first_column; (yyloc).last_column = (yylsp[(3) - (3)]).last_column; 
+						   (yyloc).first_line=0; (yyloc).last_line=0;;}
     break;
 
   case 19:
-#line 236 "ast_expr2.y"
-    { (yyval.val) = op_rem ((yyvsp[-2].val), (yyvsp[0].val)); 
-						DESTROY((yyvsp[-1].val));	
-	                      (yyloc).first_column = (yylsp[-2]).first_column; (yyloc).last_column = (yylsp[0]).last_column; 
+#line 240 "ast_expr2.y"
+    { (yyval.val) = op_div ((yyvsp[(1) - (3)].val), (yyvsp[(3) - (3)].val)); 
+						DESTROY((yyvsp[(2) - (3)].val));	
+	                      (yyloc).first_column = (yylsp[(1) - (3)]).first_column; (yyloc).last_column = (yylsp[(3) - (3)]).last_column; 
 						  (yyloc).first_line=0; (yyloc).last_line=0;;}
     break;
 
   case 20:
-#line 240 "ast_expr2.y"
-    { (yyval.val) = op_colon ((yyvsp[-2].val), (yyvsp[0].val)); 
-						DESTROY((yyvsp[-1].val));	
-	                        (yyloc).first_column = (yylsp[-2]).first_column; (yyloc).last_column = (yylsp[0]).last_column; 
-							(yyloc).first_line=0; (yyloc).last_line=0;;}
+#line 244 "ast_expr2.y"
+    { (yyval.val) = op_rem ((yyvsp[(1) - (3)].val), (yyvsp[(3) - (3)].val)); 
+						DESTROY((yyvsp[(2) - (3)].val));	
+	                      (yyloc).first_column = (yylsp[(1) - (3)]).first_column; (yyloc).last_column = (yylsp[(3) - (3)]).last_column; 
+						  (yyloc).first_line=0; (yyloc).last_line=0;;}
     break;
 
   case 21:
-#line 244 "ast_expr2.y"
-    { (yyval.val) = op_eqtilde ((yyvsp[-2].val), (yyvsp[0].val)); 
-						DESTROY((yyvsp[-1].val));	
-	                        (yyloc).first_column = (yylsp[-2]).first_column; (yyloc).last_column = (yylsp[0]).last_column; 
+#line 248 "ast_expr2.y"
+    { (yyval.val) = op_colon ((yyvsp[(1) - (3)].val), (yyvsp[(3) - (3)].val)); 
+						DESTROY((yyvsp[(2) - (3)].val));	
+	                        (yyloc).first_column = (yylsp[(1) - (3)]).first_column; (yyloc).last_column = (yylsp[(3) - (3)]).last_column; 
 							(yyloc).first_line=0; (yyloc).last_line=0;;}
     break;
 
   case 22:
-#line 248 "ast_expr2.y"
-    { (yyval.val) = op_cond ((yyvsp[-4].val), (yyvsp[-2].val), (yyvsp[0].val)); 
-						DESTROY((yyvsp[-3].val));	
-						DESTROY((yyvsp[-1].val));	
-	                        (yyloc).first_column = (yylsp[-4]).first_column; (yyloc).last_column = (yylsp[-2]).last_column; 
+#line 252 "ast_expr2.y"
+    { (yyval.val) = op_eqtilde ((yyvsp[(1) - (3)].val), (yyvsp[(3) - (3)].val)); 
+						DESTROY((yyvsp[(2) - (3)].val));	
+	                        (yyloc).first_column = (yylsp[(1) - (3)]).first_column; (yyloc).last_column = (yylsp[(3) - (3)]).last_column; 
+							(yyloc).first_line=0; (yyloc).last_line=0;;}
+    break;
+
+  case 23:
+#line 256 "ast_expr2.y"
+    { (yyval.val) = op_cond ((yyvsp[(1) - (5)].val), (yyvsp[(3) - (5)].val), (yyvsp[(5) - (5)].val)); 
+						DESTROY((yyvsp[(2) - (5)].val));	
+						DESTROY((yyvsp[(4) - (5)].val));	
+	                        (yyloc).first_column = (yylsp[(1) - (5)]).first_column; (yyloc).last_column = (yylsp[(3) - (5)]).last_column; 
 							(yyloc).first_line=0; (yyloc).last_line=0;;}
     break;
 
 
+/* Line 1270 of yacc.c.  */
+#line 1857 "ast_expr2.c"
       default: break;
     }
+  YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
 
-/* Line 1126 of yacc.c.  */
-#line 1532 "ast_expr2.c"
-
-  yyvsp -= yylen;
-  yyssp -= yylen;
-  yylsp -= yylen;
-
+  YYPOPSTACK (yylen);
+  yylen = 0;
   YY_STACK_PRINT (yyss, yyssp);
 
   *++yyvsp = yyval;
@@ -1567,110 +1893,41 @@ yyerrlab:
   if (!yyerrstatus)
     {
       ++yynerrs;
-#if YYERROR_VERBOSE
-      yyn = yypact[yystate];
-
-      if (YYPACT_NINF < yyn && yyn < YYLAST)
-	{
-	  int yytype = YYTRANSLATE (yychar);
-	  YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]);
-	  YYSIZE_T yysize = yysize0;
-	  YYSIZE_T yysize1;
-	  int yysize_overflow = 0;
-	  char *yymsg = 0;
-#	  define YYERROR_VERBOSE_ARGS_MAXIMUM 5
-	  char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
-	  int yyx;
-
-#if 0
-	  /* This is so xgettext sees the translatable formats that are
-	     constructed on the fly.  */
-	  YY_("syntax error, unexpected %s");
-	  YY_("syntax error, unexpected %s, expecting %s");
-	  YY_("syntax error, unexpected %s, expecting %s or %s");
-	  YY_("syntax error, unexpected %s, expecting %s or %s or %s");
-	  YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s");
-#endif
-	  char *yyfmt;
-	  char const *yyf;
-	  static char const yyunexpected[] = "syntax error, unexpected %s";
-	  static char const yyexpecting[] = ", expecting %s";
-	  static char const yyor[] = " or %s";
-	  char yyformat[sizeof yyunexpected
-			+ sizeof yyexpecting - 1
-			+ ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2)
-			   * (sizeof yyor - 1))];
-	  char const *yyprefix = yyexpecting;
-
-	  /* Start YYX at -YYN if negative to avoid negative indexes in
-	     YYCHECK.  */
-	  int yyxbegin = yyn < 0 ? -yyn : 0;
-
-	  /* Stay within bounds of both yycheck and yytname.  */
-	  int yychecklim = YYLAST - yyn;
-	  int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
-	  int yycount = 1;
-
-	  yyarg[0] = yytname[yytype];
-	  yyfmt = yystpcpy (yyformat, yyunexpected);
-
-	  for (yyx = yyxbegin; yyx < yyxend; ++yyx)
-	    if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
+#if ! YYERROR_VERBOSE
+      yyerror (YY_("syntax error"));
+#else
+      {
+	YYSIZE_T yysize = yysyntax_error (0, yystate, yychar);
+	if (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM)
+	  {
+	    YYSIZE_T yyalloc = 2 * yysize;
+	    if (! (yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM))
+	      yyalloc = YYSTACK_ALLOC_MAXIMUM;
+	    if (yymsg != yymsgbuf)
+	      YYSTACK_FREE (yymsg);
+	    yymsg = (char *) YYSTACK_ALLOC (yyalloc);
+	    if (yymsg)
+	      yymsg_alloc = yyalloc;
+	    else
 	      {
-		if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
-		  {
-		    yycount = 1;
-		    yysize = yysize0;
-		    yyformat[sizeof yyunexpected - 1] = '\0';
-		    break;
-		  }
-		yyarg[yycount++] = yytname[yyx];
-		yysize1 = yysize + yytnamerr (0, yytname[yyx]);
-		yysize_overflow |= yysize1 < yysize;
-		yysize = yysize1;
-		yyfmt = yystpcpy (yyfmt, yyprefix);
-		yyprefix = yyor;
+		yymsg = yymsgbuf;
+		yymsg_alloc = sizeof yymsgbuf;
 	      }
+	  }
 
-	  yyf = YY_(yyformat);
-	  yysize1 = yysize + yystrlen (yyf);
-	  yysize_overflow |= yysize1 < yysize;
-	  yysize = yysize1;
-
-	  if (!yysize_overflow && yysize <= YYSTACK_ALLOC_MAXIMUM)
-	    yymsg = (char *) YYSTACK_ALLOC (yysize);
-	  if (yymsg)
-	    {
-	      /* Avoid sprintf, as that infringes on the user's name space.
-		 Don't have undefined behavior even if the translation
-		 produced a string with the wrong number of "%s"s.  */
-	      char *yyp = yymsg;
-	      int yyi = 0;
-	      while ((*yyp = *yyf))
-		{
-		  if (*yyp == '%' && yyf[1] == 's' && yyi < yycount)
-		    {
-		      yyp += yytnamerr (yyp, yyarg[yyi++]);
-		      yyf += 2;
-		    }
-		  else
-		    {
-		      yyp++;
-		      yyf++;
-		    }
-		}
-	      yyerror (yymsg);
-	      YYSTACK_FREE (yymsg);
-	    }
-	  else
-	    {
-	      yyerror (YY_("syntax error"));
+	if (0 < yysize && yysize <= yymsg_alloc)
+	  {
+	    (void) yysyntax_error (yymsg, yystate, yychar);
+	    yyerror (yymsg);
+	  }
+	else
+	  {
+	    yyerror (YY_("syntax error"));
+	    if (yysize != 0)
 	      goto yyexhaustedlab;
-	    }
-	}
-      else
-#endif /* YYERROR_VERBOSE */
-	yyerror (YY_("syntax error"));
+	  }
+      }
+#endif
     }
 
   yyerror_range[0] = yylloc;
@@ -1681,14 +1938,15 @@ yyerrlab:
 	 error, discard it.  */
 
       if (yychar <= YYEOF)
-        {
+	{
 	  /* Return failure if at end of input.  */
 	  if (yychar == YYEOF)
 	    YYABORT;
-        }
+	}
       else
 	{
-	  yydestruct ("Error: discarding", yytoken, &yylval, &yylloc);
+	  yydestruct ("Error: discarding",
+		      yytoken, &yylval, &yylloc);
 	  yychar = YYEMPTY;
 	}
     }
@@ -1706,13 +1964,15 @@ yyerrorlab:
   /* Pacify compilers like GCC when the user code never invokes
      YYERROR and the label yyerrorlab therefore never appears in user
      code.  */
-  if (0)
+  if (/*CONSTCOND*/ 0)
      goto yyerrorlab;
 
   yyerror_range[0] = yylsp[1-yylen];
-  yylsp -= yylen;
-  yyvsp -= yylen;
-  yyssp -= yylen;
+  /* Do not reclaim the symbols of the rule which action triggered
+     this YYERROR.  */
+  YYPOPSTACK (yylen);
+  yylen = 0;
+  YY_STACK_PRINT (yyss, yyssp);
   yystate = *yyssp;
   goto yyerrlab1;
 
@@ -1742,8 +2002,9 @@ yyerrlab1:
 	YYABORT;
 
       yyerror_range[0] = *yylsp;
-      yydestruct ("Error: popping", yystos[yystate], yyvsp, yylsp);
-      YYPOPSTACK;
+      yydestruct ("Error: popping",
+		  yystos[yystate], yyvsp, yylsp);
+      YYPOPSTACK (1);
       yystate = *yyssp;
       YY_STACK_PRINT (yyss, yyssp);
     }
@@ -1755,11 +2016,11 @@ yyerrlab1:
 
   yyerror_range[1] = yylloc;
   /* Using YYLLOC is tempting, but would change the location of
-     the look-ahead.  YYLOC is available though. */
-  YYLLOC_DEFAULT (yyloc, yyerror_range - 1, 2);
+     the look-ahead.  YYLOC is available though.  */
+  YYLLOC_DEFAULT (yyloc, (yyerror_range - 1), 2);
   *++yylsp = yyloc;
 
-  /* Shift the error token. */
+  /* Shift the error token.  */
   YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp);
 
   yystate = yyn;
@@ -1794,21 +2055,29 @@ yyreturn:
   if (yychar != YYEOF && yychar != YYEMPTY)
      yydestruct ("Cleanup: discarding lookahead",
 		 yytoken, &yylval, &yylloc);
+  /* Do not reclaim the symbols of the rule which action triggered
+     this YYABORT or YYACCEPT.  */
+  YYPOPSTACK (yylen);
+  YY_STACK_PRINT (yyss, yyssp);
   while (yyssp != yyss)
     {
       yydestruct ("Cleanup: popping",
 		  yystos[*yyssp], yyvsp, yylsp);
-      YYPOPSTACK;
+      YYPOPSTACK (1);
     }
 #ifndef yyoverflow
   if (yyss != yyssa)
     YYSTACK_FREE (yyss);
+#endif
+#if YYERROR_VERBOSE
+  if (yymsg != yymsgbuf)
+    YYSTACK_FREE (yymsg);
 #endif
   return yyresult;
 }
 
 
-#line 255 "ast_expr2.y"
+#line 263 "ast_expr2.y"
 
 
 static struct val *
@@ -1979,11 +2248,40 @@ void ast_log(int level, const char *file, int line, const char *function, const
 
 int main(int argc,char **argv) {
 	char s[4096];
+	char out[4096];
+	FILE *infile;
 	
-	if (ast_expr(argv[1], s, sizeof(s)))
-		printf("=====%s======\n",s);
+	if( !argv[1] )
+		exit(20);
+	
+	if( access(argv[1],F_OK)== 0 )
+	{
+		int ret;
+		
+		infile = fopen(argv[1],"r");
+		if( !infile )
+		{
+			printf("Sorry, couldn't open %s for reading!\n", argv[1]);
+			exit(10);
+		}
+		while( fgets(s,sizeof(s),infile) )
+		{
+			if( s[strlen(s)-1] == '\n' )
+				s[strlen(s)-1] = 0;
+			
+			ret = ast_expr(s, out, sizeof(out));
+			printf("Expression: %s    Result: [%d] '%s'\n",
+				   s, ret, out);
+		}
+		fclose(infile);
+	}
 	else
-		printf("No result\n");
+	{
+		if (ast_expr(argv[1], s, sizeof(s)))
+			printf("=====%s======\n",s);
+		else
+			printf("No result\n");
+	}
 }
 
 #endif
@@ -2207,7 +2505,8 @@ op_plus (struct val *a, struct val *b)
 	struct val *r;
 
 	if (!to_integer (a)) {
-		ast_log(LOG_WARNING,"non-numeric argument\n");
+		if( !extra_error_message_supplied )
+			ast_log(LOG_WARNING,"non-numeric argument\n");
 		if (!to_integer (b)) {
 			free_value(a);
 			free_value(b);
@@ -2250,7 +2549,8 @@ op_minus (struct val *a, struct val *b)
 	struct val *r;
 
 	if (!to_integer (a)) {
-		ast_log(LOG_WARNING, "non-numeric argument\n");
+		if( !extra_error_message_supplied )
+			ast_log(LOG_WARNING, "non-numeric argument\n");
 		if (!to_integer (b)) {
 			free_value(a);
 			free_value(b);
@@ -2262,7 +2562,8 @@ op_minus (struct val *a, struct val *b)
 			return (r);
 		}
 	} else if (!to_integer(b)) {
-		ast_log(LOG_WARNING, "non-numeric argument\n");
+		if( !extra_error_message_supplied )
+			ast_log(LOG_WARNING, "non-numeric argument\n");
 		free_value(b);
 		return (a);
 	}
@@ -2283,7 +2584,8 @@ op_negate (struct val *a)
 
 	if (!to_integer (a) ) {
 		free_value(a);
-		ast_log(LOG_WARNING, "non-numeric argument\n");
+		if( !extra_error_message_supplied )
+			ast_log(LOG_WARNING, "non-numeric argument\n");
 		return make_integer(0);
 	}
 
@@ -2365,7 +2667,8 @@ op_times (struct val *a, struct val *b)
 	if (!to_integer (a) || !to_integer (b)) {
 		free_value(a);
 		free_value(b);
-		ast_log(LOG_WARNING, "non-numeric argument\n");
+		if( !extra_error_message_supplied )
+			ast_log(LOG_WARNING, "non-numeric argument\n");
 		return(make_integer(0));
 	}
 
@@ -2397,12 +2700,14 @@ op_div (struct val *a, struct val *b)
 	if (!to_integer (a)) {
 		free_value(a);
 		free_value(b);
-		ast_log(LOG_WARNING, "non-numeric argument\n");
+		if( !extra_error_message_supplied )
+			ast_log(LOG_WARNING, "non-numeric argument\n");
 		return make_integer(0);
 	} else if (!to_integer (b)) {
 		free_value(a);
 		free_value(b);
-		ast_log(LOG_WARNING, "non-numeric argument\n");
+		if( !extra_error_message_supplied )
+			ast_log(LOG_WARNING, "non-numeric argument\n");
 		return make_integer(INT_MAX);
 	}
 
@@ -2428,7 +2733,8 @@ op_rem (struct val *a, struct val *b)
 	struct val *r;
 
 	if (!to_integer (a) || !to_integer (b)) {
-		ast_log(LOG_WARNING, "non-numeric argument\n");
+		if( !extra_error_message_supplied )
+			ast_log(LOG_WARNING, "non-numeric argument\n");
 		free_value(a);
 		free_value(b);
 		return make_integer(0);
diff --git a/ast_expr2.fl b/ast_expr2.fl
index 8eaea639fa..6273bc8b1c 100644
--- a/ast_expr2.fl
+++ b/ast_expr2.fl
@@ -19,7 +19,7 @@
 
 /*! \file
  *
- * \brief Dialplan Expression Parser
+ * \brief Dialplan Expression Lexical Scanner
  */
 
 #include <sys/types.h>
@@ -73,6 +73,7 @@ struct parse_io
 void ast_yyset_column(int column_no, yyscan_t yyscanner);
 int ast_yyget_column(yyscan_t yyscanner);
 static int curlycount = 0;
+static char *expr2_token_subst(char *mess);
 %}
 
 %option prefix="ast_yy"
@@ -89,6 +90,10 @@ static int curlycount = 0;
 \|	{ SET_COLUMNS; SET_STRING; return TOK_OR;}
 \&	{ SET_COLUMNS; SET_STRING; return TOK_AND;}
 \=	{ SET_COLUMNS; SET_STRING; return TOK_EQ;}
+\|\|	{ SET_COLUMNS; SET_STRING; return TOK_OR;}
+\&\&	{ SET_COLUMNS; SET_STRING; return TOK_AND;}
+\=\=	{ SET_COLUMNS; SET_STRING; return TOK_EQ;}
+\=~	{ SET_COLUMNS; SET_STRING; return TOK_EQTILDE;}
 \>	{ SET_COLUMNS; SET_STRING; return TOK_GT;}
 \<	{ SET_COLUMNS; SET_STRING; return TOK_LT;}
 \>\=	{ SET_COLUMNS; SET_STRING; return TOK_GE;}
@@ -100,6 +105,7 @@ static int curlycount = 0;
 \/	{ SET_COLUMNS; SET_STRING; return TOK_DIV;}
 \%	{ SET_COLUMNS; SET_STRING; return TOK_MOD;}
 \?	{ SET_COLUMNS; SET_STRING; return TOK_COND;}
+\!	{ SET_COLUMNS; SET_STRING; return TOK_COMPL;}
 \:	{ SET_COLUMNS; SET_STRING; return TOK_COLON;}
 \:\:	{ SET_COLUMNS; SET_STRING; return TOK_COLONCOLON;}
 \(	{ SET_COLUMNS; SET_STRING; return TOK_LP;}
@@ -114,14 +120,15 @@ static int curlycount = 0;
 [0-9]+		{   SET_COLUMNS;  /* the original behavior of the expression parser was to bring in numbers as a numeric string */
 				SET_NUMERIC_STRING;
 				return TOKEN;}
-[a-zA-Z0-9,.';\\_^%$#@!]+	{SET_COLUMNS; SET_STRING; return TOKEN;}
+
+[a-zA-Z0-9,.';\\_^$#@]+	{SET_COLUMNS; SET_STRING; return TOKEN;}
 
 <var>[^{}]*\}  {curlycount--; if(curlycount < 0){ BEGIN(trail);  yymore();} else {  yymore();}}
 <var>[^{}]*\{  {curlycount++; yymore();  }
 <trail>[^-\t\r \n$():?%/+=*<>!|&]* {BEGIN(0); SET_COLUMNS; SET_STRING; return TOKEN;}
 <trail>[-\t\r \n$():?%/+=*<>!|&]        {char c = yytext[yyleng-1]; BEGIN(0); unput(c); SET_COLUMNS; SET_STRING; return TOKEN;}
 <trail>\$\{            {curlycount = 0; BEGIN(var); yymore();  }
-<trail><<EOF>>		{BEGIN(0); SET_COLUMNS; SET_STRING; return TOKEN; /* actually, if an expr is only a variable ref, this could happen a LOT */}
+<trail><<EOF>>		{BEGIN(0); SET_COLUMNS; SET_STRING; return TOKEN; /*actually, if an expr is only a variable ref, this could happen a LOT */}
 
 %%
 
@@ -175,16 +182,129 @@ int ast_expr(char *expr, char *buf, int length)
 	return return_value;
 }
 
+
+char extra_error_message[4095];
+int extra_error_message_supplied = 0;
+void  ast_expr_register_extra_error_info(char *message);
+void  ast_expr_clear_extra_error_info(void);
+
+void  ast_expr_register_extra_error_info(char *message)
+{
+       extra_error_message_supplied=1;
+       strcpy(extra_error_message, message);
+}
+
+void  ast_expr_clear_extra_error_info(void)
+{
+       extra_error_message_supplied=0;
+       extra_error_message[0] = 0;
+}
+
+static char *expr2_token_equivs1[] = 
+{
+	"TOKEN",
+	"TOK_COND",
+	"TOK_COLONCOLON",
+	"TOK_OR",
+	"TOK_AND",
+	"TOK_EQ",
+	"TOK_GT",
+	"TOK_LT",
+	"TOK_GE",
+	"TOK_LE",
+	"TOK_NE",
+	"TOK_PLUS",
+	"TOK_MINUS",
+	"TOK_MULT",
+	"TOK_DIV",
+	"TOK_MOD",
+	"TOK_COMPL",
+	"TOK_COLON",
+	"TOK_EQTILDE",
+	"TOK_RP",
+	"TOK_LP"
+};
+
+static char *expr2_token_equivs2[] = 
+{
+	"<token>",
+	"?",
+	"::",
+	"|",
+	"&",
+	"=",
+	">",
+	"<",
+	">=",
+	"<=",
+	"!=",
+	"+",
+	"-",
+	"*",
+	"/",
+	"%",
+	"!",
+	":",
+	"=~",
+	")",
+	"("
+};
+
+
+static char *expr2_token_subst(char *mess)
+{
+	/* calc a length, malloc, fill, and return; yyerror had better free it! */
+	int len=0,i;
+	char *p;
+	char *res, *s,*t;
+	int expr2_token_equivs_entries = sizeof(expr2_token_equivs1)/sizeof(char*);
+
+	for (p=mess; *p; p++) {
+		for (i=0; i<expr2_token_equivs_entries; i++) {
+			if ( strncmp(p,expr2_token_equivs1[i],strlen(expr2_token_equivs1[i])) == 0 )
+			{
+				len+=strlen(expr2_token_equivs2[i])+2;
+				p += strlen(expr2_token_equivs1[i])-1;
+				break;
+			}
+		}
+		len++;
+	}
+	res = (char*)malloc(len+1);
+	res[0] = 0;
+	s = res;
+	for (p=mess; *p;) {
+		int found = 0;
+		for (i=0; i<expr2_token_equivs_entries; i++) {
+			if ( strncmp(p,expr2_token_equivs1[i],strlen(expr2_token_equivs1[i])) == 0 ) {
+				*s++ = '\'';
+				for (t=expr2_token_equivs2[i]; *t;) {
+					*s++ = *t++;
+				}
+				*s++ = '\'';
+				p += strlen(expr2_token_equivs1[i]);
+				found = 1;
+				break;
+			}
+		}
+		if( !found )
+			*s++ = *p++;
+	}
+	*s++ = 0;
+	return res;
+}
+
 int ast_yyerror (const char *s,  yyltype *loc, struct parse_io *parseio )
 {	
 	struct yyguts_t * yyg = (struct yyguts_t*)(parseio->scanner);
 	char spacebuf[8000]; /* best safe than sorry */
 	char spacebuf2[8000]; /* best safe than sorry */
 	int i=0;
+	char *s2 = expr2_token_subst((char *)s);
 	spacebuf[0] = 0;
 	
 	for(i=0;i< (int)(yytext - YY_CURRENT_BUFFER_LVALUE->yy_ch_buf);i++) spacebuf2[i] = ' ';  /* uh... assuming yyg is defined, then I can use the yycolumn macro,
-													which is the same thing as... get this:
+																								which is the same thing as... get this:
 													yyg->yy_buffer_stack[yyg->yy_buffer_stack_top]->yy_bs_column
 													I was tempted to just use yy_buf_pos in the STATE, but..., well:
 														a. the yy_buf_pos is the current position in the buffer, which
@@ -199,14 +319,15 @@ int ast_yyerror (const char *s,  yyltype *loc, struct parse_io *parseio )
 
 #ifdef STANDALONE3
 	/* easier to read in the standalone version */
-	printf("ast_yyerror(): syntax error: %s; Input:\n%s\n%s\n",  
-			s, parseio->string,spacebuf2);
+	printf("ast_yyerror(): %s syntax error: %s; Input:\n%s\n%s\n",  
+			(extra_error_message_supplied?extra_error_message:""), s2, parseio->string,spacebuf2);
 #else
-	ast_log(LOG_WARNING,"ast_yyerror(): syntax error: %s; Input:\n%s\n%s\n",  
-			s, parseio->string,spacebuf2);
+	ast_log(LOG_WARNING,"ast_yyerror(): %s syntax error: %s; Input:\n%s\n%s\n",  
+			(extra_error_message_supplied?extra_error_message:""), s2, parseio->string,spacebuf2);
 #endif
 #ifndef STANDALONE
 	ast_log(LOG_WARNING,"If you have questions, please refer to doc/channelvariables.txt in the asterisk source.\n");
 #endif
+	free(s2);
 	return(0);
 }
diff --git a/ast_expr2.h b/ast_expr2.h
index f90139c8e7..190ef975c2 100644
--- a/ast_expr2.h
+++ b/ast_expr2.h
@@ -1,7 +1,7 @@
-/* A Bison parser, made by GNU Bison 2.1.  */
+/* A Bison parser, made by GNU Bison 2.1a.  */
 
 /* Skeleton parser for Yacc-like parsing with Bison,
-   Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+   Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -78,13 +78,15 @@
 
 
 
-#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED)
-#line 142 "ast_expr2.y"
-typedef union YYSTYPE {
+#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
+typedef union YYSTYPE
+#line 140 "ast_expr2.y"
+{
 	struct val *val;
-} YYSTYPE;
-/* Line 1447 of yacc.c.  */
-#line 88 "ast_expr2.h"
+}
+/* Line 1536 of yacc.c.  */
+#line 89 "ast_expr2.h"
+	YYSTYPE;
 # define yystype YYSTYPE /* obsolescent; will be withdrawn */
 # define YYSTYPE_IS_DECLARED 1
 # define YYSTYPE_IS_TRIVIAL 1
@@ -92,7 +94,7 @@ typedef union YYSTYPE {
 
 
 
-#if ! defined (YYLTYPE) && ! defined (YYLTYPE_IS_DECLARED)
+#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED
 typedef struct YYLTYPE
 {
   int first_line;
diff --git a/ast_expr2.y b/ast_expr2.y
index 58295c9f63..6886cf7c40 100644
--- a/ast_expr2.y
+++ b/ast_expr2.y
@@ -17,6 +17,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <locale.h>
+#include <unistd.h>
 #include <ctype.h>
 #if !defined(SOLARIS) && !defined(__CYGWIN__)
 #include <err.h>
@@ -51,6 +52,8 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
 #define YYPARSE_PARAM parseio
 #define YYLEX_PARAM ((struct parse_io *)parseio)->scanner
 #define YYERROR_VERBOSE 1
+extern char extra_error_message[4095];
+extern int extra_error_message_supplied;
 
 enum valtype {
 	AST_EXPR_integer, AST_EXPR_numeric_string, AST_EXPR_string
@@ -129,12 +132,7 @@ int		ast_yyerror(const char *,YYLTYPE *, struct parse_io *);
    some useful info about the error. Not as easy as it looks, but it
    is possible. */
 #define ast_yyerror(x) ast_yyerror(x,&yyloc,parseio)
-#define DESTROY(x) { \
-if ((x)->type == AST_EXPR_numeric_string || (x)->type == AST_EXPR_string) \
-	free((x)->u.s); \
-	(x)->u.s = 0; \
-	free(x); \
-}
+#define DESTROY(x) {if((x)->type == AST_EXPR_numeric_string || (x)->type == AST_EXPR_string) free((x)->u.s); (x)->u.s = 0; free(x);}
 %}
  
 %pure-parser
@@ -165,6 +163,11 @@ extern int		ast_yylex __P((YYSTYPE *, YYLTYPE *, yyscan_t));
 %token <val> TOKEN
 %type <val> start expr
 
+
+%destructor {  free_value($$); }  expr TOKEN TOK_COND TOK_COLONCOLON TOK_OR TOK_AND TOK_EQ 
+                                 TOK_GT TOK_LT TOK_GE TOK_LE TOK_NE TOK_PLUS TOK_MINUS TOK_MULT TOK_DIV TOK_MOD TOK_COMPL TOK_COLON TOK_EQTILDE 
+                                 TOK_RP TOK_LP
+
 %%
 
 start: expr { ((struct parse_io *)parseio)->val = (struct val *)calloc(sizeof(struct val),1);
@@ -175,6 +178,11 @@ start: expr { ((struct parse_io *)parseio)->val = (struct val *)calloc(sizeof(st
 				  ((struct parse_io *)parseio)->val->u.s = $1->u.s; 
 			  free($1);
 			}
+	| {/* nothing */ ((struct parse_io *)parseio)->val = (struct val *)calloc(sizeof(struct val),1);
+              ((struct parse_io *)parseio)->val->type = AST_EXPR_string;
+			  ((struct parse_io *)parseio)->val->u.s = strdup(""); 
+			}
+
 	;
 
 expr:	TOKEN   { $$= $1;}
@@ -427,11 +435,40 @@ void ast_log(int level, const char *file, int line, const char *function, const
 
 int main(int argc,char **argv) {
 	char s[4096];
+	char out[4096];
+	FILE *infile;
 	
-	if (ast_expr(argv[1], s, sizeof(s)))
-		printf("=====%s======\n",s);
+	if( !argv[1] )
+		exit(20);
+	
+	if( access(argv[1],F_OK)== 0 )
+	{
+		int ret;
+		
+		infile = fopen(argv[1],"r");
+		if( !infile )
+		{
+			printf("Sorry, couldn't open %s for reading!\n", argv[1]);
+			exit(10);
+		}
+		while( fgets(s,sizeof(s),infile) )
+		{
+			if( s[strlen(s)-1] == '\n' )
+				s[strlen(s)-1] = 0;
+			
+			ret = ast_expr(s, out, sizeof(out));
+			printf("Expression: %s    Result: [%d] '%s'\n",
+				   s, ret, out);
+		}
+		fclose(infile);
+	}
 	else
-		printf("No result\n");
+	{
+		if (ast_expr(argv[1], s, sizeof(s)))
+			printf("=====%s======\n",s);
+		else
+			printf("No result\n");
+	}
 }
 
 #endif
@@ -655,7 +692,8 @@ op_plus (struct val *a, struct val *b)
 	struct val *r;
 
 	if (!to_integer (a)) {
-		ast_log(LOG_WARNING,"non-numeric argument\n");
+		if( !extra_error_message_supplied )
+			ast_log(LOG_WARNING,"non-numeric argument\n");
 		if (!to_integer (b)) {
 			free_value(a);
 			free_value(b);
@@ -698,7 +736,8 @@ op_minus (struct val *a, struct val *b)
 	struct val *r;
 
 	if (!to_integer (a)) {
-		ast_log(LOG_WARNING, "non-numeric argument\n");
+		if( !extra_error_message_supplied )
+			ast_log(LOG_WARNING, "non-numeric argument\n");
 		if (!to_integer (b)) {
 			free_value(a);
 			free_value(b);
@@ -710,7 +749,8 @@ op_minus (struct val *a, struct val *b)
 			return (r);
 		}
 	} else if (!to_integer(b)) {
-		ast_log(LOG_WARNING, "non-numeric argument\n");
+		if( !extra_error_message_supplied )
+			ast_log(LOG_WARNING, "non-numeric argument\n");
 		free_value(b);
 		return (a);
 	}
@@ -731,7 +771,8 @@ op_negate (struct val *a)
 
 	if (!to_integer (a) ) {
 		free_value(a);
-		ast_log(LOG_WARNING, "non-numeric argument\n");
+		if( !extra_error_message_supplied )
+			ast_log(LOG_WARNING, "non-numeric argument\n");
 		return make_integer(0);
 	}
 
@@ -813,7 +854,8 @@ op_times (struct val *a, struct val *b)
 	if (!to_integer (a) || !to_integer (b)) {
 		free_value(a);
 		free_value(b);
-		ast_log(LOG_WARNING, "non-numeric argument\n");
+		if( !extra_error_message_supplied )
+			ast_log(LOG_WARNING, "non-numeric argument\n");
 		return(make_integer(0));
 	}
 
@@ -845,12 +887,14 @@ op_div (struct val *a, struct val *b)
 	if (!to_integer (a)) {
 		free_value(a);
 		free_value(b);
-		ast_log(LOG_WARNING, "non-numeric argument\n");
+		if( !extra_error_message_supplied )
+			ast_log(LOG_WARNING, "non-numeric argument\n");
 		return make_integer(0);
 	} else if (!to_integer (b)) {
 		free_value(a);
 		free_value(b);
-		ast_log(LOG_WARNING, "non-numeric argument\n");
+		if( !extra_error_message_supplied )
+			ast_log(LOG_WARNING, "non-numeric argument\n");
 		return make_integer(INT_MAX);
 	}
 
@@ -876,7 +920,8 @@ op_rem (struct val *a, struct val *b)
 	struct val *r;
 
 	if (!to_integer (a) || !to_integer (b)) {
-		ast_log(LOG_WARNING, "non-numeric argument\n");
+		if( !extra_error_message_supplied )
+			ast_log(LOG_WARNING, "non-numeric argument\n");
 		free_value(a);
 		free_value(b);
 		return make_integer(0);
diff --git a/ast_expr2f.c b/ast_expr2f.c
index ed87455960..bc0dcb34f1 100644
--- a/ast_expr2f.c
+++ b/ast_expr2f.c
@@ -523,34 +523,34 @@ static yyconst flex_int16_t yy_nxt[][128] =
         7,  -11,  -11,  -11,  -11,  -11,  -11,  -11,  -11,  -11,
       -11,  -11,  -11,  -11,  -11,  -11,  -11,  -11,  -11,  -11,
       -11,  -11,  -11,  -11,  -11,  -11,  -11,  -11,  -11,  -11,
-      -11,  -11,  -11,   36,  -11,   36,   36,   36,  -11,   36,
-      -11,  -11,  -11,  -11,   36,  -11,   36,  -11,   36,   36,
-       36,   36,   36,   36,   36,   36,   36,   36,  -11,   36,
-      -11,   37,  -11,  -11,   36,   36,   36,   36,   36,   36,
-
-       36,   36,   36,   36,   36,   36,   36,   36,   36,   36,
-       36,   36,   36,   36,   36,   36,   36,   36,   36,   36,
-       36,  -11,   36,  -11,   36,   36,  -11,   36,   36,   36,
-       36,   36,   36,   36,   36,   36,   36,   36,   36,   36,
-       36,   36,   36,   36,   36,   36,   36,   36,   36,   36,
-       36,   36,   36,  -11,  -11,  -11,  -11,  -11
+      -11,  -11,  -11,  -11,  -11,  -11,  -11,  -11,  -11,  -11,
+      -11,  -11,  -11,  -11,  -11,  -11,  -11,  -11,  -11,  -11,
+      -11,  -11,  -11,  -11,  -11,  -11,  -11,  -11,  -11,  -11,
+      -11,   36,  -11,  -11,  -11,  -11,  -11,  -11,  -11,  -11,
+
+      -11,  -11,  -11,  -11,  -11,  -11,  -11,  -11,  -11,  -11,
+      -11,  -11,  -11,  -11,  -11,  -11,  -11,  -11,  -11,  -11,
+      -11,  -11,  -11,  -11,  -11,  -11,  -11,  -11,  -11,  -11,
+      -11,  -11,  -11,  -11,  -11,  -11,  -11,  -11,  -11,  -11,
+      -11,  -11,  -11,  -11,  -11,  -11,  -11,  -11,  -11,  -11,
+      -11,  -11,  -11,  -11,  -11,  -11,  -11,  -11
     },
 
     {
-        7,   38,   38,   38,   38,   38,   38,   38,   38,   38,
-       38,   38,   38,   38,   38,   38,   38,   38,   38,   38,
-       38,   38,   38,   38,   38,   38,   38,   38,   38,   38,
-       38,   38,   38,   38,   39,   38,   38,   38,   38,   38,
-
-       38,   38,   38,   38,   38,   38,   38,   38,   38,   38,
-       38,   38,   38,   38,   38,   38,   38,   38,   38,   38,
-       38,   38,   38,   38,   38,   38,   38,   38,   38,   38,
-       38,   38,   38,   38,   38,   38,   38,   38,   38,   38,
-       38,   38,   38,   38,   38,   38,   38,   38,   38,   38,
-       38,   38,   38,   38,   38,   38,   38,   38,   38,   38,
-       38,   38,   38,   38,   38,   38,   38,   38,   38,   38,
-       38,   38,   38,   38,   38,   38,   38,   38,   38,   38,
-       38,   38,   38,   38,   38,   38,   38,   38
+        7,   37,   37,   37,   37,   37,   37,   37,   37,   37,
+       37,   37,   37,   37,   37,   37,   37,   37,   37,   37,
+       37,   37,   37,   37,   37,   37,   37,   37,   37,   37,
+       37,   37,   37,   37,   38,   37,   37,   37,   37,   37,
+
+       37,   37,   37,   37,   37,   37,   37,   37,   37,   37,
+       37,   37,   37,   37,   37,   37,   37,   37,   37,   37,
+       37,   37,   37,   37,   37,   37,   37,   37,   37,   37,
+       37,   37,   37,   37,   37,   37,   37,   37,   37,   37,
+       37,   37,   37,   37,   37,   37,   37,   37,   37,   37,
+       37,   37,   37,   37,   37,   37,   37,   37,   37,   37,
+       37,   37,   37,   37,   37,   37,   37,   37,   37,   37,
+       37,   37,   37,   37,   37,   37,   37,   37,   37,   37,
+       37,   37,   37,   37,   37,   37,   37,   37
     },
 
     {
@@ -558,51 +558,51 @@ static yyconst flex_int16_t yy_nxt[][128] =
 
       -13,  -13,  -13,  -13,  -13,  -13,  -13,  -13,  -13,  -13,
       -13,  -13,  -13,  -13,  -13,  -13,  -13,  -13,  -13,  -13,
-      -13,  -13,  -13,   36,  -13,   36,   36,   36,  -13,   36,
-      -13,  -13,  -13,  -13,   36,  -13,   36,  -13,   36,   36,
-       36,   36,   36,   36,   36,   36,   36,   36,  -13,   36,
-      -13,  -13,  -13,  -13,   36,   36,   36,   36,   36,   36,
-       36,   36,   36,   36,   36,   36,   36,   36,   36,   36,
-       36,   36,   36,   36,   36,   36,   36,   36,   36,   36,
-       36,  -13,   36,  -13,   36,   36,  -13,   36,   36,   36,
-       36,   36,   36,   36,   36,   36,   36,   36,   36,   36,
-
-       36,   36,   36,   36,   36,   36,   36,   36,   36,   36,
-       36,   36,   36,  -13,  -13,  -13,  -13,  -13
+      -13,  -13,  -13,  -13,  -13,   39,   39,  -13,  -13,   39,
+      -13,  -13,  -13,  -13,   39,  -13,   39,  -13,   39,   39,
+       39,   39,   39,   39,   39,   39,   39,   39,  -13,   39,
+      -13,  -13,  -13,  -13,   39,   39,   39,   39,   39,   39,
+       39,   39,   39,   39,   39,   39,   39,   39,   39,   39,
+       39,   39,   39,   39,   39,   39,   39,   39,   39,   39,
+       39,  -13,   39,  -13,   39,   39,  -13,   39,   39,   39,
+       39,   39,   39,   39,   39,   39,   39,   39,   39,   39,
+
+       39,   39,   39,   39,   39,   39,   39,   39,   39,   39,
+       39,   39,   39,  -13,  -13,  -13,  -13,  -13
     },
 
     {
         7,  -14,  -14,  -14,  -14,  -14,  -14,  -14,  -14,  -14,
       -14,  -14,  -14,  -14,  -14,  -14,  -14,  -14,  -14,  -14,
       -14,  -14,  -14,  -14,  -14,  -14,  -14,  -14,  -14,  -14,
-      -14,  -14,  -14,   36,  -14,   36,   36,   36,  -14,   36,
-      -14,  -14,  -14,  -14,   36,  -14,   36,  -14,   36,   36,
-       36,   36,   36,   36,   36,   36,   36,   36,  -14,   36,
-      -14,  -14,  -14,  -14,   36,   36,   36,   36,   36,   36,
-       36,   36,   36,   36,   36,   36,   36,   36,   36,   36,
-
-       36,   36,   36,   36,   36,   36,   36,   36,   36,   36,
-       36,  -14,   36,  -14,   36,   36,  -14,   36,   36,   36,
-       36,   36,   36,   36,   36,   36,   36,   36,   36,   36,
-       36,   36,   36,   36,   36,   36,   36,   36,   36,   36,
-       36,   36,   36,   40,  -14,  -14,  -14,  -14
+      -14,  -14,  -14,  -14,  -14,   39,   39,  -14,  -14,   39,
+      -14,  -14,  -14,  -14,   39,  -14,   39,  -14,   39,   39,
+       39,   39,   39,   39,   39,   39,   39,   39,  -14,   39,
+      -14,  -14,  -14,  -14,   39,   39,   39,   39,   39,   39,
+       39,   39,   39,   39,   39,   39,   39,   39,   39,   39,
+
+       39,   39,   39,   39,   39,   39,   39,   39,   39,   39,
+       39,  -14,   39,  -14,   39,   39,  -14,   39,   39,   39,
+       39,   39,   39,   39,   39,   39,   39,   39,   39,   39,
+       39,   39,   39,   39,   39,   39,   39,   39,   39,   39,
+       39,   39,   39,   40,  -14,  -14,  -14,  -14
     },
 
     {
         7,  -15,  -15,  -15,  -15,  -15,  -15,  -15,  -15,  -15,
       -15,  -15,  -15,  -15,  -15,  -15,  -15,  -15,  -15,  -15,
       -15,  -15,  -15,  -15,  -15,  -15,  -15,  -15,  -15,  -15,
-      -15,  -15,  -15,   36,  -15,   36,   36,   36,  -15,   36,
-      -15,  -15,  -15,  -15,   36,  -15,   36,  -15,   36,   36,
-
-       36,   36,   36,   36,   36,   36,   36,   36,  -15,   36,
-      -15,  -15,  -15,  -15,   36,   36,   36,   36,   36,   36,
-       36,   36,   36,   36,   36,   36,   36,   36,   36,   36,
-       36,   36,   36,   36,   36,   36,   36,   36,   36,   36,
-       36,  -15,   36,  -15,   36,   36,  -15,   36,   36,   36,
-       36,   36,   36,   36,   36,   36,   36,   36,   36,   36,
-       36,   36,   36,   36,   36,   36,   36,   36,   36,   36,
-       36,   36,   36,  -15,  -15,  -15,  -15,  -15
+      -15,  -15,  -15,  -15,  -15,  -15,  -15,  -15,  -15,  -15,
+      -15,  -15,  -15,  -15,  -15,  -15,  -15,  -15,  -15,  -15,
+
+      -15,  -15,  -15,  -15,  -15,  -15,  -15,  -15,  -15,  -15,
+      -15,  -15,  -15,  -15,  -15,  -15,  -15,  -15,  -15,  -15,
+      -15,  -15,  -15,  -15,  -15,  -15,  -15,  -15,  -15,  -15,
+      -15,  -15,  -15,  -15,  -15,  -15,  -15,  -15,  -15,  -15,
+      -15,  -15,  -15,  -15,  -15,  -15,  -15,  -15,  -15,  -15,
+      -15,  -15,  -15,  -15,  -15,  -15,  -15,  -15,  -15,  -15,
+      -15,  -15,  -15,  -15,  -15,  -15,  -15,  -15,  -15,  -15,
+      -15,  -15,  -15,  -15,  -15,  -15,  -15,  -15
     },
 
     {
@@ -610,7 +610,7 @@ static yyconst flex_int16_t yy_nxt[][128] =
       -16,  -16,  -16,  -16,  -16,  -16,  -16,  -16,  -16,  -16,
 
       -16,  -16,  -16,  -16,  -16,  -16,  -16,  -16,  -16,  -16,
-      -16,  -16,  -16,  -16,  -16,  -16,  -16,  -16,  -16,  -16,
+      -16,  -16,  -16,  -16,  -16,  -16,  -16,  -16,   41,  -16,
       -16,  -16,  -16,  -16,  -16,  -16,  -16,  -16,  -16,  -16,
       -16,  -16,  -16,  -16,  -16,  -16,  -16,  -16,  -16,  -16,
       -16,  -16,  -16,  -16,  -16,  -16,  -16,  -16,  -16,  -16,
@@ -731,17 +731,17 @@ static yyconst flex_int16_t yy_nxt[][128] =
 
       -23,  -23,  -23,  -23,  -23,  -23,  -23,  -23,  -23,  -23,
       -23,  -23,  -23,  -23,  -23,  -23,  -23,  -23,  -23,  -23,
-      -23,  -23,  -23,   36,  -23,   36,   36,   36,  -23,   36,
-      -23,  -23,  -23,  -23,   36,  -23,   36,  -23,   41,   41,
-       41,   41,   41,   41,   41,   41,   41,   41,  -23,   36,
-      -23,  -23,  -23,  -23,   36,   36,   36,   36,   36,   36,
-       36,   36,   36,   36,   36,   36,   36,   36,   36,   36,
-       36,   36,   36,   36,   36,   36,   36,   36,   36,   36,
-       36,  -23,   36,  -23,   36,   36,  -23,   36,   36,   36,
-       36,   36,   36,   36,   36,   36,   36,   36,   36,   36,
-
-       36,   36,   36,   36,   36,   36,   36,   36,   36,   36,
-       36,   36,   36,  -23,  -23,  -23,  -23,  -23
+      -23,  -23,  -23,  -23,  -23,   39,   39,  -23,  -23,   39,
+      -23,  -23,  -23,  -23,   39,  -23,   39,  -23,   42,   42,
+       42,   42,   42,   42,   42,   42,   42,   42,  -23,   39,
+      -23,  -23,  -23,  -23,   39,   39,   39,   39,   39,   39,
+       39,   39,   39,   39,   39,   39,   39,   39,   39,   39,
+       39,   39,   39,   39,   39,   39,   39,   39,   39,   39,
+       39,  -23,   39,  -23,   39,   39,  -23,   39,   39,   39,
+       39,   39,   39,   39,   39,   39,   39,   39,   39,   39,
+
+       39,   39,   39,   39,   39,   39,   39,   39,   39,   39,
+       39,   39,   39,  -23,  -23,  -23,  -23,  -23
     },
 
     {
@@ -750,7 +750,7 @@ static yyconst flex_int16_t yy_nxt[][128] =
       -24,  -24,  -24,  -24,  -24,  -24,  -24,  -24,  -24,  -24,
       -24,  -24,  -24,  -24,  -24,  -24,  -24,  -24,  -24,  -24,
       -24,  -24,  -24,  -24,  -24,  -24,  -24,  -24,  -24,  -24,
-      -24,  -24,  -24,  -24,  -24,  -24,  -24,  -24,   42,  -24,
+      -24,  -24,  -24,  -24,  -24,  -24,  -24,  -24,   43,  -24,
       -24,  -24,  -24,  -24,  -24,  -24,  -24,  -24,  -24,  -24,
       -24,  -24,  -24,  -24,  -24,  -24,  -24,  -24,  -24,  -24,
 
@@ -769,7 +769,7 @@ static yyconst flex_int16_t yy_nxt[][128] =
       -25,  -25,  -25,  -25,  -25,  -25,  -25,  -25,  -25,  -25,
 
       -25,  -25,  -25,  -25,  -25,  -25,  -25,  -25,  -25,  -25,
-      -25,   43,  -25,  -25,  -25,  -25,  -25,  -25,  -25,  -25,
+      -25,   44,  -25,  -25,  -25,  -25,  -25,  -25,  -25,  -25,
       -25,  -25,  -25,  -25,  -25,  -25,  -25,  -25,  -25,  -25,
       -25,  -25,  -25,  -25,  -25,  -25,  -25,  -25,  -25,  -25,
       -25,  -25,  -25,  -25,  -25,  -25,  -25,  -25,  -25,  -25,
@@ -786,14 +786,14 @@ static yyconst flex_int16_t yy_nxt[][128] =
       -26,  -26,  -26,  -26,  -26,  -26,  -26,  -26,  -26,  -26,
       -26,  -26,  -26,  -26,  -26,  -26,  -26,  -26,  -26,  -26,
       -26,  -26,  -26,  -26,  -26,  -26,  -26,  -26,  -26,  -26,
-      -26,  -26,  -26,  -26,  -26,  -26,  -26,  -26,  -26,  -26,
+      -26,   45,  -26,  -26,  -26,  -26,  -26,  -26,  -26,  -26,
       -26,  -26,  -26,  -26,  -26,  -26,  -26,  -26,  -26,  -26,
       -26,  -26,  -26,  -26,  -26,  -26,  -26,  -26,  -26,  -26,
       -26,  -26,  -26,  -26,  -26,  -26,  -26,  -26,  -26,  -26,
       -26,  -26,  -26,  -26,  -26,  -26,  -26,  -26,  -26,  -26,
       -26,  -26,  -26,  -26,  -26,  -26,  -26,  -26,  -26,  -26,
 
-      -26,  -26,  -26,  -26,  -26,  -26,  -26,  -26
+      -26,  -26,  -26,  -26,  -26,  -26,   46,  -26
     },
 
     {
@@ -803,7 +803,7 @@ static yyconst flex_int16_t yy_nxt[][128] =
       -27,  -27,  -27,  -27,  -27,  -27,  -27,  -27,  -27,  -27,
       -27,  -27,  -27,  -27,  -27,  -27,  -27,  -27,  -27,  -27,
       -27,  -27,  -27,  -27,  -27,  -27,  -27,  -27,  -27,  -27,
-      -27,   44,  -27,  -27,  -27,  -27,  -27,  -27,  -27,  -27,
+      -27,   47,  -27,  -27,  -27,  -27,  -27,  -27,  -27,  -27,
       -27,  -27,  -27,  -27,  -27,  -27,  -27,  -27,  -27,  -27,
       -27,  -27,  -27,  -27,  -27,  -27,  -27,  -27,  -27,  -27,
 
@@ -844,25 +844,25 @@ static yyconst flex_int16_t yy_nxt[][128] =
       -29,  -29,  -29,  -29,  -29,  -29,  -29,  -29,  -29,  -29,
       -29,  -29,  -29,  -29,  -29,  -29,  -29,  -29,  -29,  -29,
       -29,  -29,  -29,  -29,  -29,  -29,  -29,  -29,  -29,  -29,
-      -29,  -29,  -29,  -29,  -29,  -29,  -29,  -29
+      -29,  -29,  -29,  -29,   48,  -29,  -29,  -29
 
     },
 
     {
-        7,   45,   45,   45,   45,   45,   45,   45,   45,   45,
-       45,   45,   45,   45,   45,   45,   45,   45,   45,   45,
-       45,   45,   45,   45,   45,   45,   45,   45,   45,   45,
-       45,   45,   45,   45,   45,   45,   45,   45,   45,   45,
-       45,   45,   45,   45,   45,   45,   45,   45,   45,   45,
-       45,   45,   45,   45,   45,   45,   45,   45,   45,   45,
-       45,   45,   45,   45,   45,   45,   45,   45,   45,   45,
-       45,   45,   45,   45,   45,   45,   45,   45,   45,   45,
-       45,   45,   45,   45,   45,   45,   45,   45,   45,   45,
-       45,   45,   45,   45,   45,   45,   45,   45,   45,   45,
-
-       45,   45,   45,   45,   45,   45,   45,   45,   45,   45,
-       45,   45,   45,   45,   45,   45,   45,   45,   45,   45,
-       45,   45,   45,   46,   45,   47,   45,   45
+        7,   49,   49,   49,   49,   49,   49,   49,   49,   49,
+       49,   49,   49,   49,   49,   49,   49,   49,   49,   49,
+       49,   49,   49,   49,   49,   49,   49,   49,   49,   49,
+       49,   49,   49,   49,   49,   49,   49,   49,   49,   49,
+       49,   49,   49,   49,   49,   49,   49,   49,   49,   49,
+       49,   49,   49,   49,   49,   49,   49,   49,   49,   49,
+       49,   49,   49,   49,   49,   49,   49,   49,   49,   49,
+       49,   49,   49,   49,   49,   49,   49,   49,   49,   49,
+       49,   49,   49,   49,   49,   49,   49,   49,   49,   49,
+       49,   49,   49,   49,   49,   49,   49,   49,   49,   49,
+
+       49,   49,   49,   49,   49,   49,   49,   49,   49,   49,
+       49,   49,   49,   49,   49,   49,   49,   49,   49,   49,
+       49,   49,   49,   50,   49,   51,   49,   49
     },
 
     {
@@ -900,21 +900,21 @@ static yyconst flex_int16_t yy_nxt[][128] =
     },
 
     {
-        7,   48,   48,   48,   48,   48,   48,   48,   48,  -33,
-
-      -33,   48,   48,  -33,   48,   48,   48,   48,   48,   48,
-       48,   48,   48,   48,   48,   48,   48,   48,   48,   48,
-       48,   48,  -33,  -33,   48,   48,  -33,  -33,  -33,   48,
-      -33,  -33,  -33,  -33,   48,  -33,   48,  -33,   48,   48,
-       48,   48,   48,   48,   48,   48,   48,   48,  -33,   48,
-      -33,  -33,  -33,  -33,   48,   48,   48,   48,   48,   48,
-       48,   48,   48,   48,   48,   48,   48,   48,   48,   48,
-       48,   48,   48,   48,   48,   48,   48,   48,   48,   48,
-       48,   48,   48,   48,   48,   48,   48,   48,   48,   48,
-       48,   48,   48,   48,   48,   48,   48,   48,   48,   48,
-
-       48,   48,   48,   48,   48,   48,   48,   48,   48,   48,
-       48,   48,   48,   48,  -33,   48,   48,   48
+        7,   52,   52,   52,   52,   52,   52,   52,   52,  -33,
+
+      -33,   52,   52,  -33,   52,   52,   52,   52,   52,   52,
+       52,   52,   52,   52,   52,   52,   52,   52,   52,   52,
+       52,   52,  -33,  -33,   52,   52,  -33,  -33,  -33,   52,
+      -33,  -33,  -33,  -33,   52,  -33,   52,  -33,   52,   52,
+       52,   52,   52,   52,   52,   52,   52,   52,  -33,   52,
+      -33,  -33,  -33,  -33,   52,   52,   52,   52,   52,   52,
+       52,   52,   52,   52,   52,   52,   52,   52,   52,   52,
+       52,   52,   52,   52,   52,   52,   52,   52,   52,   52,
+       52,   52,   52,   52,   52,   52,   52,   52,   52,   52,
+       52,   52,   52,   52,   52,   52,   52,   52,   52,   52,
+
+       52,   52,   52,   52,   52,   52,   52,   52,   52,   52,
+       52,   52,   52,   52,  -33,   52,   52,   52
     },
 
     {
@@ -948,7 +948,7 @@ static yyconst flex_int16_t yy_nxt[][128] =
       -35,  -35,  -35,  -35,  -35,  -35,  -35,  -35,  -35,  -35,
       -35,  -35,  -35,  -35,  -35,  -35,  -35,  -35,  -35,  -35,
       -35,  -35,  -35,  -35,  -35,  -35,  -35,  -35,  -35,  -35,
-      -35,  -35,  -35,   49,  -35,  -35,  -35,  -35
+      -35,  -35,  -35,   53,  -35,  -35,  -35,  -35
     },
 
     {
@@ -956,51 +956,51 @@ static yyconst flex_int16_t yy_nxt[][128] =
       -36,  -36,  -36,  -36,  -36,  -36,  -36,  -36,  -36,  -36,
 
       -36,  -36,  -36,  -36,  -36,  -36,  -36,  -36,  -36,  -36,
-      -36,  -36,  -36,   36,  -36,   36,   36,   36,  -36,   36,
-      -36,  -36,  -36,  -36,   36,  -36,   36,  -36,   36,   36,
-       36,   36,   36,   36,   36,   36,   36,   36,  -36,   36,
-      -36,  -36,  -36,  -36,   36,   36,   36,   36,   36,   36,
-       36,   36,   36,   36,   36,   36,   36,   36,   36,   36,
-       36,   36,   36,   36,   36,   36,   36,   36,   36,   36,
-       36,  -36,   36,  -36,   36,   36,  -36,   36,   36,   36,
-       36,   36,   36,   36,   36,   36,   36,   36,   36,   36,
-       36,   36,   36,   36,   36,   36,   36,   36,   36,   36,
-
-       36,   36,   36,  -36,  -36,  -36,  -36,  -36
+      -36,  -36,  -36,  -36,  -36,  -36,  -36,  -36,  -36,  -36,
+      -36,  -36,  -36,  -36,  -36,  -36,  -36,  -36,  -36,  -36,
+      -36,  -36,  -36,  -36,  -36,  -36,  -36,  -36,  -36,  -36,
+      -36,  -36,  -36,  -36,  -36,  -36,  -36,  -36,  -36,  -36,
+      -36,  -36,  -36,  -36,  -36,  -36,  -36,  -36,  -36,  -36,
+      -36,  -36,  -36,  -36,  -36,  -36,  -36,  -36,  -36,  -36,
+      -36,  -36,  -36,  -36,  -36,  -36,  -36,  -36,  -36,  -36,
+      -36,  -36,  -36,  -36,  -36,  -36,  -36,  -36,  -36,  -36,
+      -36,  -36,  -36,  -36,  -36,  -36,  -36,  -36,  -36,  -36,
+
+      -36,  -36,  -36,  -36,  -36,  -36,  -36,  -36
     },
 
     {
-        7,  -37,  -37,  -37,  -37,  -37,  -37,  -37,  -37,  -37,
-      -37,  -37,  -37,  -37,  -37,  -37,  -37,  -37,  -37,  -37,
-      -37,  -37,  -37,  -37,  -37,  -37,  -37,  -37,  -37,  -37,
-      -37,  -37,  -37,  -37,  -37,  -37,  -37,  -37,  -37,  -37,
-      -37,  -37,  -37,  -37,  -37,  -37,  -37,  -37,  -37,  -37,
-      -37,  -37,  -37,  -37,  -37,  -37,  -37,  -37,  -37,  -37,
-      -37,  -37,  -37,  -37,  -37,  -37,  -37,  -37,  -37,  -37,
-      -37,  -37,  -37,  -37,  -37,  -37,  -37,  -37,  -37,  -37,
-      -37,  -37,  -37,  -37,  -37,  -37,  -37,  -37,  -37,  -37,
-
-      -37,  -37,  -37,  -37,  -37,  -37,  -37,  -37,  -37,  -37,
-      -37,  -37,  -37,  -37,  -37,  -37,  -37,  -37,  -37,  -37,
-      -37,  -37,  -37,  -37,  -37,  -37,  -37,  -37,  -37,  -37,
-      -37,  -37,  -37,  -37,  -37,  -37,  -37,  -37
+        7,   37,   37,   37,   37,   37,   37,   37,   37,   37,
+       37,   37,   37,   37,   37,   37,   37,   37,   37,   37,
+       37,   37,   37,   37,   37,   37,   37,   37,   37,   37,
+       37,   37,   37,   37,   38,   37,   37,   37,   37,   37,
+       37,   37,   37,   37,   37,   37,   37,   37,   37,   37,
+       37,   37,   37,   37,   37,   37,   37,   37,   37,   37,
+       37,   37,   37,   37,   37,   37,   37,   37,   37,   37,
+       37,   37,   37,   37,   37,   37,   37,   37,   37,   37,
+       37,   37,   37,   37,   37,   37,   37,   37,   37,   37,
+
+       37,   37,   37,   37,   37,   37,   37,   37,   37,   37,
+       37,   37,   37,   37,   37,   37,   37,   37,   37,   37,
+       37,   37,   37,   37,   37,   37,   37,   37,   37,   37,
+       37,   37,   37,   37,   37,   37,   37,   37
     },
 
     {
-        7,   38,   38,   38,   38,   38,   38,   38,   38,   38,
-       38,   38,   38,   38,   38,   38,   38,   38,   38,   38,
-       38,   38,   38,   38,   38,   38,   38,   38,   38,   38,
-       38,   38,   38,   38,   39,   38,   38,   38,   38,   38,
-       38,   38,   38,   38,   38,   38,   38,   38,   38,   38,
-       38,   38,   38,   38,   38,   38,   38,   38,   38,   38,
-
-       38,   38,   38,   38,   38,   38,   38,   38,   38,   38,
-       38,   38,   38,   38,   38,   38,   38,   38,   38,   38,
-       38,   38,   38,   38,   38,   38,   38,   38,   38,   38,
-       38,   38,   38,   38,   38,   38,   38,   38,   38,   38,
-       38,   38,   38,   38,   38,   38,   38,   38,   38,   38,
-       38,   38,   38,   38,   38,   38,   38,   38,   38,   38,
-       38,   38,   38,   38,   38,   38,   38,   38
+        7,  -38,  -38,  -38,  -38,  -38,  -38,  -38,  -38,  -38,
+      -38,  -38,  -38,  -38,  -38,  -38,  -38,  -38,  -38,  -38,
+      -38,  -38,  -38,  -38,  -38,  -38,  -38,  -38,  -38,  -38,
+      -38,  -38,  -38,  -38,  -38,  -38,  -38,  -38,  -38,  -38,
+      -38,  -38,  -38,  -38,  -38,  -38,  -38,  -38,  -38,  -38,
+      -38,  -38,  -38,  -38,  -38,  -38,  -38,  -38,  -38,  -38,
+
+      -38,  -38,  -38,  -38,  -38,  -38,  -38,  -38,  -38,  -38,
+      -38,  -38,  -38,  -38,  -38,  -38,  -38,  -38,  -38,  -38,
+      -38,  -38,  -38,  -38,  -38,  -38,  -38,  -38,  -38,  -38,
+      -38,  -38,  -38,  -38,  -38,  -38,  -38,  -38,  -38,  -38,
+      -38,  -38,  -38,  -38,  -38,  -38,  -38,  -38,  -38,  -38,
+      -38,  -38,  -38,  -38,  -38,  -38,  -38,  -38,  -38,  -38,
+      -38,  -38,  -38,  -38,  -38,  -38,  -38,  -38
     },
 
     {
@@ -1008,16 +1008,16 @@ static yyconst flex_int16_t yy_nxt[][128] =
       -39,  -39,  -39,  -39,  -39,  -39,  -39,  -39,  -39,  -39,
       -39,  -39,  -39,  -39,  -39,  -39,  -39,  -39,  -39,  -39,
 
-      -39,  -39,  -39,  -39,  -39,  -39,  -39,  -39,  -39,  -39,
-      -39,  -39,  -39,  -39,  -39,  -39,  -39,  -39,  -39,  -39,
-      -39,  -39,  -39,  -39,  -39,  -39,  -39,  -39,  -39,  -39,
-      -39,  -39,  -39,  -39,  -39,  -39,  -39,  -39,  -39,  -39,
-      -39,  -39,  -39,  -39,  -39,  -39,  -39,  -39,  -39,  -39,
-      -39,  -39,  -39,  -39,  -39,  -39,  -39,  -39,  -39,  -39,
-      -39,  -39,  -39,  -39,  -39,  -39,  -39,  -39,  -39,  -39,
-      -39,  -39,  -39,  -39,  -39,  -39,  -39,  -39,  -39,  -39,
-      -39,  -39,  -39,  -39,  -39,  -39,  -39,  -39,  -39,  -39,
-      -39,  -39,  -39,  -39,  -39,  -39,  -39,  -39
+      -39,  -39,  -39,  -39,  -39,   39,   39,  -39,  -39,   39,
+      -39,  -39,  -39,  -39,   39,  -39,   39,  -39,   39,   39,
+       39,   39,   39,   39,   39,   39,   39,   39,  -39,   39,
+      -39,  -39,  -39,  -39,   39,   39,   39,   39,   39,   39,
+       39,   39,   39,   39,   39,   39,   39,   39,   39,   39,
+       39,   39,   39,   39,   39,   39,   39,   39,   39,   39,
+       39,  -39,   39,  -39,   39,   39,  -39,   39,   39,   39,
+       39,   39,   39,   39,   39,   39,   39,   39,   39,   39,
+       39,   39,   39,   39,   39,   39,   39,   39,   39,   39,
+       39,   39,   39,  -39,  -39,  -39,  -39,  -39
 
     },
 
@@ -1042,34 +1042,34 @@ static yyconst flex_int16_t yy_nxt[][128] =
         7,  -41,  -41,  -41,  -41,  -41,  -41,  -41,  -41,  -41,
       -41,  -41,  -41,  -41,  -41,  -41,  -41,  -41,  -41,  -41,
       -41,  -41,  -41,  -41,  -41,  -41,  -41,  -41,  -41,  -41,
-      -41,  -41,  -41,   36,  -41,   36,   36,   36,  -41,   36,
-      -41,  -41,  -41,  -41,   36,  -41,   36,  -41,   41,   41,
-       41,   41,   41,   41,   41,   41,   41,   41,  -41,   36,
-      -41,  -41,  -41,  -41,   36,   36,   36,   36,   36,   36,
-
-       36,   36,   36,   36,   36,   36,   36,   36,   36,   36,
-       36,   36,   36,   36,   36,   36,   36,   36,   36,   36,
-       36,  -41,   36,  -41,   36,   36,  -41,   36,   36,   36,
-       36,   36,   36,   36,   36,   36,   36,   36,   36,   36,
-       36,   36,   36,   36,   36,   36,   36,   36,   36,   36,
-       36,   36,   36,  -41,  -41,  -41,  -41,  -41
+      -41,  -41,  -41,  -41,  -41,  -41,  -41,  -41,  -41,  -41,
+      -41,  -41,  -41,  -41,  -41,  -41,  -41,  -41,  -41,  -41,
+      -41,  -41,  -41,  -41,  -41,  -41,  -41,  -41,  -41,  -41,
+      -41,  -41,  -41,  -41,  -41,  -41,  -41,  -41,  -41,  -41,
+
+      -41,  -41,  -41,  -41,  -41,  -41,  -41,  -41,  -41,  -41,
+      -41,  -41,  -41,  -41,  -41,  -41,  -41,  -41,  -41,  -41,
+      -41,  -41,  -41,  -41,  -41,  -41,  -41,  -41,  -41,  -41,
+      -41,  -41,  -41,  -41,  -41,  -41,  -41,  -41,  -41,  -41,
+      -41,  -41,  -41,  -41,  -41,  -41,  -41,  -41,  -41,  -41,
+      -41,  -41,  -41,  -41,  -41,  -41,  -41,  -41
     },
 
     {
         7,  -42,  -42,  -42,  -42,  -42,  -42,  -42,  -42,  -42,
       -42,  -42,  -42,  -42,  -42,  -42,  -42,  -42,  -42,  -42,
       -42,  -42,  -42,  -42,  -42,  -42,  -42,  -42,  -42,  -42,
-      -42,  -42,  -42,  -42,  -42,  -42,  -42,  -42,  -42,  -42,
-
-      -42,  -42,  -42,  -42,  -42,  -42,  -42,  -42,  -42,  -42,
-      -42,  -42,  -42,  -42,  -42,  -42,  -42,  -42,  -42,  -42,
-      -42,  -42,  -42,  -42,  -42,  -42,  -42,  -42,  -42,  -42,
-      -42,  -42,  -42,  -42,  -42,  -42,  -42,  -42,  -42,  -42,
-      -42,  -42,  -42,  -42,  -42,  -42,  -42,  -42,  -42,  -42,
-      -42,  -42,  -42,  -42,  -42,  -42,  -42,  -42,  -42,  -42,
-      -42,  -42,  -42,  -42,  -42,  -42,  -42,  -42,  -42,  -42,
-      -42,  -42,  -42,  -42,  -42,  -42,  -42,  -42,  -42,  -42,
-      -42,  -42,  -42,  -42,  -42,  -42,  -42,  -42
+      -42,  -42,  -42,  -42,  -42,   39,   39,  -42,  -42,   39,
+
+      -42,  -42,  -42,  -42,   39,  -42,   39,  -42,   42,   42,
+       42,   42,   42,   42,   42,   42,   42,   42,  -42,   39,
+      -42,  -42,  -42,  -42,   39,   39,   39,   39,   39,   39,
+       39,   39,   39,   39,   39,   39,   39,   39,   39,   39,
+       39,   39,   39,   39,   39,   39,   39,   39,   39,   39,
+       39,  -42,   39,  -42,   39,   39,  -42,   39,   39,   39,
+       39,   39,   39,   39,   39,   39,   39,   39,   39,   39,
+       39,   39,   39,   39,   39,   39,   39,   39,   39,   39,
+       39,   39,   39,  -42,  -42,  -42,  -42,  -42
     },
 
     {
@@ -1108,20 +1108,20 @@ static yyconst flex_int16_t yy_nxt[][128] =
     },
 
     {
-        7,   45,   45,   45,   45,   45,   45,   45,   45,   45,
-       45,   45,   45,   45,   45,   45,   45,   45,   45,   45,
-       45,   45,   45,   45,   45,   45,   45,   45,   45,   45,
-       45,   45,   45,   45,   45,   45,   45,   45,   45,   45,
-       45,   45,   45,   45,   45,   45,   45,   45,   45,   45,
-
-       45,   45,   45,   45,   45,   45,   45,   45,   45,   45,
-       45,   45,   45,   45,   45,   45,   45,   45,   45,   45,
-       45,   45,   45,   45,   45,   45,   45,   45,   45,   45,
-       45,   45,   45,   45,   45,   45,   45,   45,   45,   45,
-       45,   45,   45,   45,   45,   45,   45,   45,   45,   45,
-       45,   45,   45,   45,   45,   45,   45,   45,   45,   45,
-       45,   45,   45,   45,   45,   45,   45,   45,   45,   45,
-       45,   45,   45,   46,   45,   47,   45,   45
+        7,  -45,  -45,  -45,  -45,  -45,  -45,  -45,  -45,  -45,
+      -45,  -45,  -45,  -45,  -45,  -45,  -45,  -45,  -45,  -45,
+      -45,  -45,  -45,  -45,  -45,  -45,  -45,  -45,  -45,  -45,
+      -45,  -45,  -45,  -45,  -45,  -45,  -45,  -45,  -45,  -45,
+      -45,  -45,  -45,  -45,  -45,  -45,  -45,  -45,  -45,  -45,
+
+      -45,  -45,  -45,  -45,  -45,  -45,  -45,  -45,  -45,  -45,
+      -45,  -45,  -45,  -45,  -45,  -45,  -45,  -45,  -45,  -45,
+      -45,  -45,  -45,  -45,  -45,  -45,  -45,  -45,  -45,  -45,
+      -45,  -45,  -45,  -45,  -45,  -45,  -45,  -45,  -45,  -45,
+      -45,  -45,  -45,  -45,  -45,  -45,  -45,  -45,  -45,  -45,
+      -45,  -45,  -45,  -45,  -45,  -45,  -45,  -45,  -45,  -45,
+      -45,  -45,  -45,  -45,  -45,  -45,  -45,  -45,  -45,  -45,
+      -45,  -45,  -45,  -45,  -45,  -45,  -45,  -45
     },
 
     {
@@ -1160,38 +1160,107 @@ static yyconst flex_int16_t yy_nxt[][128] =
     },
 
     {
-        7,   48,   48,   48,   48,   48,   48,   48,   48,  -48,
-      -48,   48,   48,  -48,   48,   48,   48,   48,   48,   48,
-       48,   48,   48,   48,   48,   48,   48,   48,   48,   48,
-       48,   48,  -48,  -48,   48,   48,  -48,  -48,  -48,   48,
-      -48,  -48,  -48,  -48,   48,  -48,   48,  -48,   48,   48,
-       48,   48,   48,   48,   48,   48,   48,   48,  -48,   48,
-
-      -48,  -48,  -48,  -48,   48,   48,   48,   48,   48,   48,
-       48,   48,   48,   48,   48,   48,   48,   48,   48,   48,
-       48,   48,   48,   48,   48,   48,   48,   48,   48,   48,
-       48,   48,   48,   48,   48,   48,   48,   48,   48,   48,
-       48,   48,   48,   48,   48,   48,   48,   48,   48,   48,
-       48,   48,   48,   48,   48,   48,   48,   48,   48,   48,
-       48,   48,   48,   48,  -48,   48,   48,   48
+        7,  -48,  -48,  -48,  -48,  -48,  -48,  -48,  -48,  -48,
+      -48,  -48,  -48,  -48,  -48,  -48,  -48,  -48,  -48,  -48,
+      -48,  -48,  -48,  -48,  -48,  -48,  -48,  -48,  -48,  -48,
+      -48,  -48,  -48,  -48,  -48,  -48,  -48,  -48,  -48,  -48,
+      -48,  -48,  -48,  -48,  -48,  -48,  -48,  -48,  -48,  -48,
+      -48,  -48,  -48,  -48,  -48,  -48,  -48,  -48,  -48,  -48,
+
+      -48,  -48,  -48,  -48,  -48,  -48,  -48,  -48,  -48,  -48,
+      -48,  -48,  -48,  -48,  -48,  -48,  -48,  -48,  -48,  -48,
+      -48,  -48,  -48,  -48,  -48,  -48,  -48,  -48,  -48,  -48,
+      -48,  -48,  -48,  -48,  -48,  -48,  -48,  -48,  -48,  -48,
+      -48,  -48,  -48,  -48,  -48,  -48,  -48,  -48,  -48,  -48,
+      -48,  -48,  -48,  -48,  -48,  -48,  -48,  -48,  -48,  -48,
+      -48,  -48,  -48,  -48,  -48,  -48,  -48,  -48
     },
 
     {
-        7,  -49,  -49,  -49,  -49,  -49,  -49,  -49,  -49,  -49,
-      -49,  -49,  -49,  -49,  -49,  -49,  -49,  -49,  -49,  -49,
-      -49,  -49,  -49,  -49,  -49,  -49,  -49,  -49,  -49,  -49,
-
-      -49,  -49,  -49,  -49,  -49,  -49,  -49,  -49,  -49,  -49,
-      -49,  -49,  -49,  -49,  -49,  -49,  -49,  -49,  -49,  -49,
-      -49,  -49,  -49,  -49,  -49,  -49,  -49,  -49,  -49,  -49,
-      -49,  -49,  -49,  -49,  -49,  -49,  -49,  -49,  -49,  -49,
-      -49,  -49,  -49,  -49,  -49,  -49,  -49,  -49,  -49,  -49,
-      -49,  -49,  -49,  -49,  -49,  -49,  -49,  -49,  -49,  -49,
-      -49,  -49,  -49,  -49,  -49,  -49,  -49,  -49,  -49,  -49,
-      -49,  -49,  -49,  -49,  -49,  -49,  -49,  -49,  -49,  -49,
-      -49,  -49,  -49,  -49,  -49,  -49,  -49,  -49,  -49,  -49,
-      -49,  -49,  -49,  -49,  -49,  -49,  -49,  -49
+        7,   49,   49,   49,   49,   49,   49,   49,   49,   49,
+       49,   49,   49,   49,   49,   49,   49,   49,   49,   49,
+       49,   49,   49,   49,   49,   49,   49,   49,   49,   49,
+
+       49,   49,   49,   49,   49,   49,   49,   49,   49,   49,
+       49,   49,   49,   49,   49,   49,   49,   49,   49,   49,
+       49,   49,   49,   49,   49,   49,   49,   49,   49,   49,
+       49,   49,   49,   49,   49,   49,   49,   49,   49,   49,
+       49,   49,   49,   49,   49,   49,   49,   49,   49,   49,
+       49,   49,   49,   49,   49,   49,   49,   49,   49,   49,
+       49,   49,   49,   49,   49,   49,   49,   49,   49,   49,
+       49,   49,   49,   49,   49,   49,   49,   49,   49,   49,
+       49,   49,   49,   49,   49,   49,   49,   49,   49,   49,
+       49,   49,   49,   50,   49,   51,   49,   49
+
+    },
 
+    {
+        7,  -50,  -50,  -50,  -50,  -50,  -50,  -50,  -50,  -50,
+      -50,  -50,  -50,  -50,  -50,  -50,  -50,  -50,  -50,  -50,
+      -50,  -50,  -50,  -50,  -50,  -50,  -50,  -50,  -50,  -50,
+      -50,  -50,  -50,  -50,  -50,  -50,  -50,  -50,  -50,  -50,
+      -50,  -50,  -50,  -50,  -50,  -50,  -50,  -50,  -50,  -50,
+      -50,  -50,  -50,  -50,  -50,  -50,  -50,  -50,  -50,  -50,
+      -50,  -50,  -50,  -50,  -50,  -50,  -50,  -50,  -50,  -50,
+      -50,  -50,  -50,  -50,  -50,  -50,  -50,  -50,  -50,  -50,
+      -50,  -50,  -50,  -50,  -50,  -50,  -50,  -50,  -50,  -50,
+      -50,  -50,  -50,  -50,  -50,  -50,  -50,  -50,  -50,  -50,
+
+      -50,  -50,  -50,  -50,  -50,  -50,  -50,  -50,  -50,  -50,
+      -50,  -50,  -50,  -50,  -50,  -50,  -50,  -50,  -50,  -50,
+      -50,  -50,  -50,  -50,  -50,  -50,  -50,  -50
+    },
+
+    {
+        7,  -51,  -51,  -51,  -51,  -51,  -51,  -51,  -51,  -51,
+      -51,  -51,  -51,  -51,  -51,  -51,  -51,  -51,  -51,  -51,
+      -51,  -51,  -51,  -51,  -51,  -51,  -51,  -51,  -51,  -51,
+      -51,  -51,  -51,  -51,  -51,  -51,  -51,  -51,  -51,  -51,
+      -51,  -51,  -51,  -51,  -51,  -51,  -51,  -51,  -51,  -51,
+      -51,  -51,  -51,  -51,  -51,  -51,  -51,  -51,  -51,  -51,
+      -51,  -51,  -51,  -51,  -51,  -51,  -51,  -51,  -51,  -51,
+
+      -51,  -51,  -51,  -51,  -51,  -51,  -51,  -51,  -51,  -51,
+      -51,  -51,  -51,  -51,  -51,  -51,  -51,  -51,  -51,  -51,
+      -51,  -51,  -51,  -51,  -51,  -51,  -51,  -51,  -51,  -51,
+      -51,  -51,  -51,  -51,  -51,  -51,  -51,  -51,  -51,  -51,
+      -51,  -51,  -51,  -51,  -51,  -51,  -51,  -51,  -51,  -51,
+      -51,  -51,  -51,  -51,  -51,  -51,  -51,  -51
+    },
+
+    {
+        7,   52,   52,   52,   52,   52,   52,   52,   52,  -52,
+      -52,   52,   52,  -52,   52,   52,   52,   52,   52,   52,
+       52,   52,   52,   52,   52,   52,   52,   52,   52,   52,
+       52,   52,  -52,  -52,   52,   52,  -52,  -52,  -52,   52,
+
+      -52,  -52,  -52,  -52,   52,  -52,   52,  -52,   52,   52,
+       52,   52,   52,   52,   52,   52,   52,   52,  -52,   52,
+      -52,  -52,  -52,  -52,   52,   52,   52,   52,   52,   52,
+       52,   52,   52,   52,   52,   52,   52,   52,   52,   52,
+       52,   52,   52,   52,   52,   52,   52,   52,   52,   52,
+       52,   52,   52,   52,   52,   52,   52,   52,   52,   52,
+       52,   52,   52,   52,   52,   52,   52,   52,   52,   52,
+       52,   52,   52,   52,   52,   52,   52,   52,   52,   52,
+       52,   52,   52,   52,  -52,   52,   52,   52
+    },
+
+    {
+        7,  -53,  -53,  -53,  -53,  -53,  -53,  -53,  -53,  -53,
+
+      -53,  -53,  -53,  -53,  -53,  -53,  -53,  -53,  -53,  -53,
+      -53,  -53,  -53,  -53,  -53,  -53,  -53,  -53,  -53,  -53,
+      -53,  -53,  -53,  -53,  -53,  -53,  -53,  -53,  -53,  -53,
+      -53,  -53,  -53,  -53,  -53,  -53,  -53,  -53,  -53,  -53,
+      -53,  -53,  -53,  -53,  -53,  -53,  -53,  -53,  -53,  -53,
+      -53,  -53,  -53,  -53,  -53,  -53,  -53,  -53,  -53,  -53,
+      -53,  -53,  -53,  -53,  -53,  -53,  -53,  -53,  -53,  -53,
+      -53,  -53,  -53,  -53,  -53,  -53,  -53,  -53,  -53,  -53,
+      -53,  -53,  -53,  -53,  -53,  -53,  -53,  -53,  -53,  -53,
+      -53,  -53,  -53,  -53,  -53,  -53,  -53,  -53,  -53,  -53,
+
+      -53,  -53,  -53,  -53,  -53,  -53,  -53,  -53,  -53,  -53,
+      -53,  -53,  -53,  -53,  -53,  -53,  -53,  -53
     },
 
     } ;
@@ -1212,8 +1281,8 @@ static void yy_fatal_error (yyconst char msg[] ,yyscan_t yyscanner );
 	*yy_cp = '\0'; \
 	yyg->yy_c_buf_p = yy_cp;
 
-#define YY_NUM_RULES 30
-#define YY_END_OF_BUFFER 31
+#define YY_NUM_RULES 35
+#define YY_END_OF_BUFFER 36
 /* This struct is not used in this scanner,
    but its presence is necessary. */
 struct yy_trans_info
@@ -1221,22 +1290,24 @@ struct yy_trans_info
 	flex_int32_t yy_verify;
 	flex_int32_t yy_nxt;
 	};
-static yyconst flex_int16_t yy_accept[50] =
+static yyconst flex_int16_t yy_accept[54] =
     {   0,
-        0,    0,    0,    0,   27,   27,   31,   30,   20,   22,
-       24,   30,   24,   24,   13,    2,   17,   18,   11,    9,
-       10,   12,   23,   15,    5,    3,    4,   14,    1,   30,
-       26,   25,   27,   28,   28,   24,    8,    0,   21,   19,
-       23,   16,    7,    6,    0,   26,   25,   27,   29
+        0,    0,    0,    0,   32,   32,   36,   35,   25,   27,
+       19,   35,   29,   29,   17,    2,   22,   23,   15,   13,
+       14,   16,   28,   20,    9,    3,    8,   18,    1,   35,
+       31,   30,   32,   33,   33,   12,    0,   26,   29,   24,
+        5,   28,   21,   11,    6,    7,   10,    4,    0,   31,
+       30,   32,   34
     } ;
 
-static yyconst yy_state_type yy_NUL_trans[50] =
+static yyconst yy_state_type yy_NUL_trans[54] =
     {   0,
         8,    8,   30,   30,   33,   33,    0,    0,    0,    0,
-        0,   38,    0,    0,    0,    0,    0,    0,    0,    0,
-        0,    0,    0,    0,    0,    0,    0,    0,    0,   45,
-        0,    0,   48,    0,    0,    0,    0,   38,    0,    0,
-        0,    0,    0,    0,   45,    0,    0,   48,    0
+        0,   37,    0,    0,    0,    0,    0,    0,    0,    0,
+        0,    0,    0,    0,    0,    0,    0,    0,    0,   49,
+        0,    0,   52,    0,    0,    0,   37,    0,    0,    0,
+        0,    0,    0,    0,    0,    0,    0,    0,   49,    0,
+        0,   52,    0
     } ;
 
 /* The intent behind this definition is that it'll catch
@@ -1248,9 +1319,27 @@ static yyconst yy_state_type yy_NUL_trans[50] =
 #define YY_RESTORE_YY_MORE_OFFSET
 #line 1 "ast_expr2.fl"
 #line 2 "ast_expr2.fl"
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 1999 - 2006, Digium, Inc.
+ *
+ * Mark Spencer <markster@digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
 /*! \file
  *
- * \brief Dialplan Expression Parser
+ * \brief Dialplan Expression Lexical Scanner
  */
 
 #include <sys/types.h>
@@ -1304,8 +1393,9 @@ struct parse_io
 void ast_yyset_column(int column_no, yyscan_t yyscanner);
 int ast_yyget_column(yyscan_t yyscanner);
 static int curlycount = 0;
+static char *expr2_token_subst(char *mess);
 
-#line 1304 "ast_expr2f.c"
+#line 1394 "ast_expr2f.c"
 
 #define INITIAL 0
 #define var 1
@@ -1522,10 +1612,10 @@ YY_DECL
 	register int yy_act;
     struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
 
-#line 64 "ast_expr2.fl"
+#line 83 "ast_expr2.fl"
 
 
-#line 1524 "ast_expr2f.c"
+#line 1614 "ast_expr2f.c"
 
     yylval = yylval_param;
 
@@ -1608,167 +1698,192 @@ do_action:	/* This label is used only to access EOF actions. */
 
 case 1:
 YY_RULE_SETUP
-#line 66 "ast_expr2.fl"
+#line 85 "ast_expr2.fl"
 { SET_COLUMNS; SET_STRING; return TOK_OR;}
 	YY_BREAK
 case 2:
 YY_RULE_SETUP
-#line 67 "ast_expr2.fl"
+#line 86 "ast_expr2.fl"
 { SET_COLUMNS; SET_STRING; return TOK_AND;}
 	YY_BREAK
 case 3:
 YY_RULE_SETUP
-#line 68 "ast_expr2.fl"
+#line 87 "ast_expr2.fl"
 { SET_COLUMNS; SET_STRING; return TOK_EQ;}
 	YY_BREAK
 case 4:
 YY_RULE_SETUP
-#line 69 "ast_expr2.fl"
-{ SET_COLUMNS; SET_STRING; return TOK_GT;}
+#line 88 "ast_expr2.fl"
+{ SET_COLUMNS; SET_STRING; return TOK_OR;}
 	YY_BREAK
 case 5:
 YY_RULE_SETUP
-#line 70 "ast_expr2.fl"
-{ SET_COLUMNS; SET_STRING; return TOK_LT;}
+#line 89 "ast_expr2.fl"
+{ SET_COLUMNS; SET_STRING; return TOK_AND;}
 	YY_BREAK
 case 6:
 YY_RULE_SETUP
-#line 71 "ast_expr2.fl"
-{ SET_COLUMNS; SET_STRING; return TOK_GE;}
+#line 90 "ast_expr2.fl"
+{ SET_COLUMNS; SET_STRING; return TOK_EQ;}
 	YY_BREAK
 case 7:
 YY_RULE_SETUP
-#line 72 "ast_expr2.fl"
-{ SET_COLUMNS; SET_STRING; return TOK_LE;}
+#line 91 "ast_expr2.fl"
+{ SET_COLUMNS; SET_STRING; return TOK_EQTILDE;}
 	YY_BREAK
 case 8:
 YY_RULE_SETUP
-#line 73 "ast_expr2.fl"
-{ SET_COLUMNS; SET_STRING; return TOK_NE;}
+#line 92 "ast_expr2.fl"
+{ SET_COLUMNS; SET_STRING; return TOK_GT;}
 	YY_BREAK
 case 9:
 YY_RULE_SETUP
-#line 74 "ast_expr2.fl"
-{ SET_COLUMNS; SET_STRING; return TOK_PLUS;}
+#line 93 "ast_expr2.fl"
+{ SET_COLUMNS; SET_STRING; return TOK_LT;}
 	YY_BREAK
 case 10:
 YY_RULE_SETUP
-#line 75 "ast_expr2.fl"
-{ SET_COLUMNS; SET_STRING; return TOK_MINUS;}
+#line 94 "ast_expr2.fl"
+{ SET_COLUMNS; SET_STRING; return TOK_GE;}
 	YY_BREAK
 case 11:
 YY_RULE_SETUP
-#line 76 "ast_expr2.fl"
-{ SET_COLUMNS; SET_STRING; return TOK_MULT;}
+#line 95 "ast_expr2.fl"
+{ SET_COLUMNS; SET_STRING; return TOK_LE;}
 	YY_BREAK
 case 12:
 YY_RULE_SETUP
-#line 77 "ast_expr2.fl"
-{ SET_COLUMNS; SET_STRING; return TOK_DIV;}
+#line 96 "ast_expr2.fl"
+{ SET_COLUMNS; SET_STRING; return TOK_NE;}
 	YY_BREAK
 case 13:
 YY_RULE_SETUP
-#line 78 "ast_expr2.fl"
-{ SET_COLUMNS; SET_STRING; return TOK_MOD;}
+#line 97 "ast_expr2.fl"
+{ SET_COLUMNS; SET_STRING; return TOK_PLUS;}
 	YY_BREAK
 case 14:
 YY_RULE_SETUP
-#line 79 "ast_expr2.fl"
-{ SET_COLUMNS; SET_STRING; return TOK_COND;}
+#line 98 "ast_expr2.fl"
+{ SET_COLUMNS; SET_STRING; return TOK_MINUS;}
 	YY_BREAK
 case 15:
 YY_RULE_SETUP
-#line 80 "ast_expr2.fl"
-{ SET_COLUMNS; SET_STRING; return TOK_COLON;}
+#line 99 "ast_expr2.fl"
+{ SET_COLUMNS; SET_STRING; return TOK_MULT;}
 	YY_BREAK
 case 16:
 YY_RULE_SETUP
-#line 81 "ast_expr2.fl"
-{ SET_COLUMNS; SET_STRING; return TOK_COLONCOLON;}
+#line 100 "ast_expr2.fl"
+{ SET_COLUMNS; SET_STRING; return TOK_DIV;}
 	YY_BREAK
 case 17:
 YY_RULE_SETUP
-#line 82 "ast_expr2.fl"
-{ SET_COLUMNS; SET_STRING; return TOK_LP;}
+#line 101 "ast_expr2.fl"
+{ SET_COLUMNS; SET_STRING; return TOK_MOD;}
 	YY_BREAK
 case 18:
 YY_RULE_SETUP
-#line 83 "ast_expr2.fl"
-{ SET_COLUMNS; SET_STRING; return TOK_RP;}
+#line 102 "ast_expr2.fl"
+{ SET_COLUMNS; SET_STRING; return TOK_COND;}
 	YY_BREAK
 case 19:
 YY_RULE_SETUP
-#line 84 "ast_expr2.fl"
+#line 103 "ast_expr2.fl"
+{ SET_COLUMNS; SET_STRING; return TOK_COMPL;}
+	YY_BREAK
+case 20:
+YY_RULE_SETUP
+#line 104 "ast_expr2.fl"
+{ SET_COLUMNS; SET_STRING; return TOK_COLON;}
+	YY_BREAK
+case 21:
+YY_RULE_SETUP
+#line 105 "ast_expr2.fl"
+{ SET_COLUMNS; SET_STRING; return TOK_COLONCOLON;}
+	YY_BREAK
+case 22:
+YY_RULE_SETUP
+#line 106 "ast_expr2.fl"
+{ SET_COLUMNS; SET_STRING; return TOK_LP;}
+	YY_BREAK
+case 23:
+YY_RULE_SETUP
+#line 107 "ast_expr2.fl"
+{ SET_COLUMNS; SET_STRING; return TOK_RP;}
+	YY_BREAK
+case 24:
+YY_RULE_SETUP
+#line 108 "ast_expr2.fl"
 {/* gather the contents of ${} expressions, with trailing stuff, into a single TOKEN. They are much more complex now than they used to be */
                        curlycount = 0; BEGIN(var); yymore();}
 	YY_BREAK
-case 20:
+case 25:
 YY_RULE_SETUP
-#line 87 "ast_expr2.fl"
+#line 111 "ast_expr2.fl"
 {}
 	YY_BREAK
-case 21:
-/* rule 21 can match eol */
+case 26:
+/* rule 26 can match eol */
 YY_RULE_SETUP
-#line 88 "ast_expr2.fl"
+#line 112 "ast_expr2.fl"
 {SET_COLUMNS; SET_STRING; return TOKEN;}
 	YY_BREAK
-case 22:
-/* rule 22 can match eol */
+case 27:
+/* rule 27 can match eol */
 YY_RULE_SETUP
-#line 90 "ast_expr2.fl"
+#line 114 "ast_expr2.fl"
 {/* what to do with eol */}
 	YY_BREAK
-case 23:
+case 28:
 YY_RULE_SETUP
-#line 91 "ast_expr2.fl"
+#line 115 "ast_expr2.fl"
 {   SET_COLUMNS;  /* the original behavior of the expression parser was to bring in numbers as a numeric string */
 				SET_NUMERIC_STRING;
 				return TOKEN;}
 	YY_BREAK
-case 24:
+case 29:
 YY_RULE_SETUP
-#line 94 "ast_expr2.fl"
+#line 119 "ast_expr2.fl"
 {SET_COLUMNS; SET_STRING; return TOKEN;}
 	YY_BREAK
-case 25:
-/* rule 25 can match eol */
+case 30:
+/* rule 30 can match eol */
 YY_RULE_SETUP
-#line 96 "ast_expr2.fl"
+#line 121 "ast_expr2.fl"
 {curlycount--; if(curlycount < 0){ BEGIN(trail);  yymore();} else {  yymore();}}
 	YY_BREAK
-case 26:
-/* rule 26 can match eol */
+case 31:
+/* rule 31 can match eol */
 YY_RULE_SETUP
-#line 97 "ast_expr2.fl"
+#line 122 "ast_expr2.fl"
 {curlycount++; yymore();  }
 	YY_BREAK
-case 27:
+case 32:
 YY_RULE_SETUP
-#line 98 "ast_expr2.fl"
+#line 123 "ast_expr2.fl"
 {BEGIN(0); SET_COLUMNS; SET_STRING; return TOKEN;}
 	YY_BREAK
-case 28:
-/* rule 28 can match eol */
+case 33:
+/* rule 33 can match eol */
 YY_RULE_SETUP
-#line 99 "ast_expr2.fl"
+#line 124 "ast_expr2.fl"
 {char c = yytext[yyleng-1]; BEGIN(0); unput(c); SET_COLUMNS; SET_STRING; return TOKEN;}
 	YY_BREAK
-case 29:
+case 34:
 YY_RULE_SETUP
-#line 100 "ast_expr2.fl"
+#line 125 "ast_expr2.fl"
 {curlycount = 0; BEGIN(var); yymore();  }
 	YY_BREAK
 case YY_STATE_EOF(trail):
-#line 101 "ast_expr2.fl"
-{BEGIN(0); SET_COLUMNS; SET_STRING; return TOKEN; /* actually, if an expr is only a variable ref, this could happen a LOT */}
+#line 126 "ast_expr2.fl"
+{BEGIN(0); SET_COLUMNS; SET_STRING; return TOKEN; /*actually, if an expr is only a variable ref, this could happen a LOT */}
 	YY_BREAK
-case 30:
+case 35:
 YY_RULE_SETUP
-#line 103 "ast_expr2.fl"
+#line 128 "ast_expr2.fl"
 ECHO;
 	YY_BREAK
-#line 1767 "ast_expr2f.c"
+#line 1882 "ast_expr2f.c"
 case YY_STATE_EOF(INITIAL):
 case YY_STATE_EOF(var):
 	yyterminate();
@@ -2901,7 +3016,7 @@ void ast_yyfree (void * ptr , yyscan_t yyscanner)
 #undef YY_DECL_IS_OURS
 #undef YY_DECL
 #endif
-#line 103 "ast_expr2.fl"
+#line 128 "ast_expr2.fl"
 
 
 
@@ -2955,16 +3070,129 @@ int ast_expr(char *expr, char *buf, int length)
 	return return_value;
 }
 
+
+char extra_error_message[4095];
+int extra_error_message_supplied = 0;
+void  ast_expr_register_extra_error_info(char *message);
+void  ast_expr_clear_extra_error_info(void);
+
+void  ast_expr_register_extra_error_info(char *message)
+{
+       extra_error_message_supplied=1;
+       strcpy(extra_error_message, message);
+}
+
+void  ast_expr_clear_extra_error_info(void)
+{
+       extra_error_message_supplied=0;
+       extra_error_message[0] = 0;
+}
+
+static char *expr2_token_equivs1[] = 
+{
+	"TOKEN",
+	"TOK_COND",
+	"TOK_COLONCOLON",
+	"TOK_OR",
+	"TOK_AND",
+	"TOK_EQ",
+	"TOK_GT",
+	"TOK_LT",
+	"TOK_GE",
+	"TOK_LE",
+	"TOK_NE",
+	"TOK_PLUS",
+	"TOK_MINUS",
+	"TOK_MULT",
+	"TOK_DIV",
+	"TOK_MOD",
+	"TOK_COMPL",
+	"TOK_COLON",
+	"TOK_EQTILDE",
+	"TOK_RP",
+	"TOK_LP"
+};
+
+static char *expr2_token_equivs2[] = 
+{
+	"<token>",
+	"?",
+	"::",
+	"|",
+	"&",
+	"=",
+	">",
+	"<",
+	">=",
+	"<=",
+	"!=",
+	"+",
+	"-",
+	"*",
+	"/",
+	"%",
+	"!",
+	":",
+	"=~",
+	")",
+	"("
+};
+
+
+static char *expr2_token_subst(char *mess)
+{
+	/* calc a length, malloc, fill, and return; yyerror had better free it! */
+	int len=0,i;
+	char *p;
+	char *res, *s,*t;
+	int expr2_token_equivs_entries = sizeof(expr2_token_equivs1)/sizeof(char*);
+
+	for (p=mess; *p; p++) {
+		for (i=0; i<expr2_token_equivs_entries; i++) {
+			if ( strncmp(p,expr2_token_equivs1[i],strlen(expr2_token_equivs1[i])) == 0 )
+			{
+				len+=strlen(expr2_token_equivs2[i])+2;
+				p += strlen(expr2_token_equivs1[i])-1;
+				break;
+			}
+		}
+		len++;
+	}
+	res = (char*)malloc(len+1);
+	res[0] = 0;
+	s = res;
+	for (p=mess; *p;) {
+		int found = 0;
+		for (i=0; i<expr2_token_equivs_entries; i++) {
+			if ( strncmp(p,expr2_token_equivs1[i],strlen(expr2_token_equivs1[i])) == 0 ) {
+				*s++ = '\'';
+				for (t=expr2_token_equivs2[i]; *t;) {
+					*s++ = *t++;
+				}
+				*s++ = '\'';
+				p += strlen(expr2_token_equivs1[i]);
+				found = 1;
+				break;
+			}
+		}
+		if( !found )
+			*s++ = *p++;
+	}
+	*s++ = 0;
+	return res;
+}
+
 int ast_yyerror (const char *s,  yyltype *loc, struct parse_io *parseio )
 {	
 	struct yyguts_t * yyg = (struct yyguts_t*)(parseio->scanner);
 	char spacebuf[8000]; /* best safe than sorry */
 	char spacebuf2[8000]; /* best safe than sorry */
 	int i=0;
+	char *s2 = expr2_token_subst((char *)s);
 	spacebuf[0] = 0;
 	
 	for(i=0;i< (int)(yytext - YY_CURRENT_BUFFER_LVALUE->yy_ch_buf);i++) spacebuf2[i] = ' ';  /* uh... assuming yyg is defined, then I can use the yycolumn macro,
-													which is the same thing as... get this:
+																								which is the same thing as... get this:
 													yyg->yy_buffer_stack[yyg->yy_buffer_stack_top]->yy_bs_column
 													I was tempted to just use yy_buf_pos in the STATE, but..., well:
 														a. the yy_buf_pos is the current position in the buffer, which
@@ -2979,15 +3207,16 @@ int ast_yyerror (const char *s,  yyltype *loc, struct parse_io *parseio )
 
 #ifdef STANDALONE3
 	/* easier to read in the standalone version */
-	printf("ast_yyerror(): syntax error: %s; Input:\n%s\n%s\n",  
-			s, parseio->string,spacebuf2);
+	printf("ast_yyerror(): %s syntax error: %s; Input:\n%s\n%s\n",  
+			(extra_error_message_supplied?extra_error_message:""), s2, parseio->string,spacebuf2);
 #else
-	ast_log(LOG_WARNING,"ast_yyerror(): syntax error: %s; Input:\n%s\n%s\n",  
-			s, parseio->string,spacebuf2);
+	ast_log(LOG_WARNING,"ast_yyerror(): %s syntax error: %s; Input:\n%s\n%s\n",  
+			(extra_error_message_supplied?extra_error_message:""), s2, parseio->string,spacebuf2);
 #endif
 #ifndef STANDALONE
 	ast_log(LOG_WARNING,"If you have questions, please refer to doc/channelvariables.txt in the asterisk source.\n");
 #endif
+	free(s2);
 	return(0);
 }
 
diff --git a/configs/extensions.ael.sample b/configs/extensions.ael.sample
index 87fe580394..39e0e191d5 100644
--- a/configs/extensions.ael.sample
+++ b/configs/extensions.ael.sample
@@ -1,6 +1,307 @@
 //
 // Example AEL config file
 //
+//
+// Static extension configuration file, used by
+// the pbx_config module. This is where you configure all your 
+// inbound and outbound calls in Asterisk. 
+// 
+// This configuration file is reloaded 
+// - With the "extensions reload" command in the CLI
+// - With the "reload" command (that reloads everything) in the CLI
+
+// The "Globals" category contains global variables that can be referenced
+// in the dialplan with ${VARIABLE} or ${ENV(VARIABLE)} for Environmental
+// variables,
+// ${${VARIABLE}} or ${text${VARIABLE}} or any hybrid
+//
+
+globals {
+	CONSOLE="Console/dsp"; 		// Console interface for demo
+	//CONSOLE=Zap/1
+	//CONSOLE=Phone/phone0
+	IAXINFO=guest;				// IAXtel username/password
+	//IAXINFO="myuser:mypass";
+	TRUNK="Zap/g2";					// Trunk interface
+	//
+	// Note the 'g2' in the TRUNK variable above. It specifies which group (defined
+	// in zapata.conf) to dial, i.e. group 2, and how to choose a channel to use in
+	// the specified group. The four possible options are:
+	//
+	// g: select the lowest-numbered non-busy Zap channel
+	//    (aka. ascending sequential hunt group).
+	// G: select the highest-numbered non-busy Zap channel
+	//    (aka. descending sequential hunt group).
+	// r: use a round-robin search, starting at the next highest channel than last
+	//    time (aka. ascending rotary hunt group).
+	// R: use a round-robin search, starting at the next lowest channel than last
+	//    time (aka. descending rotary hunt group).
+	//
+	TRUNKMSD=1;					// MSD digits to strip (usually 1 or 0)
+	//TRUNK=IAX2/user:pass@provider
+};
+
+//
+// Any category other than "General" and "Globals" represent 
+// extension contexts, which are collections of extensions.  
+//
+// Extension names may be numbers, letters, or combinations
+// thereof. If an extension name is prefixed by a '_'
+// character, it is interpreted as a pattern rather than a
+// literal.  In patterns, some characters have special meanings:
+//
+//   X - any digit from 0-9
+//   Z - any digit from 1-9
+//   N - any digit from 2-9
+//   [1235-9] - any digit in the brackets (in this example, 1,2,3,5,6,7,8,9)
+//   . - wildcard, matches anything remaining (e.g. _9011. matches 
+//	anything starting with 9011 excluding 9011 itself)
+//   ! - wildcard, causes the matching process to complete as soon as
+//       it can unambiguously determine that no other matches are possible
+//
+// For example the extension _NXXXXXX would match normal 7 digit dialings, 
+// while _1NXXNXXXXXX would represent an area code plus phone number
+// preceeded by a one.
+//
+// Each step of an extension is ordered by priority, which must
+// always start with 1 to be considered a valid extension.  The priority
+// "next" or "n" means the previous priority plus one, regardless of whether
+// the previous priority was associated with the current extension or not.
+// The priority "same" or "s" means the same as the previously specified
+// priority, again regardless of whether the previous entry was for the
+// same extension.  Priorities may be immediately followed by a plus sign
+// and another integer to add that amount (most useful with 's' or 'n').  
+// Priorities may then also have an alias, or label, in 
+// parenthesis after their name which can be used in goto situations
+//
+// Contexts contain several lines, one for each step of each
+// extension, which can take one of two forms as listed below,
+// with the first form being preferred.  One may include another
+// context in the current one as well, optionally with a
+// date and time.  Included contexts are included in the order
+// they are listed.
+//
+//context name {
+//	exten-name => {
+//		application(arg1,arg2,...);
+//
+// 	Timing list for includes is 
+//
+//   <time range>|<days of week>|<days of month>|<months>
+//
+//	includes { 
+//		daytime|9:00-17:00|mon-fri|*|*;
+//  };
+//
+// 	ignorepat can be used to instruct drivers to not cancel dialtone upon
+// 	receipt of a particular pattern.  The most commonly used example is
+// 	of course '9' like this:
+//
+//	ignorepat => 9;
+//
+// 	so that dialtone remains even after dialing a 9.
+//};
+
+
+//
+// Sample entries for extensions.conf
+//
+//
+context dundi-e164-canonical {
+	//
+	// List canonical entries here
+	//
+	// 12564286000 => &std-exten(6000,IAX2/foo);
+	// _125642860XX => Dial(IAX2/otherbox/${EXTEN:7});
+};
+
+context dundi-e164-customers {
+	//
+	// If you are an ITSP or Reseller, list your customers here.
+	//
+	//_12564286000 => Dial(SIP/customer1);
+	//_12564286001 => Dial(IAX2/customer2);
+};
+
+context dundi-e164-via-pstn {
+	//
+	// If you are freely delivering calls to the PSTN, list them here
+	//
+	//_1256428XXXX => Dial(Zap/g2/${EXTEN:7}); // Expose all of 256-428 
+	//_1256325XXXX => Dial(Zap/g2/${EXTEN:7}); // Ditto for 256-325
+};
+
+context dundi-e164-local {
+	//
+	// Context to put your dundi IAX2 or SIP user in for
+	// full access
+	//
+	includes {
+	 dundi-e164-canonical;
+	 dundi-e164-customers;
+	 dundi-e164-via-pstn;
+	};
+};
+
+context dundi-e164-switch {
+	//
+	// Just a wrapper for the switch
+	//
+	
+	switches { 
+		DUNDi/e164;
+	};
+};
+
+context dundi-e164-lookup {
+	//
+	// Locally to lookup, try looking for a local E.164 solution
+	// then try DUNDi if we don't have one.
+	//
+	includes {
+		dundi-e164-local;
+		dundi-e164-switch;
+	};
+	//
+};
+
+//
+// DUNDi can also be implemented as a Macro instead of using 
+// the Local channel driver. 
+//
+macro dundi-e164(exten) {
+//
+// ARG1 is the extension to Dial
+//
+	goto ${exten}|1;
+};
+
+//
+// Here are the entries you need to participate in the IAXTEL
+// call routing system.  Most IAXTEL numbers begin with 1-700, but
+// there are exceptions.  For more information, and to sign
+// up, please go to www.gnophone.com or www.iaxtel.com
+//
+context iaxtel700 {
+	_91700XXXXXXX => Dial(IAX2/${IAXINFO}@iaxtel.com/${EXTEN:1}@iaxtel);
+};
+
+//
+// The SWITCH statement permits a server to share the dialplain with
+// another server. Use with care: Reciprocal switch statements are not
+// allowed (e.g. both A -> B and B -> A), and the switched server needs
+// to be on-line or else dialing can be severly delayed.
+//
+context iaxprovider {
+	switches {
+	// IAX2/user:[key]@myserver/mycontext;
+	};
+};
+
+context trunkint {
+	//
+	// International long distance through trunk
+	//
+	includes {
+		dundi-e164-lookup;
+	};
+	_9011. => {
+		&dundi-e164(${EXTEN:4});
+		Dial(${TRUNK}/${EXTEN:${TRUNKMSD}});
+	};
+};
+
+context trunkld {
+	//
+	// Long distance context accessed through trunk
+	//
+	includes {
+		dundi-e164-lookup;
+	};
+	_91NXXNXXXXXX => {
+		&dundi-e164(${EXTEN:1});
+		Dial(${TRUNK}/${EXTEN:${TRUNKMSD}});
+	};
+};
+
+context trunklocal {
+	//
+	// Local seven-digit dialing accessed through trunk interface
+	//
+	_9NXXXXXX => {
+		Dial(${TRUNK}/${EXTEN:${TRUNKMSD}});
+	};
+};
+
+context trunktollfree {
+	//
+	// Long distance context accessed through trunk interface
+	//
+	
+	_91800NXXXXXX => Dial(${TRUNK}/${EXTEN:${TRUNKMSD}});
+	_91888NXXXXXX => Dial(${TRUNK}/${EXTEN:${TRUNKMSD}});
+	_91877NXXXXXX => Dial(${TRUNK}/${EXTEN:${TRUNKMSD}});
+	_91866NXXXXXX => Dial(${TRUNK}/${EXTEN:${TRUNKMSD}});
+};
+
+context international {
+	//
+	// Master context for international long distance
+	//
+	ignorepat => 9;
+	includes {
+		longdistance;
+		trunkint;
+	};
+};
+
+context longdistance {
+	//
+	// Master context for long distance
+	//
+	ignorepat => 9;
+	includes {
+		local;
+		trunkld;
+	};
+};
+
+context local {
+	//
+	// Master context for local, toll-free, and iaxtel calls only
+	//
+	ignorepat => 9;
+	includes {
+		default;
+		parkedcalls;
+		trunklocal;
+		iaxtel700;
+		trunktollfree;
+		iaxprovider;
+	};
+};
+
+//
+// You can use an alternative switch type as well, to resolve
+// extensions that are not known here, for example with remote 
+// IAX switching you transparently get access to the remote
+// Asterisk PBX
+// 
+// switch => IAX2/user:password@bigserver/local
+//
+// An "lswitch" is like a switch but is literal, in that
+// variable substitution is not performed at load time
+// but is passed to the switch directly (presumably to
+// be substituted in the switch routine itself)
+//
+// lswitch => Loopback/12${EXTEN}@othercontext
+//
+// An "eswitch" is like a switch but the evaluation of
+// variable substitution is performed at runtime before
+// being passed to the switch routine.
+//
+// eswitch => IAX2/context@${CURSERVER}
+
 
 macro std-exten-ael( ext , dev ) {
         Dial(${dev}/${ext},20);
@@ -21,8 +322,8 @@ context ael-demo {
 	s => {
 		Wait(1);
 		Answer();
-		TIMEOUT(digit)=5;
-		TIMEOUT(response)=10;
+		Set(TIMEOUT(digit)=5);
+		Set(TIMEOUT(response)=10);
 restart:
 		Background(demo-congrats);
 instructions:
@@ -36,12 +337,15 @@ instructions:
 		goto s|instructions;
 	};
 	3 => {
-		LANGUAGE()=fr;
+		Set(LANGUAGE()=fr);
 		goto s|restart;
 	};
+	1000 => {
+		goto default|s|1;
+	};
 	500 => {
 		Playback(demo-abouttotry);
-		Dial(IAX2/guest@misery.digium.com);
+		Dial(IAX2/guest@misery.digium.com/s@default);
 		Playback(demo-nogo);
 		goto s|instructions;
 	};
@@ -52,11 +356,83 @@ instructions:
 		goto s|instructions;
 	};
 	_1234 => &std-exten-ael(${EXTEN}, "IAX2");
+	8500 => {
+		VoicemailMain();
+		goto s|instructions;
+	};
 	# => {
 		Playback(demo-thanks);
 		Hangup();
 	};
-	t => jump #;
+	t => goto #|1;
 	i => Playback(invalid);
 };
 
+context default {
+
+// By default we include the demo.  In a production system, you 
+// probably don't want to have the demo there.
+
+	includes {
+		ael-demo;
+	};
+//
+// Extensions like the two below can be used for FWD, Nikotel, sipgate etc.
+// Note that you must have a [sipprovider] section in sip.conf whereas
+// the otherprovider.net example does not require such a peer definition
+//
+//_41X. => Dial(SIP/${EXTEN:2}@sipprovider,,r);
+//_42X. => Dial(SIP/user:passwd@${EXTEN:2}@otherprovider.net,30,rT);
+
+// Real extensions would go here. Generally you want real extensions to be
+// 4 or 5 digits long (although there is no such requirement) and start with a
+// single digit that is fairly large (like 6 or 7) so that you have plenty of
+// room to overlap extensions and menu options without conflict.  You can alias
+// them with names, too, and use global variables
+
+// 6245  => {
+//		hint(SIP/Grandstream1&SIP/Xlite1,Joe Schmoe); // Channel hints for presence
+// 		Dial(SIP/Grandstream1,20,rt);                 // permit transfer
+//        Dial(${HINT}/5245},20,rtT);                    // Use hint as listed
+//        switch(${DIALSTATUS}) {
+//        case BUSY:
+//                Voicemail(b6245);
+//				return;
+//        default:
+//                Voicemail(u6245);
+//				return;
+//        };
+//       };
+
+// 6361 => Dial(IAX2/JaneDoe,,rm);                // ring without time limit
+// 6389 => Dial(MGCP/aaln/1@192.168.0.14);
+// 6394 => Dial(Local/6275/n);                    // this will dial ${MARK}
+
+// 6275 => &ael-stdexten(6275,${MARK});           // assuming ${MARK} is something like Zap/2
+// mark => goto 6275|1;                          // alias mark to 6275
+// 6536 => &ael-stdexten(6236,${WIL});            // Ditto for wil
+// wil  => goto 6236|1;
+//
+// Some other handy things are an extension for checking voicemail via
+// voicemailmain
+//
+// 8500 => {
+//			VoicemailMain();
+//			Hangup();
+//	       };
+//
+// Or a conference room (you'll need to edit meetme.conf to enable this room)
+//
+// 8600 => Meetme(1234);
+//
+// Or playing an announcement to the called party, as soon it answers
+//
+// 8700 => Dial(${MARK},30,A(/path/to/my/announcemsg))
+//
+// For more information on applications, just type "show applications" at your
+// friendly Asterisk CLI prompt.
+//
+// 'show application <command>' will show details of how you
+// use that particular application in this file, the dial plan. 
+//
+};
diff --git a/doc/ael.txt b/doc/ael.txt
index e2014a4e19..54d68c658b 100644
--- a/doc/ael.txt
+++ b/doc/ael.txt
@@ -1,273 +1,1248 @@
-The Asterisk Extension Language
-===================================
+The Asterisk Extension Language - v 2
+=====================================
 
-Over time, people have been pushing to add features to extensions.conf to make
-it more like a programming language.  AEL is intended to provide an actual
-programming language that can be used to write an Asterisk dialplan.
+AEL is a specialized language intended purely for 
+describing Asterisk dial plans.
 
-Getting Started
+The current version was written by Steve Murphy, and is a rewrite of 
+the original version.
+
+AEL is considered an EXPERIMENTAL Version. (yet is being
+used in the field with success)
+
+This new version further extends AEL, and
+provides more flexible syntax, better error messages, and some missing
+functionality.
+
+AEL is really the merger of 4 different 'languages', or syntaxes:
+
+    * The first and most obvious is the AEL syntax itselft. A BNF is
+      provided near the end of this document.
+
+    * The second syntax is the Expression Syntax, which is normally
+     handled by Asterisk extension engine, as expressions enclosed in
+     $[...]. The right hand side of assignments are wrapped in $[ ... ] 
+     by AEL, and so are the if and while expressions, among others.
+
+    * The third syntax is the Variable Reference Syntax, the stuff
+      enclosed in ${..} curly braces. It's a bit more involved than just
+      putting a variable name in there. You can include one of dozens of
+      'functions', and their arguments, and there are even some string
+      manipulation notation in there.
+
+    * The last syntax that underlies AEL, and is not used
+      directly in AEL, is the Extension Language Syntax. The
+      extension language is what you see in extensions.conf, and AEL
+      compiles the higher level AEL language into extensions and
+      priorities, and passes them via function calls into
+      Asterisk. Embedded in this language is the Application/AGI
+      commands, of which one application call per step, or priority
+      can be made. You can think of this as a "macro assembler"
+      language, that AEL2 will compile into.
+
+
+Any programmer of AEL should be familiar with it's syntax, of course,
+as well as the Expression syntax, and the Variable syntax.
+
+**************************
+* Asterisk in a Nutshell *
+**************************
+
+Asterisk acts as a server. Devices involved in telephony, like Zapata
+cards, or Voip phones, all indicate some context that should be
+activated in their behalf. See the config file formats for IAX, SIP,
+zapata.conf, etc. They all help describe a device, and they all
+specify a context to activate when somebody picks up a phone, or a
+call comes in from the phone company, or a voip phone, etc.
+
+Contexts
+--------
+
+Contexts are a grouping of extensions.
+
+Contexts can also include other contexts. Think of it as a sort of
+merge operation at runtime, whereby the included context's extensions
+are added to the contexts making the inclusion.
+
+Extensions and priorities
 -------------------------
+
+A Context contains zero or more Extensions. There are several
+predefined extensions. The "s" extension is the "start" extension, and
+when a device activates a context the "s" extension is the one that is
+going to be run. Other extensions are the timeout "t" extension, the
+invalid response, or "i" extension, and there's a "fax" extension. For
+instance, a normal call will activate the "s" extension, but an
+incoming FAX call will come into the "fax" extension, if it
+exists. (BTW, asterisk can tell it's a fax call by the little "beep"
+that the calling fax machine emits every so many seconds.).
+
+Extensions contain several priorities, which are individual
+instructions to perform. Some are as simple as setting a variable to a
+value. Others are as complex as initiating the Voicemail application,
+for instance. Priorities are executed in order.
+
+When the 's" extension completes, asterisk waits until the timeout for
+a response. If the response matches an extension's pattern in the
+context, then control is transferred to that extension. Usually the
+responses are tones emitted when a user presses a button on their
+phone. For instance, a context associated with a desk phone might not
+have any "s" extension. It just plays a dialtone until someone starts
+hitting numbers on the keypad, gather the number, find a matching
+extension, and begin executing it. That extension might Dial out over
+a connected telephone line for the user, and then connect the two
+lines together.
+
+The extensions can also contain "goto" or "jump" commands to skip to
+extensions in other contexts. Conditionals provide the ability to
+react to different stimiuli, and there you have it.
+
+Macros
+------
+
+Think of a macro as a combination of a context with one nameless
+extension, and a subroutine. It has arguments like a subroutine
+might. A macro call can be made within an extension, and the
+individual statements there are executed until it ends. At this point,
+execution returns to the next statement after the macro call. Macros
+can call other macros. And they work just like function calls.
+
+Applications
+------------
+
+Application calls, like "Dial()", or "Hangup()", or "Answer()", are
+available for users to use to accomplish the work of the
+dialplan. There are over 145 of them at the moment this was written,
+and the list grows as new needs and wants are uncovered. Some
+applications do fairly simple things, some provide amazingly complex
+services.
+
+Hopefully, the above objects will allow you do anything you need to in
+the Asterisk environment!
+
+
+*******************
+* Getting Started *
+*******************
+
 The AEL parser (pbx_ael.so) is completely separate from the module
-that parses extensions.conf (pbx_config.so).  To use AEL, the only thing that
-has to be done is the module pbx_ael.so must be loaded by Asterisk.  This will
-be done automatically if using 'autoload=yes' in /etc/asterisk/modules.conf.
-When the module is loaded, it will look for 'extensions.ael' in /etc/asterisk/.
-Both extensions.conf and extensions.ael can be used in conjunction with each 
-other if that is what is desired.  Some users may want to keep extensions.conf
-for the features that are configured in the 'general' section of 
-extensions.conf.
+that parses extensions.conf (pbx_config.so). To use AEL, the only
+thing that has to be done is the module pbx_ael.so must be loaded by
+Asterisk. This will be done automatically if using 'autoload=yes' in
+/etc/asterisk/modules.conf. When the module is loaded, it will look
+for 'extensions.ael' in /etc/asterisk/. extensions.conf and
+extensions.ael can be used in conjunction with
+each other if that is what is desired. Some users may want to keep
+extensions.conf for the features that are configured in the 'general'
+section of extensions.conf.
 
+------------------------------
+- Reloading extensions.ael  -
+------------------------------
 
-Reloading extensions.ael
--------------------------
-To reload extensions.ael, the following command can be issued at the CLI.
+To reload extensions.ael, the following command can be issued at the
+CLI:
 
-	*CLI> reload pbx_ael.so
+    *CLI> ael reload
 
 
-Contexts
+
+*************
+* Debugging *
+*************
+
+Right at this moment, the following commands are available, but do
+nothing:
+
+Enable AEL contexts debug
+   *CLI> ael debug contexts 
+
+Enable AEL macros debug
+   *CLI> ael debug macros 
+
+Enable AEL read debug
+   *CLI> ael debug read
+
+Enable AEL tokens debug
+   *CLI> ael debug tokens 
+
+Disable AEL debug messages
+   *CLI> ael no debug
+
+If things are going wrong in your dialplan, you can use the following
+facilities to debug your file:
+
+1. The messages log in /var/log/asterisk. (from the checks done at load time).
+2. the "show dialplan" command in asterisk
+3. the standalone executable, "aelparse" built in the utils/ dir in the source.
+
+
+*****************************
+* About "aelparse"          *
+*****************************
+
+You can also use the "aelparse" program to check your extensions.ael
+file before feeding it to asterisk. Wouldn't it be nice to eliminate
+most errors before giving the file to asterisk?
+
+aelparse is compiled in the utils directory of the asterisk release.
+It isn't installed anywhere (yet). You can copy it to your favorite
+spot in your PATH.
+
+aelparse has two optional arguments:
+
+-d   - Override the normal location of the config file dir, (usually
+       /etc/asterisk), and use the current directory instead as the
+       config file dir. Aelparse will then expect to find the file
+       "./extensions.ael" in the current directory, and any included
+       files in the current directory as well.
+
+-n   - don't show all the function calls to set priorities and contexts
+       within asterisk. It will just show the errors and warnings from
+       the parsing and semantic checking phases.
+
+
+******************************
+* General Notes about Syntax *
+******************************
+
+Note that the syntax and style are now a little more free-form. The
+opening '{' (curly-braces) do not have to be on the same line as the
+keyword that precedes them. Statements can be split across lines, as
+long as tokens are not broken by doing so. More than one statement can
+be included on a single line. Whatever you think is best!
+
+You can just as easily say,
+
+if(${x}=1) { NoOp(hello!); goto s|3; } else { NoOp(Goodbye!); goto s|12; }
+
+as you can say:
+
+if(${x}=1)
+{
+       NoOp(hello!);
+   goto s|3;
+}
+else
+{
+       NoOp(Goodbye!);
+       goto s|12;
+}
+
+or:
+
+if(${x}=1) {
+       NoOp(hello!);
+   goto s|3;
+} else {
+       NoOp(Goodbye!);
+       goto s|12;
+}
+
+or:
+
+if (${x}=1) {
+       NoOp(hello!); goto s|3;
+} else {
+       NoOp(Goodbye!); goto s|12;
+}
+
+or even:
+
+if
+(${x}=1)
+{
+NoOp(hello!);
+goto s|3;
+}
+else
+{
+NoOp(Goodbye!);
+goto s|12;
+}
+
+
+************
+* Keywords *
+************
+
+The AEL keywords are case-sensitive. If an application name and a
+keyword overlap, there is probably good reason, and you should
+consider replacing the application call with an AEL statement. If you
+do not wish to do so, you can still use the application, by using a
+capitalized letter somewhere in its name. In the Asterisk extension
+language, application names are NOT case-sensitive.
+
+The following are keywords in the AEL2 language:
+
+    * abstract
+    * context
+    * macro
+    * globals
+    * ignorepat
+    * switch
+    * if
+    * ifTime
+    * else
+    * random
+    * goto
+    * jump
+    * return
+    * break
+    * continue
+    * regexten
+    * hint
+    * for
+    * while
+    * case
+    * pattern
+    * default   NOTE: the "default" keyword can be used as a context name, 
+                      for those who would like to do so.
+    * catch
+    * switches
+    * eswitches
+    * includes 
+
+
+
+
+
+Procedural Interface and Internals
+==================================
+
+AEL first parses the extensions.ael file into a memory structure representing the file.
+The entire file is represented by a tree of "pval" structures linked together.
+
+This tree is then handed to the semantic check routine. 
+
+Then the tree is handed to the compiler. 
+
+After that, it is freed from memory.
+
+A program could be written that could build a tree of pval structures, and
+a pretty printing function is provided, that would dump the data to a file,
+or the tree could be handed to the compiler to merge the data into the 
+asterisk dialplan. The modularity of the design offers several opportunities
+for developers to simplify apps to generate dialplan data.
+
+
+
+=========================
+        AEL version 2 BNF
+=========================
+
+
+
+(hopefully, something close to bnf).
+
+First, some basic objects
+
+------------------------
+
+<word>    a lexical token consisting of characters matching this pattern: [-a-zA-Z0-9"_/.\<\>\*\+!$#\[\]][-a-zA-Z0-9"_/.!\*\+\<\>\{\}$#\[\]]*
+
+<word3-list>  a concatenation of up to 3 <word>s.
+
+<collected-word>  all characters encountered until the character that follows the <collected-word> in the grammar.
+
 -------------------------
-Contexts in AEL represent a set of extensions in the same way that they do
-in extensions.conf.
+
+<file> :== <objects>
+
+<objects> :== <object>
+           | <objects> <object>
+
+
+<object> :==  <context>
+         | <macro>
+         | <globals>
+         | ';'
+
+
+<context> :==  'context' <word> '{' <elements> '}'
+            | 'context' <word> '{' '}'
+            | 'context' 'default' '{' <elements> '}'
+            | 'context' 'default' '{' '}'
+            | 'abstract'  'context' <word> '{' <elements> '}'
+            | 'abstract'  'context' <word> '{' '}'
+            | 'abstract'  'context' 'default' '{' <elements> '}'
+            | 'abstract'  'context' 'default' '{' '}'
+
+
+<macro> :== 'macro' <word> '(' <arglist> ')' '{' <macro_statements> '}'
+       | 'macro' <word> '(' <arglist> ')' '{'  '}'
+       | 'macro' <word> '(' ')' '{' <macro_statements> '}'
+       | 'macro' <word> '(' ')' '{'  '}'
+
+
+<globals> :== 'globals' '{' <global_statements> '}'
+         | 'globals' '{' '}'
+
+
+<global_statements> :== <global_statement>
+                   | <global_statements> <global_statement>
+
+
+<global_statement> :== <word> '=' <collected-word> ';'
+
+
+<arglist> :== <word>
+         | <arglist> ',' <word>
+
+
+<elements> :==  <element>
+             | <elements> <element>
+
+
+<element> :== <extension>
+         | <includes>
+         | <switches>
+         | <eswitches>
+         | <ignorepat>
+         | <word> '='  <collected-word> ';'
+         | ';'
+
+
+<ignorepat> :== 'ignorepat' '=>' <word> ';'
+
+
+<extension> :== <word> '=>' <statement>
+           | 'regexten' <word> '=>' <statement>
+           | 'hint' '(' <word3-list> ')' <word> '=>' <statement>
+           | 'regexten' 'hint' '(' <word3-list> ')' <word> '=>' <statement>
+
+
+<statements> :== <statement>
+            | <statements> <statement>
+
+<if_head> :== 'if' '('  <collected-word> ')'
+
+<random_head> :== 'random' '(' <collected-word> ')'
+
+<ifTime_head> :== 'ifTime' '(' <word3-list> ':' <word3-list> ':' <word3-list> '|' <word3-list> '|' <word3-list> '|' <word3-list> ')'
+                       | 'ifTime' '(' <word> '|' <word3-list> '|' <word3-list> '|' <word3-list> ')'
+
+
+<word3-list> :== <word>
+       | <word> <word>
+       | <word> <word> <word>
+
+<switch_head> :== 'switch' '(' <collected-word> ')'  '{'
+
+
+<statement> :== '{' <statements> '}'
+       | <word> '='  <collected-word> ';'
+       | 'goto' <target> ';'
+       | 'jump' <jumptarget> ';'
+       | <word> ':'
+       | 'for' '('  <collected-word> ';'  <collected-word> ';' <collected-word> ')' <statement>
+       | 'while' '('  <collected-word> ')' <statement>
+       | <switch_head> '}'
+       | <switch_head> <case_statements> '}'
+       | '&' macro_call ';'
+       | <application_call> ';'
+       | <application_call> '='  <collected-word> ';'
+       | 'break' ';'
+       | 'return' ';'
+       | 'continue' ';'
+       | <random_head> <statement>
+       | <random_head> <statement> 'else' <statement>
+       | <if_head> <statement>
+       | <if_head> <statement> 'else' <statement>
+       | <ifTime_head> <statement>
+       | <ifTime_head> <statement> 'else' <statement>
+       | ';'
+
+<target> :== <word>
+       | <word> '|' <word>
+       | <word> '|' <word> '|' <word>
+       | 'default' '|' <word> '|' <word>
+       | <word> ',' <word>
+       | <word> ',' <word> ',' <word>
+       | 'default' ',' <word> ',' <word>
+
+<jumptarget> :== <word>
+               | <word> ',' <word>
+               | <word> ',' <word> '@' <word>
+               | <word> '@' <word>
+               | <word> ',' <word> '@' 'default'
+               | <word> '@' 'default'
+
+<macro_call> :== <word> '(' <eval_arglist> ')'
+       | <word> '(' ')'
+
+<application_call_head> :== <word>  '('
+
+<application_call> :== <application_call_head> <eval_arglist> ')'
+       | <application_call_head> ')'
+
+<eval_arglist> :==  <collected-word>
+       | <eval_arglist> ','  <collected-word>
+       |  /* nothing */
+       | <eval_arglist> ','  /* nothing */
+
+<case_statements> :== <case_statement>
+       | <case_statements> <case_statement>
+
+
+<case_statement> :== 'case' <word> ':' <statements>
+       | 'default' ':' <statements>
+       | 'pattern' <word> ':' <statements>
+       | 'case' <word> ':'
+       | 'default' ':'
+       | 'pattern' <word> ':'
+
+<macro_statements> :== <macro_statement>
+       | <macro_statements> <macro_statement>
+
+<macro_statement> :== <statement>
+       | 'catch' <word> '{' <statements> '}'
+
+<switches> :== 'switches' '{' <switchlist> '}'
+       | 'switches' '{' '}'
+
+<eswitches> :== 'eswitches' '{' <switchlist> '}'
+       | 'eswitches' '{'  '}'
+
+<switchlist> :== <word> ';'
+       | <switchlist> <word> ';'
+
+<includeslist> :== <includedname> ';'
+       | <includedname> '|' <word3-list> ':' <word3-list> ':' <word3-list> '|' <word3-list> '|' <word3-list> '|' <word3-list> ';'
+       | <includedname> '|' <word> '|' <word3-list> '|' <word3-list> '|' <word3-list> ';'
+       | <includeslist> <includedname> ';'
+       | <includeslist> <includedname> '|' <word3-list> ':' <word3-list> ':' <word3-list> '|' <word3-list> '|' <word3-list> '|' <word3-list> ';'
+       | <includeslist> <includedname> '|' <word> '|' <word3-list> '|' <word3-list> '|' <word3-list> ';'
+
+<includedname> :== <word>
+        | 'default'
+
+<includes> :== 'includes' '{' <includeslist> '}'
+       | 'includes' '{' '}'
+
+
+**************************
+* AEL Example USAGE *****
+**************************
+
+Comments
+========
+
+Comments begin with // and end with the end of the line.
+
+Comments are removed by the lexical scanner, and will not be
+recognized in places where it is busy gathering expressions to wrap in
+$[] , or inside application call argument lists. The safest place to put
+comments is after terminating semicolons, or on otherwise empty lines.
+
+
+Context
+=======
+
+Contexts in AEL represent a set of extensions in the same way that
+they do in extensions.conf.
+
 
 context default {
 
-};
+}
+
+
+A context can be declared to be "abstract", in which case, this
+declaration expresses the intent of the writer, that this context will
+only be included by another context, and not "stand on its own". The
+current effect of this keyword is to prevent "goto " statements from
+being checked.
+
+
+abstract context longdist {
+            _1NXXNXXXXXX => NoOp(generic long distance dialing actions in the US);
+}
+
 
 
 Extensions
--------------------------
-To specify an extension in a context, the following syntax is used.  If more
-than one application is be called in an extension, they can be listed in order
-inside of a block.
+==========
+
+To specify an extension in a context, the following syntax is used. If
+more than one application is be called in an extension, they can be
+listed in order inside of a block.
+
 
 context default {
-	1234 => Playback(tt-monkeys);
-	8000 => {
-		NoOp(one);
-		NoOp(two);
-		NoOp(three);
-	};
-	_5XXX => NoOp(it's a pattern!);
-};
+    1234 => Playback(tt-monkeys);
+    8000 => {
+         NoOp(one);
+         NoOp(two);
+         NoOp(three);
+    };
+    _5XXX => NoOp(it's a pattern!);
+}
+
+
+Two optional items have been added to the AEL syntax, that allow the
+specification of hints, and a keyword, regexten, that will force the
+numbering of priorities to start at 2.
+
+
+context default {
+
+    regexten _5XXX => NoOp(it's a pattern!);
+}
+
+
+
+context default {
+
+    hint(Sip/1) _5XXX => NoOp(it's a pattern!);
+}
+
+
+
+context default {
+
+    regexten hint(Sip/1) _5XXX => NoOp(it's a pattern!);
+}
+
+
+The regexten must come before the hint if they are both present.
+
 
 
 Includes
--------------------------
-Contexts can be included in other contexts.  All included contexts are listed
-within a single block.
+========
+
+Contexts can be included in other contexts. All included contexts are
+listed within a single block.
+
 
 context default {
-	includes {
-		local;
-		longdistance;
-		international;
-	};
-};
+    includes {
+         local;
+         longdistance;
+         international;
+    }
+}
+
+
+Time-limited inclusions can be specified, as in extensions.conf
+format, with the fields described in the wiki page Asterisk cmd
+GotoIfTime.
+
+
+context default {
+    includes {
+         local;
+         longdistance|16:00-23:59|mon-fri|*|*;
+         international;
+    }
+}
+
+
+#include
+========
+
+You can include other files with the #include "filepath" construct.
+
+
+   #include "/etc/asterisk/testfor.ael"
+
+
+An interesting property of the #include, is that you can use it almost
+anywhere in the .ael file. It is possible to include the contents of
+a file in a macro, context, or even extension.  The #include does not
+have to occur at the beginning of a line. Included files can include
+other files, up to 50 levels deep. If the path provided in quotes is a
+relative path, the parser looks in the config file directory for the
+file (usually /etc/asterisk).
+
 
 
 Dialplan Switches
--------------------------
-Switches are listed in their own block within a context.
+=================
+
+Switches are listed in their own block within a context. For clues as
+to what these are used for, see Asterisk - dual servers, and Asterisk
+config extensions.conf.
+
 
 context default {
-	switches {
-		DUNDi/e164;
-		IAX2/box5;
-	};
-	eswitches {
-		IAX2/context@${CURSERVER};
-	};
-};
+    switches {
+         DUNDi/e164;
+         IAX2/box5;
+    };
+    eswitches {
+         IAX2/context@${CURSERVER};
+    }
+}
+
 
 
 Ignorepat
--------------------------
-ignorepat can be used to instruct channel drivers to not cancel dialtone upon
-receipt of a particular pattern.  The most commonly used example is '9'.
+=========
+
+ignorepat can be used to instruct channel drivers to not cancel
+dialtone upon receipt of a particular pattern. The most commonly used
+example is '9'.
+
 
 context outgoing {
-	ignorepat => 9;
-};
+    ignorepat => 9;
+}
+
+
 
 
 Variables
--------------------------
-Variables in Asterisk do not have a type, so to define a variable, it just has
-to be specified with a value.
+=========
+
+Variables in Asterisk do not have a type, so to define a variable, it
+just has to be specified with a value.
 
 Global variables are set in their own block.
 
+
 globals {
-	CONSOLE=Console/dsp;
-	TRUNK=Zap/g2;
-};
+    CONSOLE=Console/dsp;
+    TRUNK=Zap/g2;
+}
+
+
 
 Variables can be set within extensions as well.
 
+
 context foo {
-	555 => {
-		x=5;
-		y=blah;
-		NoOp(x is ${x} and y is ${y} !);
-	};
-};
+    555 => {
+         x=5;
+         y=blah;
+         divexample=10/2
+         NoOp(x is ${x} and y is ${y} !);
+    }
+}
+
+
+NOTE: AEL wraps the right hand side of an assignment with $[ ] to allow 
+expressions to be used If this is unwanted, you can protect the right hand 
+side from being wrapped by using the Set() application. 
+Read the README.variables about the requirements and behavior 
+of $[ ] expressions.
+
+NOTE: These things are wrapped up in a $[ ] expression: The while() test; 
+the if() test; the middle expression in the for( x; y; z) statement 
+(the y expression); Assignments - the right hand side, so a = b -> Set(a=$[b])
 
 Writing to a dialplan function is treated the same as writing to a variable.
 
+
 context blah {
-	s => {
-		CALLERID(name)=ChickenMan;
-		NoOp(My name is ${CALLERID(name)} !);
-	};
-}; 
+    s => {
+         CALLERID(name)=ChickenMan;
+         NoOp(My name is ${CALLERID(name)} !);
+    }
+} 
+
 
 
 Loops
--------------------------
+=====
+
 AEL has implementations of 'for' and 'while' loops.
 
+
 context loops {
-	1 => {
-		for (x=0; ${x} < 3; x=${x} + 1) {
-			Verbose(x is ${x} !);
-		};
-	};
-	2 => {
-		y=10;
-		while (${y} >= 0) {
-			Verbose(y is ${y} !);
-			y=${y}-1;
-		};
-	};
-};
+    1 => {
+         for (x=0; ${x} < 3; x=${x} + 1) {
+              Verbose(x is ${x} !);
+         }
+    }
+    2 => {
+         y=10;
+         while (${y} >= 0) {
+              Verbose(y is ${y} !);
+              y=${y}-1;
+         }
+    }
+}
+
+
+NOTE: The conditional expression (the "${y} >= 0" above) is wrapped in
+      $[ ] so it can be evaluated.  NOTE: The for loop test expression
+      (the "${x} < 3" above) is wrapped in $[ ] so it can be evaluated.
+
 
 
 Conditionals
--------------------------
-AEL supports if and switch statements.  Note that if you have an else 
-clause, you MUST place braces around the non-else portion of the if 
-statement.
+============
+
+AEL supports if and switch statements, like AEL, but adds ifTime, and
+random. Unlike the original AEL, though, you do NOT need to put curly
+braces around a single statement in the "true" branch of an if(), the
+random(), or an ifTime() statement. The if(), ifTime(), and random()
+statements allow optional else clause.
+
 
 context conditional {
-	_8XXX => {
-		Dial(SIP/${EXTEN});
-		if (${DIALSTATUS} = "BUSY") {
-			Voicemail(${EXTEN}|b);
-		} else
-			Voicemail(${EXTEN}|u);
-	};
-	_777X => {
-		switch (${EXTEN}) {
-			case 7771:
-				NoOp(You called 7771!);
-				break;
-			case 7772:
-				NoOp(You called 7772!);
-				break;
-			case 7773:
-				NoOp(You called 7773!);
-				// fall through
-			default:
-				NoOp(In the default clause!);
-		};
-	};
-};
-
-
-goto and labels
--------------------------
+    _8XXX => {
+         Dial(SIP/${EXTEN});
+         if ("${DIALSTATUS}" = "BUSY")
+         {
+              NoOp(yessir);
+              Voicemail(${EXTEN}|b);
+         }
+         else
+              Voicemail(${EXTEN}|u);
+         ifTime (14:00-25:00|sat-sun|*|*) 
+              Voicemail(${EXTEN}|b);
+         else
+         {
+              Voicemail(${EXTEN}|u);
+              NoOp(hi, there!);
+         }
+         random(51) NoOp(This should appear 51% of the time);
+
+         random( 60 )
+         {
+                       NoOp( This should appear 60% of the time );
+         }
+         else
+         {
+                       random(75)
+                       {
+                               NoOp( This should appear 30% of the time! );
+                       }
+                       else
+                       {
+                               NoOp( This should appear 10% of the time! );
+                       }
+          }
+    }
+    _777X => {
+         switch (${EXTEN}) {
+              case 7771:
+                   NoOp(You called 7771!);
+                   break;
+              case 7772:
+                   NoOp(You called 7772!);
+                   break;
+              case 7773:
+                   NoOp(You called 7773!);
+                   // fall thru-
+              pattern 777[4-9]:
+                    NoOp(You called 777 something!);
+              default:
+                   NoOp(In the default clause!);
+         }
+    }
+}
+
+
+NOTE: The conditional expression in if() statements (the
+      "${DIALSTATUS}" = "BUSY" above) is wrapped by the compiler in 
+      $[] for evaluation.
+
+NOTE: Neither the switch nor case values are wrapped in $[ ]; they can
+      be constants, or ${var} type references only.
+
+NOTE: AEL generates each case as a separate extension. case clauses
+      with no terminating 'break', or 'goto', have a goto inserted, to
+      the next clause, which creates a 'fall thru' effect.
+
+NOTE: AEL introduces the ifTime keyword/statement, which works just
+      like the if() statement, but the expression is a time value,
+      exactly like that used by the application GotoIfTime(). See
+      Asterisk cmd GotoIfTime
+
+NOTE: The pattern statement makes sure the new extension that is
+      created has an '_' preceding it to make sure asterisk recognizes
+      the extension name as a pattern.
+
+NOTE: Every character enclosed by the switch expression's parenthesis
+      are included verbatim in the labels generated. So watch out for
+      spaces!
+
+NOTE: NEW: Previous to version 0.13, the random statement used the
+      "Random()" application, which has been deprecated. It now uses
+      the RAND() function instead, in the GotoIf application.
+
+
+Break, Continue, and Return
+===========================
+
+
+Three keywords, break, continue, and return, are included in the
+syntax to provide flow of control to loops, and switches.
+
+The break can be used in switches and loops, to jump to the end of the
+loop or switch.
+
+The continue can be used in loops (while and for) to immediately jump
+to the end of the loop. In the case of a for loop, the increment and
+test will then be performed. In the case of the while loop, the
+continue will jump to the test at the top of the loop.
+
+The return keyword will cause an immediate jump to the end of the
+context, or macro, and can be used anywhere.
+
+
+
+goto, jump, and labels
+======================
+
 This is an example of how to do a goto in AEL.
 
+
+context gotoexample {
+    s => {
+begin:
+         NoOp(Infinite Loop!  yay!);
+         Wait(1);
+         goto begin;    // go to label in same extension
+    }
+    3 => {
+            goto s|begin;   // go to label in different extension
+     }
+     4 => {
+            goto gotoexample|s|begin;  // overkill go to label in same context
+     }
+}
+
+context gotoexample2 {
+     s =>  {
+   end: 
+           goto gotoexample|s|begin;   // go to label in different context
+     }
+}
+
+You can use the special label of "1" in the goto and jump
+statements. It means the "first" statement in the extension. I would
+not advise trying to use numeric labels other than "1" in goto's or
+jumps, nor would I advise declaring a "1" label anywhere! As a matter
+of fact, it would be bad form to declare a numeric label, and it might
+confllict with the priority numbers used internally by asterisk.
+
+The syntax of the jump statement is: jump
+extension[,priority][@context] If priority is absent, it defaults to
+"1". If context is not present, it is assumed to be the same as that
+which contains the "jump".
+
+
 context gotoexample {
-	s => {
+    s => {
 begin:
-		NoOp(Infinite Loop!  yay!);
-		Wait(1);
-		goto begin;
-	};
-};
+         NoOp(Infinite Loop!  yay!);
+         Wait(1);
+         jump s;    // go to first extension in same extension
+    }
+    3 => {
+            jump s,begin;   // go to label in different extension
+     }
+     4 => {
+            jump s,begin@gotoexample;  // overkill go to label in same context
+     }
+}
+
+context gotoexample2 {
+     s =>  {
+   end: 
+           jump s@gotoexample;   // go to label in different context
+     }
+}
+
+NOTE: goto labels follow the same requirements as the Goto()
+      application, except the last value has to be a label. If the
+      label does not exist, you will have run-time errors. If the
+      label exists, but in a different extension, you have to specify
+      both the extension name and label in the goto, as in: goto s|z;
+      if the label is in a different context, you specify
+      context|extension|label. There is a note about using goto's in a
+      switch statement below...
+
+NOTE  AEL introduces the special label "1", which is the beginning
+      context number for most extensions.
+
+NOTE: A NEW addition to AEL: you can now use ',' instead of '|' to 
+      separate the items in the target address. You can't have a mix,
+      though, of '|' and ',' in the target. It's either one, or the other.
+
+
 
 
 Macros
--------------------------
-A macro is defined in its own block like this.  The arguments to the macro are
-specified with the name of the macro.  They are then reffered to by that same
-name.  A catch block can be specified to catch special extensions.
+======
+
+A macro is defined in its own block like this. The arguments to the
+macro are specified with the name of the macro. They are then referred
+to by that same name. A catch block can be specified to catch special
+extensions.
+
 
 macro std-exten( ext , dev ) {
-        Dial(${dev}/${ext},20);
-        switch(${DIALSTATUS) {
-        case BUSY:
-                Voicemail(b${ext});
-                break;
-        default:
-                Voicemail(u${ext});
-        };
-        catch a {
-                VoiceMailMain(${ext});
-                return;
-        };
-};
-
-A macro is then called by preceeding the macro name with an ampersand.
+       Dial(${dev}/${ext},20);
+       switch(${DIALSTATUS) {
+       case BUSY:
+               Voicemail(b${ext});
+               break;
+       default:
+               Voicemail(u${ext});
+
+       }
+       catch a {
+               VoiceMailMain(${ext});
+               return;
+       }
+}
+
+
+A macro is then called by preceeding the macro name with an
+ampersand. Empty arguments can be passed simply with nothing between
+comments(0.11).
+
 
 context example {
-	_5XXX => &std-exten(${EXTEN}, "IAX2");
-};
+    _5XXX => &std-exten(${EXTEN}, "IAX2");
+    _6XXX => &std-exten(, "IAX2");
+    _7XXX => &std-exten(${EXTEN},);
+    _8XXX => &std-exten(,);
+}
+
 
 
 Examples
-------------------------
+========
+
 
 context demo {
-	s => {
-		Wait(1);
-		Answer();
-		TIMEOUT(digit)=5;
-		TIMEOUT(response)=10;
+    s => {
+         Wait(1);
+         Answer();
+         TIMEOUT(digit)=5;
+         TIMEOUT(response)=10;
 restart:
-		Background(demo-congrats);
+         Background(demo-congrats);
 instructions:
-		for (x=0; ${x} < 3; x=${x} + 1) {
-			Background(demo-instruct);
-			WaitExten();
-		};
-	};
-	2 => {
-		Background(demo-moreinfo);
-		goto s|instructions;
-	};
-	3 => {
-		LANGUAGE()=fr;
-		goto s|restart;
-	};
-	500 => {
-		Playback(demo-abouttotry);
-		Dial(IAX2/guest@misery.digium.com);
-		Playback(demo-nogo);
-		goto s|instructions;
-	};
-	600 => {
-		Playback(demo-echotest);
-		Echo();
-		Playback(demo-echodone);
-		goto s|instructions;
-	};
-	# => {
+         for (x=0; ${x} < 3; x=${x} + 1) {
+              Background(demo-instruct);
+              WaitExten();
+         }
+    }
+    2 => {
+         Background(demo-moreinfo);
+         goto s|instructions;
+    }
+    3 => {
+         LANGUAGE()=fr;
+         goto s|restart;
+    }
+
+    500 => {
+         Playback(demo-abouttotry);
+         Dial(IAX2/guest@misery.digium.com);
+         Playback(demo-nogo);
+         goto s|instructions;
+    }
+    600 => {
+         Playback(demo-echotest);
+         Echo();
+         Playback(demo-echodone);
+         goto s|instructions;
+    }
+    # => {
 hangup:
-		Playback(demo-thanks);
-		Hangup();
-	};
-	t => goto #|hangup;
-	i => Playback(invalid);
-};
+         Playback(demo-thanks);
+         Hangup();
+    }
+    t => goto #|hangup;
+    i => Playback(invalid);
+}
 
 
-Syntax Note
-------------------------
-Please note that all opening {'s are on the same line as the keyword.  For
-the time being, that syntax is mandatory.  We are looking at ways to allow
-other syntax in the future for flexibility, but for now, that is the way
-you must write AEL clauses.
+Semantic Checks
+===============
+
+
+AEL, after parsing, but before compiling, traverses the dialplan
+tree, and makes several checks:
+
+    * Macro calls to non-existent macros.
+    * Macro calls to contexts.
+    * Macro calls with argument count not matching the definition.
+    * application call to macro. (missing the '&')
+    * application calls to "GotoIf", "GotoIfTime", "while",
+      "endwhile", "Random", and "execIf", will generate a message to
+      consider converting the call to AEL goto, while, etc. constructs.
+    * goto a label in an empty extension.
+    * goto a non-existent label, either a within-extension,
+      within-context, or in a different context, or in any included
+      contexts. Will even check "sister" context references.
+    * All the checks done on the time values in the dial plan, are
+      done on the time values in the ifTime() and includes times:
+          o the time range has to have two times separated by a dash;
+          o the times have to be in range of 0 to 24 hours.
+          o The weekdays have to match the internal list, if they are provided;
+          o the day of the month, if provided, must be in range of 1 to 31;
+          o the month name or names have to match those in the internal list. 
+    * (0.5) If an expression is wrapped in $[ ... ], and the compiler
+      will wrap it again, a warning is issued.
+    * (0.5) If an expression had operators (you know,
+      +,-,*,/,%,!,etc), but no ${ } variables, a warning is
+      issued. Maybe someone forgot to wrap a variable name?
+    * (0.12) check for duplicate context names.
+    * (0.12) check for abstract contexts that are not included by any context.
+    * (0.13) Issue a warning if a label is a numeric value. 
+
+There are a subset of checks that have been removed until the proposed
+AAL (Asterisk Argument Language) is developed and incorporated into Asterisk.
+These checks will be:
+
+    * (if the application argument analyzer is working: the presence
+      of the 'j' option is reported as error.
+    * if options are specified, that are not available in an
+      application.
+    * if you specify too many arguments to an application.
+    * a required argument is not present in an application call.
+    * Switch-case using "known" variables that applications set, that
+      does not cover all the possible values. (a "default" case will
+      solve this problem. Each "unhandled" value is listed.
+    * a Switch construct is used, which is uses a known variable, and
+      the application that would set that variable is not called in
+      the same extension. This is a warning only...
+    * Calls to applications not in the "applist" database (installed
+      in /var/lib/asterisk/applist" on most systems).
+    * In an assignment statement, if the assignment is to a function,
+      the function name used is checked to see if it one of the
+      currently known functions. A warning is issued if it is not.
+
+
+
+Differences with the original version of AEL
+============================================
+
+   1. The $[...] expressions have been enhanced to inlcude the ==, ||,
+      and && operators. These operators are exactly equivalent to the
+      =, |, and & operators, respectively. Why? So the C, Java, C++
+      hackers feel at home here.
+   2. It is more free-form. The newline character means very little,
+      and is pulled out of the white-space only for line numbers in
+      error messages.
+   3. It generates more error messages -- by this I mean that any
+      difference between the input and the grammar are reported, by
+      file, line number, and column.
+   4. It checks the contents of $[ ] expressions (or what will end up
+      being $[ ] expressions!) for syntax errors. It also does
+      matching paren/bracket counts.
+   5. It runs several semantic checks after the parsing is over, but
+      before the compiling begins, see the list above.
+   6. It handles #include "filepath" directives. -- ALMOST
+      anywhere, in fact. You could easily include a file in a context,
+      in an extension, or at the root level. Files can be included in
+      files that are included in files, down to 50 levels of hierarchy...
+   7. Local Goto's inside Switch statements automatically have the
+      extension of the location of the switch statement appended to them.
+   8. A pretty printer function is available within pbx_ael.so.
+   9. In the utils directory, two standalone programs are supplied for
+      debugging AEL files. One is called "aelparse", and it reads in
+      the /etc/asterisk/extensions.ael file, and shows the results of
+      syntax and semantic checking on stdout, and also shows the
+      results of compilation to stdout. The other is "aelparse1",
+      which uses the original ael compiler to do the same work,
+      reading in "/etc/asterisk/extensions.ael", using the original
+      'pbx_ael.so' instead.
+  10. AEL supports the "jump" statement, and the "pattern" statement
+      in switch constructs. Hopefully these will be documented in the
+      AEL README.
+  11. Added the "return" keyword, which will jump to the end of an
+      extension/Macro.
+  12. Added the ifTime (<time range>|<days of week>|<days of
+      month>|<months> ) {} [else {}] construct, which executes much
+      like an if () statement, but the decision is based on the
+      current time, and the time spec provided in the ifTime. See the
+      example above. (Note: all the other time-dependent Applications
+      can be used via ifTime)
+  13. Added the optional time spec to the contexts in the includes
+      construct. See examples above.
+  14. You don't have to wrap a single "true" statement in curly
+      braces, as in the orignal AEL. An "else" is attached to the
+      closest if. As usual, be careful about nested if statements!
+      When in doubt, use curlies!
+  15. Added the syntax [regexten] [hint(channel)] to preceed an
+      extension declaration. See examples above, under
+      "Extension". The regexten keyword will cause the priorities in
+      the extension to begin with 2 instead of 1. The hint keyword
+      will cause its arguments to be inserted in the extension under
+      the hint priority. They are both optional, of course, but the
+      order is fixed at the moment-- the regexten must come before the
+      hint, if they are both present.
+  16. Empty case/default/pattern statements will "fall thru" as
+      expected. (0.6)
+  17. A trailing label in an extension, will automatically have a
+      NoOp() added, to make sure the label exists in the extension on
+      Asterisk. (0.6)
+  18. (0.9) the semicolon is no longer required after a closing brace!
+      (i.e. "];" ===> "}". You can have them there if you like, but
+      they are not necessary. Someday they may be rejected as a syntax
+      error, maybe.
+  19. (0.9) the // comments are not recognized and removed in the
+      spots where expressions are gathered, nor in application call
+      arguments. You may have to move a comment if you get errors in
+      existing files.
+  20. (0.10) the random statement has been added. Syntax: random (
+      <expr> ) <lucky-statement> [ else <unlucky-statement> ]. The
+      probability of the lucky-statement getting executed is <expr>,
+      which should evaluate to an integer between 0 and 100. If the
+      <lucky-statement> isn't so lucky this time around, then the
+      <unlucky-statement> gets executed, if it is present.
+
+
+
+Hints and Bugs
+==============
+
+    * The safest way to check for a null strings is to say $[ "${x}" =
+     "" ] The old way would do as shell scripts often do, and append
+     something on both sides, like this: $[ ${x}foo = foo ]. The
+     trouble with the old way, is that, if x contains any spaces, then
+     problems occur, usually syntax errors. It is better practice and
+     safer wrap all such tests with double quotes! Also, there are now
+     some functions that can be used in a variable referenece,
+     ISNULL(), and LEN(), that can be used to test for an empty string:
+     ${ISNULL(${x})} or $[ ${LEN(${x}) = 0 ].
+
+    * Assignment vs. Set(). Keep in mind that setting a variable to
+      value can be done two different ways. If you choose say 'x=y;',
+      keep in mind that AEL will wrap the right-hand-side with
+      $[]. So, when compiled into extension language format, the end
+      result will be 'Set(x=$[y])'. If you don't want this effect,
+      then say "Set(x=y);" instead.
+
+
+The Full Power of AEL
+==============================
+
+A newcomer to Asterisk will look at the above constructs and
+descriptions, and ask, "Where's the string manipulation functions?",
+"Where's all the cool operators that other languages have to offer?",
+etc.
+
+The answer is that the rich capabilities of Asterisk are made
+available through AEL, via:
+
+    * Applications: See Asterisk - documentation of application
+      commands
+
+    * Functions: Functions were implemented inside ${ .. } variable
+      references, and supply many useful capabilities. 
+
+    * Expressions: An expression evaluation engine handles items
+      wrapped inside $[...]. This includes some string manipulation
+      facilities, arithmetic expressions, etc. 
+
+    * Application Gateway Interface: Asterisk can fork external
+      processes that communicate via pipe. AGI applications can be
+      written in any language. Very powerful applications can be added
+      this way. 
+
+    * Variables: Channels of communication have variables associated
+      with them, and asterisk provides some global variables. These can be
+      manipulated and/or consulted by the above mechanisms. 
 
diff --git a/include/asterisk/ael_structs.h b/include/asterisk/ael_structs.h
new file mode 100644
index 0000000000..ea10df9b28
--- /dev/null
+++ b/include/asterisk/ael_structs.h
@@ -0,0 +1,178 @@
+#if !defined(SOLARIS) && !defined(__CYGWIN__)
+#include <err.h>
+#else
+#define quad_t int64_t
+#endif
+
+#ifdef LONG_LONG_MIN
+#define QUAD_MIN LONG_LONG_MIN
+#endif
+#ifdef LONG_LONG_MAX
+#define QUAD_MAX LONG_LONG_MAX
+#endif
+
+#  if ! defined(QUAD_MIN)
+#   define QUAD_MIN     (-0x7fffffffffffffffLL-1)
+#  endif
+#  if ! defined(QUAD_MAX)
+#   define QUAD_MAX     (0x7fffffffffffffffLL)
+#  endif
+
+
+typedef enum 
+{
+	PV_WORD, /* an ident, string, name, label, etc. A user-supplied string. */
+	PV_MACRO,
+	PV_CONTEXT,
+	PV_MACRO_CALL,
+	PV_APPLICATION_CALL,
+	PV_CASE,
+	PV_PATTERN,
+	PV_DEFAULT,
+	PV_CATCH,
+	PV_SWITCHES,
+	PV_ESWITCHES,
+	PV_INCLUDES,
+	PV_STATEMENTBLOCK,
+	PV_VARDEC, /* you know, var=val; */
+	PV_GOTO,
+	PV_LABEL,
+	PV_FOR,
+	PV_WHILE,
+	PV_BREAK,
+	PV_RETURN,
+	PV_CONTINUE,
+	PV_IF,
+	PV_IFTIME,
+	PV_RANDOM,
+	PV_SWITCH,
+	PV_EXTENSION,
+	PV_IGNOREPAT,
+	PV_GLOBALS,
+
+} pvaltype;
+
+/* why this horrible mess? It's always been a tradeoff-- tons of structs,
+   each storing it's specific lists of goodies, or a 'simple' single struct,
+   with lots of fields, that catches all uses at once. Either you have a long
+   list of struct names and subnames, or you have a long list of field names,
+   and where/how they are used. I'm going with a single struct, using unions
+   to reduce storage. Some simple generalizations, and a long list of types,
+   and a book about what is used with what types.... Sorry!
+*/
+
+struct pval
+{
+	pvaltype type;
+	int startline;
+	int endline;
+	int startcol;
+	int endcol;
+	char *filename;
+	
+	union
+	{
+		char *str; /* wow, used almost everywhere! */
+		struct pval *list; /* used in SWITCHES, ESWITCHES, INCLUDES, STATEMENTBLOCK, GOTO */
+		struct pval *statements;/*  used in EXTENSION */
+		char *for_init;  /* used in FOR */
+	} u1;
+	struct pval *u1_last; /* to build in-order lists -- looks like we only need one */
+	
+	union
+	{
+		struct pval *arglist; /* used in macro_call, application_call, MACRO def, also attached to PWORD, the 4 timevals for includes  */
+		struct pval *statements; /* used in case, default, catch, while's statement, CONTEXT elements, GLOBALS */
+		char *val;  /* used in VARDEC */
+		char *for_test; /* used in FOR */
+		
+	} u2;
+	
+	union
+	{
+		char *for_inc; /* used in FOR */
+		struct pval *else_statements; /* used in IF */
+		struct pval *macro_statements; /* used in MACRO */
+		int abstract;  /* used for context */
+		char *hints; /* used in EXTENSION */
+	} u3;
+	
+	union
+	{
+		struct pval *for_statements; /* used in PV_FOR */
+		int regexten;                /* used in EXTENSION */
+	} u4;
+	
+	
+	struct pval *next; /* the pval at the end of this ptr will ALWAYS be of the same type as this one! 
+						  EXCEPT for objects of the different types, that are in the same list, like contexts & macros, etc */
+	
+	
+} ;
+
+
+typedef struct pval pval;
+
+pval *npval(pvaltype type, int first_line, int last_line, int first_column, int last_column);
+void linku1(pval *head, pval *tail);
+void print_pval_list(FILE *f, pval *item, int depth);
+void print_pval(FILE *f, pval *item, int depth);
+void ael2_semantic_check(pval *item, int *errs, int *warns, int *notes);
+struct pval *find_label_in_current_context(char *exten, char *label);
+struct pval *find_label_in_current_extension(char *label);
+int count_labels_in_current_context(char *label);
+struct pval *find_label_in_current_db(char *context, char *exten, char *label);
+struct pval *ael2_parse(char *fname, int *errs);
+void destroy_pval(pval *item);
+void ael2_print(char *fname, pval *tree);
+#ifndef YY_TYPEDEF_YY_SCANNER_T
+#define YY_TYPEDEF_YY_SCANNER_T
+typedef void* yyscan_t;
+#endif
+
+/* for passing info into and out of yyparse */
+struct parse_io
+{
+	struct pval *pval; /* yyparse will set this to point to the parse tree */
+	yyscan_t scanner;       /* yylex needs a scanner. Set it up, and pass it in */
+	int syntax_error_count;  /* the count of syntax errors encountered */
+};
+
+/* for CODE GENERATION */
+	
+typedef enum { AEL_APPCALL, AEL_CONTROL1, AEL_FOR_CONTROL, AEL_IF_CONTROL, AEL_IFTIME_CONTROL, AEL_RAND_CONTROL, AEL_LABEL, AEL_RETURN } ael_priority_type;
+
+
+struct ael_priority
+{
+	int priority_num;
+	ael_priority_type type;
+	
+	char *app;
+	char *appargs;
+	
+	struct pval *origin;
+	struct ael_extension *exten;
+	
+	struct ael_priority *goto_true;
+	struct ael_priority *goto_false;
+	struct ael_priority *next;
+};
+
+struct ael_extension
+{
+	char *name;
+	char *hints;
+	int regexten;
+	
+	struct ael_priority *plist;
+	struct ael_priority *plist_last;
+	struct ael_extension *next_exten;
+
+	struct ael_priority *loop_break;  /* set by latest loop for breaks */
+	struct ael_priority *loop_continue; /* set by lastest loop for continuing */
+	struct ael_priority *return_target;
+	int return_needed;
+};
+
+
diff --git a/mxml/configure b/mxml/configure
index bd4aaedc67..3a725707fd 100755
--- a/mxml/configure
+++ b/mxml/configure
@@ -1,9 +1,8 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.57.
+# Generated by GNU Autoconf 2.59.
 #
-# Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002
-# Free Software Foundation, Inc.
+# Copyright (C) 2003 Free Software Foundation, Inc.
 # This configure script is free software; the Free Software Foundation
 # gives unlimited permission to copy, distribute and modify it.
 ## --------------------- ##
@@ -20,9 +19,10 @@ if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
 elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then
   set -o posix
 fi
+DUALCASE=1; export DUALCASE # for MKS sh
 
 # Support unset when possible.
-if (FOO=FOO; unset FOO) >/dev/null 2>&1; then
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
   as_unset=unset
 else
   as_unset=false
@@ -41,7 +41,7 @@ for as_var in \
   LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \
   LC_TELEPHONE LC_TIME
 do
-  if (set +x; test -n "`(eval $as_var=C; export $as_var) 2>&1`"); then
+  if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then
     eval $as_var=C; export $as_var
   else
     $as_unset $as_var
@@ -218,16 +218,17 @@ rm -f conf$$ conf$$.exe conf$$.file
 if mkdir -p . 2>/dev/null; then
   as_mkdir_p=:
 else
+  test -d ./-p && rmdir ./-p
   as_mkdir_p=false
 fi
 
 as_executable_p="test -f"
 
 # Sed expression to map a string onto a valid CPP name.
-as_tr_cpp="sed y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g"
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
 
 # Sed expression to map a string onto a valid variable name.
-as_tr_sh="sed y%*+%pp%;s%[^_$as_cr_alnum]%_%g"
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
 
 
 # IFS
@@ -630,7 +631,7 @@ done
 
 # Be sure to have absolute paths.
 for ac_var in bindir sbindir libexecdir datadir sysconfdir sharedstatedir \
-              localstatedir libdir includedir oldincludedir infodir mandir
+	      localstatedir libdir includedir oldincludedir infodir mandir
 do
   eval ac_val=$`echo $ac_var`
   case $ac_val in
@@ -670,10 +671,10 @@ if test -z "$srcdir"; then
   # Try the directory containing this script, then its parent.
   ac_confdir=`(dirname "$0") 2>/dev/null ||
 $as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
-         X"$0" : 'X\(//\)[^/]' \| \
-         X"$0" : 'X\(//\)$' \| \
-         X"$0" : 'X\(/\)' \| \
-         .     : '\(.\)' 2>/dev/null ||
+	 X"$0" : 'X\(//\)[^/]' \| \
+	 X"$0" : 'X\(//\)$' \| \
+	 X"$0" : 'X\(/\)' \| \
+	 .     : '\(.\)' 2>/dev/null ||
 echo X"$0" |
     sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
   	  /^X\(\/\/\)[^/].*/{ s//\1/; q; }
@@ -769,9 +770,9 @@ _ACEOF
   cat <<_ACEOF
 Installation directories:
   --prefix=PREFIX         install architecture-independent files in PREFIX
-                          [$ac_default_prefix]
+			  [$ac_default_prefix]
   --exec-prefix=EPREFIX   install architecture-dependent files in EPREFIX
-                          [PREFIX]
+			  [PREFIX]
 
 By default, \`make install' will install all the files in
 \`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc.  You can specify
@@ -862,12 +863,45 @@ case $srcdir in
     ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix
     ac_top_srcdir=$ac_top_builddir$srcdir ;;
 esac
-# Don't blindly perform a `cd "$ac_dir"/$ac_foo && pwd` since $ac_foo can be
-# absolute.
-ac_abs_builddir=`cd "$ac_dir" && cd $ac_builddir && pwd`
-ac_abs_top_builddir=`cd "$ac_dir" && cd ${ac_top_builddir}. && pwd`
-ac_abs_srcdir=`cd "$ac_dir" && cd $ac_srcdir && pwd`
-ac_abs_top_srcdir=`cd "$ac_dir" && cd $ac_top_srcdir && pwd`
+
+# Do not use `cd foo && pwd` to compute absolute paths, because
+# the directories may not exist.
+case `pwd` in
+.) ac_abs_builddir="$ac_dir";;
+*)
+  case "$ac_dir" in
+  .) ac_abs_builddir=`pwd`;;
+  [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";;
+  *) ac_abs_builddir=`pwd`/"$ac_dir";;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_builddir=${ac_top_builddir}.;;
+*)
+  case ${ac_top_builddir}. in
+  .) ac_abs_top_builddir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;;
+  *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_srcdir=$ac_srcdir;;
+*)
+  case $ac_srcdir in
+  .) ac_abs_srcdir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;;
+  *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_srcdir=$ac_top_srcdir;;
+*)
+  case $ac_top_srcdir in
+  .) ac_abs_top_srcdir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;;
+  *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;;
+  esac;;
+esac
 
     cd $ac_dir
     # Check for guested configure; otherwise get Cygnus style configure.
@@ -878,13 +912,13 @@ ac_abs_top_srcdir=`cd "$ac_dir" && cd $ac_top_srcdir && pwd`
       echo
       $SHELL $ac_srcdir/configure  --help=recursive
     elif test -f $ac_srcdir/configure.ac ||
-           test -f $ac_srcdir/configure.in; then
+	   test -f $ac_srcdir/configure.in; then
       echo
       $ac_configure --help
     else
       echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
     fi
-    cd $ac_popdir
+    cd "$ac_popdir"
   done
 fi
 
@@ -892,8 +926,7 @@ test -n "$ac_init_help" && exit 0
 if $ac_init_version; then
   cat <<\_ACEOF
 
-Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002
-Free Software Foundation, Inc.
+Copyright (C) 2003 Free Software Foundation, Inc.
 This configure script is free software; the Free Software Foundation
 gives unlimited permission to copy, distribute and modify it.
 _ACEOF
@@ -905,7 +938,7 @@ This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
 It was created by $as_me, which was
-generated by GNU Autoconf 2.57.  Invocation command line was
+generated by GNU Autoconf 2.59.  Invocation command line was
 
   $ $0 $@
 
@@ -982,19 +1015,19 @@ do
     2)
       ac_configure_args1="$ac_configure_args1 '$ac_arg'"
       if test $ac_must_keep_next = true; then
-        ac_must_keep_next=false # Got value, back to normal.
+	ac_must_keep_next=false # Got value, back to normal.
       else
-        case $ac_arg in
-          *=* | --config-cache | -C | -disable-* | --disable-* \
-          | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \
-          | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \
-          | -with-* | --with-* | -without-* | --without-* | --x)
-            case "$ac_configure_args0 " in
-              "$ac_configure_args1"*" '$ac_arg' "* ) continue ;;
-            esac
-            ;;
-          -* ) ac_must_keep_next=true ;;
-        esac
+	case $ac_arg in
+	  *=* | --config-cache | -C | -disable-* | --disable-* \
+	  | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \
+	  | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \
+	  | -with-* | --with-* | -without-* | --without-* | --x)
+	    case "$ac_configure_args0 " in
+	      "$ac_configure_args1"*" '$ac_arg' "* ) continue ;;
+	    esac
+	    ;;
+	  -* ) ac_must_keep_next=true ;;
+	esac
       fi
       ac_configure_args="$ac_configure_args$ac_sep'$ac_arg'"
       # Get rid of the leading space.
@@ -1028,12 +1061,12 @@ _ASBOX
     case `(ac_space='"'"' '"'"'; set | grep ac_space) 2>&1` in
     *ac_space=\ *)
       sed -n \
-        "s/'"'"'/'"'"'\\\\'"'"''"'"'/g;
-    	  s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='"'"'\\2'"'"'/p"
+	"s/'"'"'/'"'"'\\\\'"'"''"'"'/g;
+	  s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='"'"'\\2'"'"'/p"
       ;;
     *)
       sed -n \
-        "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p"
+	"s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p"
       ;;
     esac;
 }
@@ -1062,7 +1095,7 @@ _ASBOX
       for ac_var in $ac_subst_files
       do
 	eval ac_val=$`echo $ac_var`
-        echo "$ac_var='"'"'$ac_val'"'"'"
+	echo "$ac_var='"'"'$ac_val'"'"'"
       done | sort
       echo
     fi
@@ -1081,7 +1114,7 @@ _ASBOX
       echo "$as_me: caught signal $ac_signal"
     echo "$as_me: exit $exit_status"
   } >&5
-  rm -f core core.* *.core &&
+  rm -f core *.core &&
   rm -rf conftest* confdefs* conf$$* $ac_clean_files &&
     exit $exit_status
      ' 0
@@ -1161,7 +1194,7 @@ fi
 # value.
 ac_cache_corrupted=false
 for ac_var in `(set) 2>&1 |
-               sed -n 's/^ac_env_\([a-zA-Z_0-9]*\)_set=.*/\1/p'`; do
+	       sed -n 's/^ac_env_\([a-zA-Z_0-9]*\)_set=.*/\1/p'`; do
   eval ac_old_set=\$ac_cv_env_${ac_var}_set
   eval ac_new_set=\$ac_env_${ac_var}_set
   eval ac_old_val="\$ac_cv_env_${ac_var}_value"
@@ -1178,13 +1211,13 @@ echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
     ,);;
     *)
       if test "x$ac_old_val" != "x$ac_new_val"; then
-        { echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5
+	{ echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5
 echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
-        { echo "$as_me:$LINENO:   former value:  $ac_old_val" >&5
+	{ echo "$as_me:$LINENO:   former value:  $ac_old_val" >&5
 echo "$as_me:   former value:  $ac_old_val" >&2;}
-        { echo "$as_me:$LINENO:   current value: $ac_new_val" >&5
+	{ echo "$as_me:$LINENO:   current value: $ac_new_val" >&5
 echo "$as_me:   current value: $ac_new_val" >&2;}
-        ac_cache_corrupted=:
+	ac_cache_corrupted=:
       fi;;
   esac
   # Pass precious variables to config.status.
@@ -1631,7 +1664,6 @@ ac_compiler=`set X $ac_compile; echo $2`
   (exit $ac_status); }
 
 cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
 /* confdefs.h.  */
 _ACEOF
 cat confdefs.h >>conftest.$ac_ext
@@ -1651,8 +1683,8 @@ ac_clean_files="$ac_clean_files a.out a.exe b.out"
 # Try to create an executable without -o first, disregard a.out.
 # It will help us diagnose broken compilers, and finding out an intuition
 # of exeext.
-echo "$as_me:$LINENO: checking for C compiler default output" >&5
-echo $ECHO_N "checking for C compiler default output... $ECHO_C" >&6
+echo "$as_me:$LINENO: checking for C compiler default output file name" >&5
+echo $ECHO_N "checking for C compiler default output file name... $ECHO_C" >&6
 ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
 if { (eval echo "$as_me:$LINENO: \"$ac_link_default\"") >&5
   (eval $ac_link_default) 2>&5
@@ -1672,23 +1704,23 @@ do
   test -f "$ac_file" || continue
   case $ac_file in
     *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj )
-        ;;
+	;;
     conftest.$ac_ext )
-        # This is the source file.
-        ;;
+	# This is the source file.
+	;;
     [ab].out )
-        # We found the default executable, but exeext='' is most
-        # certainly right.
-        break;;
+	# We found the default executable, but exeext='' is most
+	# certainly right.
+	break;;
     *.* )
-        ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
-        # FIXME: I believe we export ac_cv_exeext for Libtool,
-        # but it would be cool to find out if it's true.  Does anybody
-        # maintain Libtool? --akim.
-        export ac_cv_exeext
-        break;;
+	ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+	# FIXME: I believe we export ac_cv_exeext for Libtool,
+	# but it would be cool to find out if it's true.  Does anybody
+	# maintain Libtool? --akim.
+	export ac_cv_exeext
+	break;;
     * )
-        break;;
+	break;;
   esac
 done
 else
@@ -1762,8 +1794,8 @@ for ac_file in conftest.exe conftest conftest.*; do
   case $ac_file in
     *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) ;;
     *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
-          export ac_cv_exeext
-          break;;
+	  export ac_cv_exeext
+	  break;;
     * ) break;;
   esac
 done
@@ -1788,7 +1820,6 @@ if test "${ac_cv_objext+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
   cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
 /* confdefs.h.  */
 _ACEOF
 cat confdefs.h >>conftest.$ac_ext
@@ -1839,7 +1870,6 @@ if test "${ac_cv_c_compiler_gnu+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
   cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
 /* confdefs.h.  */
 _ACEOF
 cat confdefs.h >>conftest.$ac_ext
@@ -1859,11 +1889,20 @@ main ()
 _ACEOF
 rm -f conftest.$ac_objext
 if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
-  (eval $ac_compile) 2>&5
+  (eval $ac_compile) 2>conftest.er1
   ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-         { ac_try='test -s conftest.$ac_objext'
+	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -1876,7 +1915,7 @@ sed 's/^/| /' conftest.$ac_ext >&5
 
 ac_compiler_gnu=no
 fi
-rm -f conftest.$ac_objext conftest.$ac_ext
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
 ac_cv_c_compiler_gnu=$ac_compiler_gnu
 
 fi
@@ -1892,7 +1931,6 @@ if test "${ac_cv_prog_cc_g+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
   cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
 /* confdefs.h.  */
 _ACEOF
 cat confdefs.h >>conftest.$ac_ext
@@ -1909,11 +1947,20 @@ main ()
 _ACEOF
 rm -f conftest.$ac_objext
 if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
-  (eval $ac_compile) 2>&5
+  (eval $ac_compile) 2>conftest.er1
   ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-         { ac_try='test -s conftest.$ac_objext'
+	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -1926,7 +1973,7 @@ sed 's/^/| /' conftest.$ac_ext >&5
 
 ac_cv_prog_cc_g=no
 fi
-rm -f conftest.$ac_objext conftest.$ac_ext
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
 fi
 echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5
 echo "${ECHO_T}$ac_cv_prog_cc_g" >&6
@@ -1953,7 +2000,6 @@ else
   ac_cv_prog_cc_stdc=no
 ac_save_CC=$CC
 cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
 /* confdefs.h.  */
 _ACEOF
 cat confdefs.h >>conftest.$ac_ext
@@ -1981,6 +2027,16 @@ static char *f (char * (*g) (char **, int), char **p, ...)
   va_end (v);
   return s;
 }
+
+/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default.  It has
+   function prototypes and stuff, but not '\xHH' hex character constants.
+   These don't provoke an error unfortunately, instead are silently treated
+   as 'x'.  The following induces an error, until -std1 is added to get
+   proper ANSI mode.  Curiously '\x00'!='x' always comes out true, for an
+   array size at least.  It's necessary to write '\x00'==0 to get something
+   that's true only with -std1.  */
+int osf4_cc_array ['\x00' == 0 ? 1 : -1];
+
 int test (int i, double x);
 struct s1 {int (*f) (int a);};
 struct s2 {int (*f) (double a);};
@@ -2007,11 +2063,20 @@ do
   CC="$ac_save_CC $ac_arg"
   rm -f conftest.$ac_objext
 if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
-  (eval $ac_compile) 2>&5
+  (eval $ac_compile) 2>conftest.er1
   ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-         { ac_try='test -s conftest.$ac_objext'
+	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2024,7 +2089,7 @@ else
 sed 's/^/| /' conftest.$ac_ext >&5
 
 fi
-rm -f conftest.$ac_objext
+rm -f conftest.err conftest.$ac_objext
 done
 rm -f conftest.$ac_ext conftest.$ac_objext
 CC=$ac_save_CC
@@ -2052,19 +2117,27 @@ cat >conftest.$ac_ext <<_ACEOF
 _ACEOF
 rm -f conftest.$ac_objext
 if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
-  (eval $ac_compile) 2>&5
+  (eval $ac_compile) 2>conftest.er1
   ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-         { ac_try='test -s conftest.$ac_objext'
+	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
   for ac_declaration in \
-   ''\
-   '#include <stdlib.h>' \
+   '' \
    'extern "C" void std::exit (int) throw (); using std::exit;' \
    'extern "C" void std::exit (int); using std::exit;' \
    'extern "C" void exit (int) throw ();' \
@@ -2072,14 +2145,13 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
    'void exit (int);'
 do
   cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
 /* confdefs.h.  */
 _ACEOF
 cat confdefs.h >>conftest.$ac_ext
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
-#include <stdlib.h>
 $ac_declaration
+#include <stdlib.h>
 int
 main ()
 {
@@ -2090,11 +2162,20 @@ exit (42);
 _ACEOF
 rm -f conftest.$ac_objext
 if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
-  (eval $ac_compile) 2>&5
+  (eval $ac_compile) 2>conftest.er1
   ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-         { ac_try='test -s conftest.$ac_objext'
+	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2107,9 +2188,8 @@ sed 's/^/| /' conftest.$ac_ext >&5
 
 continue
 fi
-rm -f conftest.$ac_objext conftest.$ac_ext
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
   cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
 /* confdefs.h.  */
 _ACEOF
 cat confdefs.h >>conftest.$ac_ext
@@ -2126,11 +2206,20 @@ exit (42);
 _ACEOF
 rm -f conftest.$ac_objext
 if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
-  (eval $ac_compile) 2>&5
+  (eval $ac_compile) 2>conftest.er1
   ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-         { ac_try='test -s conftest.$ac_objext'
+	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2142,7 +2231,7 @@ else
 sed 's/^/| /' conftest.$ac_ext >&5
 
 fi
-rm -f conftest.$ac_objext conftest.$ac_ext
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
 done
 rm -f conftest*
 if test -n "$ac_declaration"; then
@@ -2156,7 +2245,7 @@ else
 sed 's/^/| /' conftest.$ac_ext >&5
 
 fi
-rm -f conftest.$ac_objext conftest.$ac_ext
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
 ac_ext=c
 ac_cpp='$CPP $CPPFLAGS'
 ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
@@ -2282,7 +2371,6 @@ if test "${ac_cv_cxx_compiler_gnu+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
   cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
 /* confdefs.h.  */
 _ACEOF
 cat confdefs.h >>conftest.$ac_ext
@@ -2302,11 +2390,20 @@ main ()
 _ACEOF
 rm -f conftest.$ac_objext
 if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
-  (eval $ac_compile) 2>&5
+  (eval $ac_compile) 2>conftest.er1
   ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-         { ac_try='test -s conftest.$ac_objext'
+	 { ac_try='test -z "$ac_cxx_werror_flag"			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2319,7 +2416,7 @@ sed 's/^/| /' conftest.$ac_ext >&5
 
 ac_compiler_gnu=no
 fi
-rm -f conftest.$ac_objext conftest.$ac_ext
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
 ac_cv_cxx_compiler_gnu=$ac_compiler_gnu
 
 fi
@@ -2335,7 +2432,6 @@ if test "${ac_cv_prog_cxx_g+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
   cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
 /* confdefs.h.  */
 _ACEOF
 cat confdefs.h >>conftest.$ac_ext
@@ -2352,11 +2448,20 @@ main ()
 _ACEOF
 rm -f conftest.$ac_objext
 if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
-  (eval $ac_compile) 2>&5
+  (eval $ac_compile) 2>conftest.er1
   ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-         { ac_try='test -s conftest.$ac_objext'
+	 { ac_try='test -z "$ac_cxx_werror_flag"			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2369,7 +2474,7 @@ sed 's/^/| /' conftest.$ac_ext >&5
 
 ac_cv_prog_cxx_g=no
 fi
-rm -f conftest.$ac_objext conftest.$ac_ext
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
 fi
 echo "$as_me:$LINENO: result: $ac_cv_prog_cxx_g" >&5
 echo "${ECHO_T}$ac_cv_prog_cxx_g" >&6
@@ -2389,8 +2494,7 @@ else
   fi
 fi
 for ac_declaration in \
-   ''\
-   '#include <stdlib.h>' \
+   '' \
    'extern "C" void std::exit (int) throw (); using std::exit;' \
    'extern "C" void std::exit (int); using std::exit;' \
    'extern "C" void exit (int) throw ();' \
@@ -2398,14 +2502,13 @@ for ac_declaration in \
    'void exit (int);'
 do
   cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
 /* confdefs.h.  */
 _ACEOF
 cat confdefs.h >>conftest.$ac_ext
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
-#include <stdlib.h>
 $ac_declaration
+#include <stdlib.h>
 int
 main ()
 {
@@ -2416,11 +2519,20 @@ exit (42);
 _ACEOF
 rm -f conftest.$ac_objext
 if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
-  (eval $ac_compile) 2>&5
+  (eval $ac_compile) 2>conftest.er1
   ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-         { ac_try='test -s conftest.$ac_objext'
+	 { ac_try='test -z "$ac_cxx_werror_flag"			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2433,9 +2545,8 @@ sed 's/^/| /' conftest.$ac_ext >&5
 
 continue
 fi
-rm -f conftest.$ac_objext conftest.$ac_ext
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
   cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
 /* confdefs.h.  */
 _ACEOF
 cat confdefs.h >>conftest.$ac_ext
@@ -2452,11 +2563,20 @@ exit (42);
 _ACEOF
 rm -f conftest.$ac_objext
 if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
-  (eval $ac_compile) 2>&5
+  (eval $ac_compile) 2>conftest.er1
   ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-         { ac_try='test -s conftest.$ac_objext'
+	 { ac_try='test -z "$ac_cxx_werror_flag"			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2468,7 +2588,7 @@ else
 sed 's/^/| /' conftest.$ac_ext >&5
 
 fi
-rm -f conftest.$ac_objext conftest.$ac_ext
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
 done
 rm -f conftest*
 if test -n "$ac_declaration"; then
@@ -2519,6 +2639,7 @@ ac_configure="$SHELL $ac_aux_dir/configure" # This should be Cygnus configure.
 # AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
 # AFS /usr/afsws/bin/install, which mishandles nonexistent args
 # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# OS/2's system install, which has a completely different semantic
 # ./install, which can be erroneously created by make from ./install.sh.
 echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5
 echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6
@@ -2535,6 +2656,7 @@ do
 case $as_dir/ in
   ./ | .// | /cC/* | \
   /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \
+  ?:\\/os2\\/install\\/* | ?:\\/OS2\\/INSTALL\\/* | \
   /usr/ucb/* ) ;;
   *)
     # OSF1 and SCO ODT 3.0 have their own names for install.
@@ -2542,20 +2664,20 @@ case $as_dir/ in
     # by default.
     for ac_prog in ginstall scoinst install; do
       for ac_exec_ext in '' $ac_executable_extensions; do
-        if $as_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then
-          if test $ac_prog = install &&
-            grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
-            # AIX install.  It has an incompatible calling convention.
-            :
-          elif test $ac_prog = install &&
-            grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
-            # program-specific install script used by HP pwplus--don't use.
-            :
-          else
-            ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c"
-            break 3
-          fi
-        fi
+	if $as_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then
+	  if test $ac_prog = install &&
+	    grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+	    # AIX install.  It has an incompatible calling convention.
+	    :
+	  elif test $ac_prog = install &&
+	    grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+	    # program-specific install script used by HP pwplus--don't use.
+	    :
+	  else
+	    ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c"
+	    break 3
+	  fi
+	fi
       done
     done
     ;;
@@ -2973,21 +3095,28 @@ if eval "test \"\${$as_ac_var+set}\" = set"; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
   cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
 /* confdefs.h.  */
 _ACEOF
 cat confdefs.h >>conftest.$ac_ext
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define $ac_func innocuous_$ac_func
+
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func (); below.
     Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
     <limits.h> exists even on freestanding compilers.  */
+
 #ifdef __STDC__
 # include <limits.h>
 #else
 # include <assert.h>
 #endif
+
+#undef $ac_func
+
 /* Override any gcc2 internal prototype to avoid an error.  */
 #ifdef __cplusplus
 extern "C"
@@ -3018,11 +3147,20 @@ return f != $ac_func;
 _ACEOF
 rm -f conftest.$ac_objext conftest$ac_exeext
 if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
-  (eval $ac_link) 2>&5
+  (eval $ac_link) 2>conftest.er1
   ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-         { ac_try='test -s conftest$ac_exeext'
+	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -3035,7 +3173,8 @@ sed 's/^/| /' conftest.$ac_ext >&5
 
 eval "$as_ac_var=no"
 fi
-rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
 fi
 echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
 echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
@@ -3060,21 +3199,28 @@ if eval "test \"\${$as_ac_var+set}\" = set"; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
   cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
 /* confdefs.h.  */
 _ACEOF
 cat confdefs.h >>conftest.$ac_ext
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define $ac_func innocuous_$ac_func
+
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func (); below.
     Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
     <limits.h> exists even on freestanding compilers.  */
+
 #ifdef __STDC__
 # include <limits.h>
 #else
 # include <assert.h>
 #endif
+
+#undef $ac_func
+
 /* Override any gcc2 internal prototype to avoid an error.  */
 #ifdef __cplusplus
 extern "C"
@@ -3105,11 +3251,20 @@ return f != $ac_func;
 _ACEOF
 rm -f conftest.$ac_objext conftest$ac_exeext
 if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
-  (eval $ac_link) 2>&5
+  (eval $ac_link) 2>conftest.er1
   ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-         { ac_try='test -s conftest$ac_exeext'
+	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -3122,7 +3277,8 @@ sed 's/^/| /' conftest.$ac_ext >&5
 
 eval "$as_ac_var=no"
 fi
-rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
 fi
 echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
 echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
@@ -3346,13 +3502,13 @@ _ACEOF
       # `set' does not quote correctly, so add quotes (double-quote
       # substitution turns \\\\ into \\, and sed turns \\ into \).
       sed -n \
-        "s/'/'\\\\''/g;
-    	  s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
+	"s/'/'\\\\''/g;
+	  s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
       ;;
     *)
       # `set' quotes correctly as required by POSIX, so do not add quotes.
       sed -n \
-        "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p"
+	"s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p"
       ;;
     esac;
 } |
@@ -3382,13 +3538,13 @@ test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
 # trailing colons and then remove the whole line if VPATH becomes empty
 # (actually we leave an empty line to preserve line numbers).
 if test "x$srcdir" = x.; then
-  ac_vpsub='/^[ 	]*VPATH[ 	]*=/{
+  ac_vpsub='/^[	 ]*VPATH[	 ]*=/{
 s/:*\$(srcdir):*/:/;
 s/:*\${srcdir}:*/:/;
 s/:*@srcdir@:*/:/;
-s/^\([^=]*=[ 	]*\):*/\1/;
+s/^\([^=]*=[	 ]*\):*/\1/;
 s/:*$//;
-s/^[^=]*=[ 	]*$//;
+s/^[^=]*=[	 ]*$//;
 }'
 fi
 
@@ -3399,7 +3555,7 @@ ac_ltlibobjs=
 for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
   # 1. Remove the extension, and $U if already installed.
   ac_i=`echo "$ac_i" |
-         sed 's/\$U\././;s/\.o$//;s/\.obj$//'`
+	 sed 's/\$U\././;s/\.o$//;s/\.obj$//'`
   # 2. Add them.
   ac_libobjs="$ac_libobjs $ac_i\$U.$ac_objext"
   ac_ltlibobjs="$ac_ltlibobjs $ac_i"'$U.lo'
@@ -3443,9 +3599,10 @@ if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
 elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then
   set -o posix
 fi
+DUALCASE=1; export DUALCASE # for MKS sh
 
 # Support unset when possible.
-if (FOO=FOO; unset FOO) >/dev/null 2>&1; then
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
   as_unset=unset
 else
   as_unset=false
@@ -3464,7 +3621,7 @@ for as_var in \
   LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \
   LC_TELEPHONE LC_TIME
 do
-  if (set +x; test -n "`(eval $as_var=C; export $as_var) 2>&1`"); then
+  if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then
     eval $as_var=C; export $as_var
   else
     $as_unset $as_var
@@ -3643,16 +3800,17 @@ rm -f conf$$ conf$$.exe conf$$.file
 if mkdir -p . 2>/dev/null; then
   as_mkdir_p=:
 else
+  test -d ./-p && rmdir ./-p
   as_mkdir_p=false
 fi
 
 as_executable_p="test -f"
 
 # Sed expression to map a string onto a valid CPP name.
-as_tr_cpp="sed y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g"
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
 
 # Sed expression to map a string onto a valid variable name.
-as_tr_sh="sed y%*+%pp%;s%[^_$as_cr_alnum]%_%g"
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
 
 
 # IFS
@@ -3679,7 +3837,7 @@ _ASBOX
 cat >&5 <<_CSEOF
 
 This file was extended by $as_me, which was
-generated by GNU Autoconf 2.57.  Invocation command line was
+generated by GNU Autoconf 2.59.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
   CONFIG_HEADERS  = $CONFIG_HEADERS
@@ -3723,9 +3881,9 @@ Usage: $0 [OPTIONS] [FILE]...
   -d, --debug      don't remove temporary files
       --recheck    update $as_me by reconfiguring in the same conditions
   --file=FILE[:TEMPLATE]
-                   instantiate the configuration file FILE
+		   instantiate the configuration file FILE
   --header=FILE[:TEMPLATE]
-                   instantiate the configuration header FILE
+		   instantiate the configuration header FILE
 
 Configuration files:
 $config_files
@@ -3739,11 +3897,10 @@ _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF
 ac_cs_version="\\
 config.status
-configured by $0, generated by GNU Autoconf 2.57,
+configured by $0, generated by GNU Autoconf 2.59,
   with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\"
 
-Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001
-Free Software Foundation, Inc.
+Copyright (C) 2003 Free Software Foundation, Inc.
 This config.status script is free software; the Free Software Foundation
 gives unlimited permission to copy, distribute and modify it."
 srcdir=$srcdir
@@ -3997,9 +4154,9 @@ _ACEOF
       (echo ':t
   /@[a-zA-Z_][a-zA-Z_0-9]*@/!b' && cat $tmp/subs.frag) >$tmp/subs-$ac_sed_frag.sed
       if test -z "$ac_sed_cmds"; then
-  	ac_sed_cmds="sed -f $tmp/subs-$ac_sed_frag.sed"
+	ac_sed_cmds="sed -f $tmp/subs-$ac_sed_frag.sed"
       else
-  	ac_sed_cmds="$ac_sed_cmds | sed -f $tmp/subs-$ac_sed_frag.sed"
+	ac_sed_cmds="$ac_sed_cmds | sed -f $tmp/subs-$ac_sed_frag.sed"
       fi
       ac_sed_frag=`expr $ac_sed_frag + 1`
       ac_beg=$ac_end
@@ -4017,21 +4174,21 @@ for ac_file in : $CONFIG_FILES; do test "x$ac_file" = x: && continue
   # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
   case $ac_file in
   - | *:- | *:-:* ) # input from stdin
-        cat >$tmp/stdin
-        ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
-        ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+	cat >$tmp/stdin
+	ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+	ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
   *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
-        ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+	ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
   * )   ac_file_in=$ac_file.in ;;
   esac
 
   # Compute @srcdir@, @top_srcdir@, and @INSTALL@ for subdirectories.
   ac_dir=`(dirname "$ac_file") 2>/dev/null ||
 $as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
-         X"$ac_file" : 'X\(//\)[^/]' \| \
-         X"$ac_file" : 'X\(//\)$' \| \
-         X"$ac_file" : 'X\(/\)' \| \
-         .     : '\(.\)' 2>/dev/null ||
+	 X"$ac_file" : 'X\(//\)[^/]' \| \
+	 X"$ac_file" : 'X\(//\)$' \| \
+	 X"$ac_file" : 'X\(/\)' \| \
+	 .     : '\(.\)' 2>/dev/null ||
 echo X"$ac_file" |
     sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
   	  /^X\(\/\/\)[^/].*/{ s//\1/; q; }
@@ -4047,10 +4204,10 @@ echo X"$ac_file" |
       as_dirs="$as_dir $as_dirs"
       as_dir=`(dirname "$as_dir") 2>/dev/null ||
 $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
-         X"$as_dir" : 'X\(//\)[^/]' \| \
-         X"$as_dir" : 'X\(//\)$' \| \
-         X"$as_dir" : 'X\(/\)' \| \
-         .     : '\(.\)' 2>/dev/null ||
+	 X"$as_dir" : 'X\(//\)[^/]' \| \
+	 X"$as_dir" : 'X\(//\)$' \| \
+	 X"$as_dir" : 'X\(/\)' \| \
+	 .     : '\(.\)' 2>/dev/null ||
 echo X"$as_dir" |
     sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
   	  /^X\(\/\/\)[^/].*/{ s//\1/; q; }
@@ -4088,12 +4245,45 @@ case $srcdir in
     ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix
     ac_top_srcdir=$ac_top_builddir$srcdir ;;
 esac
-# Don't blindly perform a `cd "$ac_dir"/$ac_foo && pwd` since $ac_foo can be
-# absolute.
-ac_abs_builddir=`cd "$ac_dir" && cd $ac_builddir && pwd`
-ac_abs_top_builddir=`cd "$ac_dir" && cd ${ac_top_builddir}. && pwd`
-ac_abs_srcdir=`cd "$ac_dir" && cd $ac_srcdir && pwd`
-ac_abs_top_srcdir=`cd "$ac_dir" && cd $ac_top_srcdir && pwd`
+
+# Do not use `cd foo && pwd` to compute absolute paths, because
+# the directories may not exist.
+case `pwd` in
+.) ac_abs_builddir="$ac_dir";;
+*)
+  case "$ac_dir" in
+  .) ac_abs_builddir=`pwd`;;
+  [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";;
+  *) ac_abs_builddir=`pwd`/"$ac_dir";;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_builddir=${ac_top_builddir}.;;
+*)
+  case ${ac_top_builddir}. in
+  .) ac_abs_top_builddir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;;
+  *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_srcdir=$ac_srcdir;;
+*)
+  case $ac_srcdir in
+  .) ac_abs_srcdir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;;
+  *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_srcdir=$ac_top_srcdir;;
+*)
+  case $ac_top_srcdir in
+  .) ac_abs_top_srcdir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;;
+  *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;;
+  esac;;
+esac
 
 
   case $INSTALL in
@@ -4101,11 +4291,6 @@ ac_abs_top_srcdir=`cd "$ac_dir" && cd $ac_top_srcdir && pwd`
   *) ac_INSTALL=$ac_top_builddir$INSTALL ;;
   esac
 
-  if test x"$ac_file" != x-; then
-    { echo "$as_me:$LINENO: creating $ac_file" >&5
-echo "$as_me: creating $ac_file" >&6;}
-    rm -f "$ac_file"
-  fi
   # Let's still pretend it is `configure' which instantiates (i.e., don't
   # use $as_me), people would be surprised to read:
   #    /* config.h.  Generated by config.status.  */
@@ -4115,7 +4300,7 @@ echo "$as_me: creating $ac_file" >&6;}
     configure_input="$ac_file.  "
   fi
   configure_input=$configure_input"Generated from `echo $ac_file_in |
-                                     sed 's,.*/,,'` by configure."
+				     sed 's,.*/,,'` by configure."
 
   # First look for the input files in the build tree, otherwise in the
   # src tree.
@@ -4124,26 +4309,32 @@ echo "$as_me: creating $ac_file" >&6;}
       case $f in
       -) echo $tmp/stdin ;;
       [\\/$]*)
-         # Absolute (can't be DOS-style, as IFS=:)
-         test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+	 # Absolute (can't be DOS-style, as IFS=:)
+	 test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
 echo "$as_me: error: cannot find input file: $f" >&2;}
    { (exit 1); exit 1; }; }
-         echo $f;;
+	 echo "$f";;
       *) # Relative
-         if test -f "$f"; then
-           # Build tree
-           echo $f
-         elif test -f "$srcdir/$f"; then
-           # Source tree
-           echo $srcdir/$f
-         else
-           # /dev/null tree
-           { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+	 if test -f "$f"; then
+	   # Build tree
+	   echo "$f"
+	 elif test -f "$srcdir/$f"; then
+	   # Source tree
+	   echo "$srcdir/$f"
+	 else
+	   # /dev/null tree
+	   { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
 echo "$as_me: error: cannot find input file: $f" >&2;}
    { (exit 1); exit 1; }; }
-         fi;;
+	 fi;;
       esac
     done` || { (exit 1); exit 1; }
+
+  if test x"$ac_file" != x-; then
+    { echo "$as_me:$LINENO: creating $ac_file" >&5
+echo "$as_me: creating $ac_file" >&6;}
+    rm -f "$ac_file"
+  fi
 _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF
   sed "$ac_vpsub
@@ -4183,12 +4374,12 @@ cat >>$CONFIG_STATUS <<\_ACEOF
 # NAME is the cpp macro being defined and VALUE is the value it is being given.
 #
 # ac_d sets the value in "#define NAME VALUE" lines.
-ac_dA='s,^\([ 	]*\)#\([ 	]*define[ 	][ 	]*\)'
-ac_dB='[ 	].*$,\1#\2'
+ac_dA='s,^\([	 ]*\)#\([	 ]*define[	 ][	 ]*\)'
+ac_dB='[	 ].*$,\1#\2'
 ac_dC=' '
 ac_dD=',;t'
 # ac_u turns "#undef NAME" without trailing blanks into "#define NAME VALUE".
-ac_uA='s,^\([ 	]*\)#\([ 	]*\)undef\([ 	][ 	]*\)'
+ac_uA='s,^\([	 ]*\)#\([	 ]*\)undef\([	 ][	 ]*\)'
 ac_uB='$,\1#\2define\3'
 ac_uC=' '
 ac_uD=',;t'
@@ -4197,11 +4388,11 @@ for ac_file in : $CONFIG_HEADERS; do test "x$ac_file" = x: && continue
   # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
   case $ac_file in
   - | *:- | *:-:* ) # input from stdin
-        cat >$tmp/stdin
-        ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
-        ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+	cat >$tmp/stdin
+	ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+	ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
   *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
-        ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+	ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
   * )   ac_file_in=$ac_file.in ;;
   esac
 
@@ -4215,28 +4406,29 @@ echo "$as_me: creating $ac_file" >&6;}
       case $f in
       -) echo $tmp/stdin ;;
       [\\/$]*)
-         # Absolute (can't be DOS-style, as IFS=:)
-         test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+	 # Absolute (can't be DOS-style, as IFS=:)
+	 test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
 echo "$as_me: error: cannot find input file: $f" >&2;}
    { (exit 1); exit 1; }; }
-         echo $f;;
+	 # Do quote $f, to prevent DOS paths from being IFS'd.
+	 echo "$f";;
       *) # Relative
-         if test -f "$f"; then
-           # Build tree
-           echo $f
-         elif test -f "$srcdir/$f"; then
-           # Source tree
-           echo $srcdir/$f
-         else
-           # /dev/null tree
-           { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+	 if test -f "$f"; then
+	   # Build tree
+	   echo "$f"
+	 elif test -f "$srcdir/$f"; then
+	   # Source tree
+	   echo "$srcdir/$f"
+	 else
+	   # /dev/null tree
+	   { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
 echo "$as_me: error: cannot find input file: $f" >&2;}
    { (exit 1); exit 1; }; }
-         fi;;
+	 fi;;
       esac
     done` || { (exit 1); exit 1; }
   # Remove the trailing spaces.
-  sed 's/[ 	]*$//' $ac_file_inputs >$tmp/in
+  sed 's/[	 ]*$//' $ac_file_inputs >$tmp/in
 
 _ACEOF
 
@@ -4259,9 +4451,9 @@ s/[\\&,]/\\&/g
 s,[\\$`],\\&,g
 t clear
 : clear
-s,^[ 	]*#[ 	]*define[ 	][ 	]*\([^ 	(][^ 	(]*\)\(([^)]*)\)[ 	]*\(.*\)$,${ac_dA}\1${ac_dB}\1\2${ac_dC}\3${ac_dD},gp
+s,^[	 ]*#[	 ]*define[	 ][	 ]*\([^	 (][^	 (]*\)\(([^)]*)\)[	 ]*\(.*\)$,${ac_dA}\1${ac_dB}\1\2${ac_dC}\3${ac_dD},gp
 t end
-s,^[ 	]*#[ 	]*define[ 	][ 	]*\([^ 	][^ 	]*\)[ 	]*\(.*\)$,${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD},gp
+s,^[	 ]*#[	 ]*define[	 ][	 ]*\([^	 ][^	 ]*\)[	 ]*\(.*\)$,${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD},gp
 : end
 _ACEOF
 # If some macros were called several times there might be several times
@@ -4275,13 +4467,13 @@ rm -f confdef2sed.sed
 # example, in the case of _POSIX_SOURCE, which is predefined and required
 # on some systems where configure will not decide to define it.
 cat >>conftest.undefs <<\_ACEOF
-s,^[ 	]*#[ 	]*undef[ 	][ 	]*[a-zA-Z_][a-zA-Z_0-9]*,/* & */,
+s,^[	 ]*#[	 ]*undef[	 ][	 ]*[a-zA-Z_][a-zA-Z_0-9]*,/* & */,
 _ACEOF
 
 # Break up conftest.defines because some shells have a limit on the size
 # of here documents, and old seds have small limits too (100 cmds).
 echo '  # Handle all the #define templates only if necessary.' >>$CONFIG_STATUS
-echo '  if grep "^[ 	]*#[ 	]*define" $tmp/in >/dev/null; then' >>$CONFIG_STATUS
+echo '  if grep "^[	 ]*#[	 ]*define" $tmp/in >/dev/null; then' >>$CONFIG_STATUS
 echo '  # If there are no defines, we may have an empty if/fi' >>$CONFIG_STATUS
 echo '  :' >>$CONFIG_STATUS
 rm -f conftest.tail
@@ -4290,7 +4482,7 @@ do
   # Write a limited-size here document to $tmp/defines.sed.
   echo '  cat >$tmp/defines.sed <<CEOF' >>$CONFIG_STATUS
   # Speed up: don't consider the non `#define' lines.
-  echo '/^[ 	]*#[ 	]*define/!b' >>$CONFIG_STATUS
+  echo '/^[	 ]*#[	 ]*define/!b' >>$CONFIG_STATUS
   # Work around the forget-to-reset-the-flag bug.
   echo 't clr' >>$CONFIG_STATUS
   echo ': clr' >>$CONFIG_STATUS
@@ -4317,7 +4509,7 @@ do
   # Write a limited-size here document to $tmp/undefs.sed.
   echo '  cat >$tmp/undefs.sed <<CEOF' >>$CONFIG_STATUS
   # Speed up: don't consider the non `#undef'
-  echo '/^[ 	]*#[ 	]*undef/!b' >>$CONFIG_STATUS
+  echo '/^[	 ]*#[	 ]*undef/!b' >>$CONFIG_STATUS
   # Work around the forget-to-reset-the-flag bug.
   echo 't clr' >>$CONFIG_STATUS
   echo ': clr' >>$CONFIG_STATUS
@@ -4351,10 +4543,10 @@ echo "$as_me: $ac_file is unchanged" >&6;}
     else
       ac_dir=`(dirname "$ac_file") 2>/dev/null ||
 $as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
-         X"$ac_file" : 'X\(//\)[^/]' \| \
-         X"$ac_file" : 'X\(//\)$' \| \
-         X"$ac_file" : 'X\(/\)' \| \
-         .     : '\(.\)' 2>/dev/null ||
+	 X"$ac_file" : 'X\(//\)[^/]' \| \
+	 X"$ac_file" : 'X\(//\)$' \| \
+	 X"$ac_file" : 'X\(/\)' \| \
+	 .     : '\(.\)' 2>/dev/null ||
 echo X"$ac_file" |
     sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
   	  /^X\(\/\/\)[^/].*/{ s//\1/; q; }
@@ -4370,10 +4562,10 @@ echo X"$ac_file" |
       as_dirs="$as_dir $as_dirs"
       as_dir=`(dirname "$as_dir") 2>/dev/null ||
 $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
-         X"$as_dir" : 'X\(//\)[^/]' \| \
-         X"$as_dir" : 'X\(//\)$' \| \
-         X"$as_dir" : 'X\(/\)' \| \
-         .     : '\(.\)' 2>/dev/null ||
+	 X"$as_dir" : 'X\(//\)[^/]' \| \
+	 X"$as_dir" : 'X\(//\)$' \| \
+	 X"$as_dir" : 'X\(/\)' \| \
+	 .     : '\(.\)' 2>/dev/null ||
 echo X"$as_dir" |
     sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
   	  /^X\(\/\/\)[^/].*/{ s//\1/; q; }
diff --git a/pbx/Makefile b/pbx/Makefile
index 60b965c292..99846a23da 100644
--- a/pbx/Makefile
+++ b/pbx/Makefile
@@ -48,6 +48,23 @@ pbx_dundi.so: pbx_dundi.o dundi-parser.o
 pbx_dundi.o: pbx_dundi.c
 	$(CC) -c -o $@ $(CFLAGS) $(Z_INCLUDE) $<
 
+pbx_ael.o: ael/aelflex.o ael/aelbison.o ../include/asterisk/ael_structs.h
+
+pbx_ael.so: pbx_ael.o ael/aelbison.o ael/aelflex.o
+	$(CC) $(SOLINK) -o $@ pbx_ael.o ael/aelbison.o ael/aelflex.o
+
+ael/aelflex.o: ael/ael_lex.c ../include/asterisk/ael_structs.h ael/ael.tab.h
+	$(CC) $(CFLAGS) -c -o ael/aelflex.o ael/ael_lex.c
+
+ael/aelbison.o: ael/ael.tab.c ael/ael.tab.h ../include/asterisk/ael_structs.h
+	$(CC) $(CFLAGS) -c -o ael/aelbison.o ael/ael.tab.c
+
+ael/ael_lex.c: ael/ael.flex
+	(cd ael; flex ael.flex)
+
+ael/ael.tab.c ael/ael.tab.h: ael/ael.y
+	(cd ael; bison -v -d ael.y)
+
 %.moc : %.h
 	$(MOC) $< -o $@
 
diff --git a/pbx/ael/ael-test/ael-test1/extensions.ael b/pbx/ael/ael-test/ael-test1/extensions.ael
new file mode 100644
index 0000000000..d25ddd3235
--- /dev/null
+++ b/pbx/ael/ael-test/ael-test1/extensions.ael
@@ -0,0 +1,163 @@
+
+macro testdial(number, timeout) {
+    Dial(IAX2/vpconnect-t02/${number},${timeout},${OG_DIAL_FLAGS});
+    switch (${DIALSTATUS}) {
+    case CHANUNAVAIL:
+        goto dial-trunk2;
+        break;
+    default:
+        NoOp(t02 Unavailable - ${DIALSTATUS});
+        return;
+    }
+
+dial-trunk2:
+    Dial(IAX2/vpconnect-t01/${number},${timeout},${OG_DIAL_FLAGS});
+
+}
+
+macro exten-gen(name,pword)
+{
+	if( ${DB_EXISTS(org/${GroupID}/${name}/secret)} = 0 )
+		goto other|nomatch|begin;
+	if( ${DB(org/${GroupID}/${name}/secret)}foo != ${pword}foo )
+		goto other|nomatch|begin;
+
+};
+
+context what {
+        who =>
+        {
+                random(51) NoOp(This should appear 51% of the time);
+
+                random( 60 )
+                {
+                        NoOp( This should appear 60% of the time );
+                }
+                else
+                {
+                        random(75)
+                        {
+                                NoOp( This should appear 30% of the time! );
+                        }
+                        else
+                        {
+                                NoOp( This should appear 10% of the time! );
+                        }
+                }
+        }
+}
+
+context other {
+	nomatch => {
+		begin:
+		NoOp(Hello!);
+		switch(${DIALSTATUS})
+		{
+		case BUSY:
+			NoOp(wow);
+		case TORTURE:
+			NoOp(woow);
+		};
+		NoOp(woohoo);
+	};
+};
+
+context testloop {
+        includes {
+                other|16:00-23:59|m0n-fri|*|*;
+        };
+	
+    1 => {
+         for (x=0; ${x} < 3; x=${x} + 1) {
+              Verbose(x is ${x} !);
+		 if( ${x} = 1 )
+			continue;
+		 if( ${x} = 2 )
+			break;
+         };
+         ifTime(14:00-25:00|sat-sun|*|*) {
+                BackGround(Hello);
+         } else
+                BackGround(Sorry);
+         NoOp(This is a totally useless NOOP);
+    };
+    2 => {
+         y=10;
+         while (${y} >= 0) {
+              Verbose(y is ${y} !);
+		if( ${y} = 1 )
+			continue;
+		if( ${y} = 2 )
+			break;
+		if( ${y} = 3 )
+			return;
+              y=${y}-1;
+         };
+    }; 
+    regexten hint(nasty/Thingy) 3 => {
+        for (x=0; ${x} < 3; x=${x} + 1) 
+		{
+            	Verbose(x is ${x} !);
+		if( ${x} = 4 )
+			break;
+		if( ${x} = 5 )
+			continue;
+		if( ${x} = 6 )
+			return;
+
+        	y=10;
+	        while (${y} >= 0) 
+			{
+            			Verbose(y is ${y} !);
+				if( ${y} = 4 )
+					break;
+				if( ${y} = 5 )
+					continue;
+				if( ${y} = 6 )
+					return;
+	   		         y=${y}-1;
+			};
+        };
+    }; 
+    4 => {
+       	y=10;
+        while (${y} >= 0) 
+	{
+            	Verbose(y is ${y} !);
+		if( ${y} = 4 )
+			break;
+		if( ${y} = 5 )
+			continue;
+		if( ${y} = 6 )
+			return;
+       		for (x=0; ${x} < 3; x=${x} + 1) 
+		{
+            		Verbose(x is ${x} !);
+			if( ${x} = 4 )
+				break;
+			if( ${x} = 5 )
+				continue;
+			if( ${x} = 6 )
+				return;
+		        for (z=0; ${z} < 17; z=${z} + 1) 
+			{
+              			Verbose(z is ${z} !);
+              			Verbose(z is ${z} !);
+				if( ${z} = 4 )
+					break;
+				if( ${z} = 5 )
+					continue;
+				if( ${z} = 6 )
+					return;
+              			Verbose(z is ${z} !);
+              			Verbose(z is ${z} !);
+         		};
+				
+		};
+	        y=${y}-1;
+        };
+    }; 
+    5 => {
+		&exten-gen(axel,brain);
+    };
+};
diff --git a/pbx/ael/ael-test/ael-test2/apptest.ael2 b/pbx/ael/ael-test/ael-test2/apptest.ael2
new file mode 100644
index 0000000000..c477d8531b
--- /dev/null
+++ b/pbx/ael/ael-test/ael-test2/apptest.ael2
@@ -0,0 +1,146 @@
+// this is a quick test to see how many of the apps we can spot j options in
+// include this in a macro or extension
+// at this moment, there are 18 apps that accept the j option.
+
+	AddQueueMember(zork,iface,20,j);
+	ADSIProg(sfile);
+	AgentCallbackLogin(agent,s,30@cont);
+	AgentLogin(agent,s);
+	AgentMonitorOutgoing(dcn);
+	AGI(whatever);
+	AlarmReceiver();
+	Answer(2);
+	AppendCDRUserField(value);
+	Authenticate(pword,adjmr);
+	BackGround(filename,snm,eng);
+	BackgroundDetect(filename,20,2,10);
+	Busy(10);
+	ChangeMonitor(fnamebase);
+	ChanIsAvail(Zap/5,sj);
+	ChanSpy(prefix,bg()qrv);
+	Congestion(5);
+	ControlPlayback(filename,10,6,4,0,5,7,j);
+	DateTime(unixtime,tz,fmt);
+	DBdel(fam/key);
+	DBdeltree(fam);
+	DeadAGI(command);
+	Dial(zap/1,45,A()CdD()fgG()hHjL()m()M()nNoprS()tTwW);
+	Dictate(basedir);
+	Directory(cont,dcont,f);
+	DISA(68986869876,context);
+	DumpChan(verblev);
+	DUNDiLookup(90709780978,context,bj);
+	EAGI(command);
+	Echo();
+	EndWhile();
+	Exec(appname,args);
+	ExecIf(expr,app,data);
+	ExecIfTime(*,*,*,*,appname);
+	ExternalIVR(command,arg1);
+	Festival(text);
+	Flash();
+	ForkCDR(v);
+	GetCPEID();
+	Gosub(cont,exten,priority);
+	GosubIf(cond?label);
+	Goto(cont,exten,prior);
+	GotoIf(cond?t:f);
+	GotoIfTime(*,*,*,*?cont,ext,prior);
+	Hangup();
+	HasNewVoicemail(vmbox,var,j);
+	HasVoicemail(vmbox,var,j);
+	IAX2Provision(template);
+	ICES(xmlconfig);
+	ImportVar(nevar@chann,var);
+	Log(NOTICE,message);
+	LookupBlacklist(j);
+	LookupCIDName();
+	Macro(macro,arg1);
+	MacroExit();
+	MacroIf(expr?etc);
+	MailboxExists(mbox@cont,j);
+	Math(v,2+2);
+	MeetMe(5555,aAbcdDeimMpPqrstTovwxX);
+	MeetMeAdmin(5555,e,user);
+	MeetMeCount(5555,var);
+	Milliwatt();
+	MixMonitor(filename,abv()V()W(),command);
+	Monitor(file.fmt,base,mb);
+	MP3Player(location);
+	MusicOnHold(class);
+	NBScat();
+	NoCDR();
+	NoOp(ignored);
+	Page(Zap/1,dq);
+	Park(exten);
+	ParkAndAnnounce(template,5,238,retcont);
+	ParkedCall(exten);
+	PauseQueueMember(queue,zap,j);
+	Pickup(ext@cont);
+	Playback(file,j);
+	PlayTones(arg);
+	PrivacyManager(3,4,j);
+	Progress();
+	Queue(queuename,dhHnrtTwW,http://www.where.what,over,5);
+	Random(30,cont,ext,pri);
+	Read(var,fname,10,skip,2,5);
+	ReadFile(var=file,10);
+	RealTime(fam,2,val,prefix);
+	RealTimeUpdate(fam,2,val,2,newval);
+	Record(file,2,10,anqst);
+	RemoveQueueMember(queuename,iface,j);
+	ResetCDR(wav);
+	RetryDial(annound,4,2);
+	Return();
+	Ringing();
+	RxFAX(fname,caller);
+	SayAlpha(string);
+	SayDigits(string);
+	SayNumber(digits);
+	SayPhonetic(string);
+	SayUnixTime(unixtime,tz,fmt);
+	SendDTMF(digits,10);
+	SendImage(filename);
+	SendText(text,j);
+	SendURL(URL);
+	Set(a=b);
+	SetAMAFlags();
+	SetCallerID(clid,a);
+	SetCallerPres(allowed_passed_screen);
+	SetCDRUserField(value);
+	SetGlobalVar(var=val);
+	SetMusicOnHold(class);
+	SetTransferCapability(SPEECH);
+	SIPAddHeader(header);
+	SIPDtmfMode(inband,info,rfc);
+	SIPGetHeader(var@headername);
+	SMS(name);
+	SoftHangup(zap/1,a);
+	StackPop();
+	StartMusicOnHold(class);
+	StopMonitor();
+	StopMusicOnHold();
+	StopPlayTones();
+	System(command);
+	TestClient(testid);
+	TestServer();
+	Transfer(zap/1,j);
+	TrySystem(command);
+	TxFAX(filename,caller,debug);
+	UnpauseQueueMember(queuename,iface,j);
+	UserEvent(eventanme,body);
+	Verbose(5,message);
+	VMAuthenticate(mailbox@cont,s);
+	VoiceMail(mailbox@cont,bg()suj);
+	VoiceMailMain(mailbox@cont,pg()s);
+	Wait(2);
+	WaitExten(3,m());
+	WaitForRing(2);
+	WaitForSilence(2,y);
+	WaitMusicOnHold(2);
+	While(expr);
+	Zapateller(answer,5);
+	ZapBarge(channel);
+	ZapRAS(arg);
+	ZapScan(group);
+	ZapSendKeypadFacility();
diff --git a/pbx/ael/ael-test/ael-test2/extensions.ael b/pbx/ael/ael-test/ael-test2/extensions.ael
new file mode 100644
index 0000000000..1763388727
--- /dev/null
+++ b/pbx/ael/ael-test/ael-test2/extensions.ael
@@ -0,0 +1,8 @@
+context test1
+{
+	s => 
+	{
+		#include "apptest.ael2";
+	}
+}
+
diff --git a/pbx/ael/ael-test/ael-test3/extensions.ael b/pbx/ael/ael-test/ael-test3/extensions.ael
new file mode 100755
index 0000000000..ae3b4bedfb
--- /dev/null
+++ b/pbx/ael/ael-test/ael-test3/extensions.ael
@@ -0,0 +1,3183 @@
+globals
+{
+	static=yes;
+	writeprotect=yes;
+	CONSOLE=Console/dsp;        // Console interface for demo
+	IAXINFO=murf:tlhfckoct;     // IAXtel username/password
+	FWDNUMBER=544788 ;          // your calling number
+	FWDCIDNAME="Joe-Worker";    // your caller id
+	FWDPASSWORD=zingledoodle ;  // your password
+	FWDRINGS=Zap/6 ;            // the phone to ring
+	FWDVMBOX=1 ;                // the VM box for this user
+}
+
+macro std-exten( ext , dev ) 
+{
+        Dial(${dev}/${ext},20);
+        switch(${DIALSTATUS}) 
+		{
+        case BUSY:
+                Voicemail(b${ext});
+                break;
+	case NOANSWER:
+		Voicemail(u${ext});
+		break;
+	case ANSWER:
+		break;
+        default:
+                Voicemail(u${ext});
+        }
+        catch a {
+                VoiceMailMain(${ext});
+        }
+}
+
+macro std-priv-exten_1( dev, ext , timeout, opts, torcont, dontcont ) 
+{
+        Dial(${dev},${timeout},${opts});
+	NoOp(${DIALSTATUS} was chosen);
+        switch(${DIALSTATUS}) 
+		{
+        case TORTURE:
+		goto ${torcont}|s|begin;
+                break;
+        case DONTCALL:
+		goto ${dontcont}|s|begin;
+                break;
+        case BUSY:
+                Voicemail(b${ext});
+                break;
+        case ANSWER:
+		break;
+        case NOANSWER:
+                Voicemail(u${ext});
+                break;
+        default:
+                Voicemail(u${ext});
+        }
+}
+
+
+macro std-priv-exten_2( dev, ext , timeout, opts, torcont, dontcont ) 
+{
+        Dial(${dev},${timeout},${opts});
+	NoOp(${DIALSTATUS} was chosen);
+        switch(${DIALSTATUS}) 
+		{
+        case TORTURE:
+		goto ${torcont}|s|begin;
+                break;
+        case DONTCALL:
+		goto ${dontcont}|s|begin;
+                break;
+        case BUSY:
+                Voicemail(b${ext});
+                break;
+        case ANSWER:
+		break;
+        case NOANSWER:
+                Voicemail(u${ext});
+                break;
+        default:
+                Voicemail(u${ext});
+        }
+}
+
+
+macro std-priv-exten_3( dev, ext , timeout, opts, torcont, dontcont ) 
+{
+        Dial(${dev},${timeout},${opts});
+	NoOp(${DIALSTATUS} was chosen);
+        switch(${DIALSTATUS}) 
+		{
+        case TORTURE:
+		goto ${torcont}|s|begin;
+                break;
+        case DONTCALL:
+		goto ${dontcont}|s|begin;
+                break;
+        case BUSY:
+                Voicemail(b${ext});
+                break;
+        case ANSWER:
+		break;
+        case NOANSWER:
+                Voicemail(u${ext});
+                break;
+        default:
+                Voicemail(u${ext});
+        }
+}
+
+
+macro std-priv-exten_4( dev, ext , timeout, opts, torcont, dontcont ) 
+{
+        Dial(${dev},${timeout},${opts});
+	NoOp(${DIALSTATUS} was chosen);
+        switch(${DIALSTATUS}) 
+		{
+        case TORTURE:
+		goto ${torcont}|s|begin;
+                break;
+        case DONTCALL:
+		goto ${dontcont}|s|begin;
+                break;
+        case BUSY:
+                Voicemail(b${ext});
+                break;
+        case ANSWER:
+		break;
+        case NOANSWER:
+                Voicemail(u${ext});
+                break;
+        default:
+                Voicemail(u${ext});
+        }
+}
+
+
+macro std-priv-exten_5( dev, ext , timeout, opts, torcont, dontcont ) 
+{
+        Dial(${dev},${timeout},${opts});
+	NoOp(${DIALSTATUS} was chosen);
+        switch(${DIALSTATUS}) 
+		{
+        case TORTURE:
+		goto ${torcont}|s|begin;
+                break;
+        case DONTCALL:
+		goto ${dontcont}|s|begin;
+                break;
+        case BUSY:
+                Voicemail(b${ext});
+                break;
+        case ANSWER:
+		break;
+        case NOANSWER:
+                Voicemail(u${ext});
+                break;
+        default:
+                Voicemail(u${ext});
+        }
+}
+
+
+macro std-priv-exten_6( dev, ext , timeout, opts, torcont, dontcont ) 
+{
+        Dial(${dev},${timeout},${opts});
+	NoOp(${DIALSTATUS} was chosen);
+        switch(${DIALSTATUS}) 
+		{
+        case TORTURE:
+		goto ${torcont}|s|begin;
+                break;
+        case DONTCALL:
+		goto ${dontcont}|s|begin;
+                break;
+        case BUSY:
+                Voicemail(b${ext});
+                break;
+        case ANSWER:
+		break;
+        case NOANSWER:
+                Voicemail(u${ext});
+                break;
+        default:
+                Voicemail(u${ext});
+        }
+}
+
+
+macro std-priv-exten_7( dev, ext , timeout, opts, torcont, dontcont ) 
+{
+        Dial(${dev},${timeout},${opts});
+	NoOp(${DIALSTATUS} was chosen);
+        switch(${DIALSTATUS}) 
+		{
+        case TORTURE:
+		goto ${torcont}|s|begin;
+                break;
+        case DONTCALL:
+		goto ${dontcont}|s|begin;
+                break;
+        case BUSY:
+                Voicemail(b${ext});
+                break;
+        case ANSWER:
+		break;
+        case NOANSWER:
+                Voicemail(u${ext});
+                break;
+        default:
+                Voicemail(u${ext});
+        }
+}
+
+
+macro std-priv-exten_8( dev, ext , timeout, opts, torcont, dontcont ) 
+{
+        Dial(${dev},${timeout},${opts});
+	NoOp(${DIALSTATUS} was chosen);
+        switch(${DIALSTATUS}) 
+		{
+        case TORTURE:
+		goto ${torcont}|s|begin;
+                break;
+        case DONTCALL:
+		goto ${dontcont}|s|begin;
+                break;
+        case BUSY:
+                Voicemail(b${ext});
+                break;
+        case ANSWER:
+		break;
+        case NOANSWER:
+                Voicemail(u${ext});
+                break;
+        default:
+                Voicemail(u${ext});
+        }
+}
+
+
+macro std-priv-exten_9( dev, ext , timeout, opts, torcont, dontcont ) 
+{
+        Dial(${dev},${timeout},${opts});
+	NoOp(${DIALSTATUS} was chosen);
+        switch(${DIALSTATUS}) 
+		{
+        case TORTURE:
+		goto ${torcont}|s|begin;
+                break;
+        case DONTCALL:
+		goto ${dontcont}|s|begin;
+                break;
+        case BUSY:
+                Voicemail(b${ext});
+                break;
+        case ANSWER:
+		break;
+        case NOANSWER:
+                Voicemail(u${ext});
+                break;
+        default:
+                Voicemail(u${ext});
+        }
+}
+
+
+macro std-priv-exten_10( dev, ext , timeout, opts, torcont, dontcont ) 
+{
+        Dial(${dev},${timeout},${opts});
+	NoOp(${DIALSTATUS} was chosen);
+        switch(${DIALSTATUS}) 
+		{
+        case TORTURE:
+		goto ${torcont}|s|begin;
+                break;
+        case DONTCALL:
+		goto ${dontcont}|s|begin;
+                break;
+        case BUSY:
+                Voicemail(b${ext});
+                break;
+        case ANSWER:
+		break;
+        case NOANSWER:
+                Voicemail(u${ext});
+                break;
+        default:
+                Voicemail(u${ext});
+        }
+}
+
+
+macro std-priv-exten_11( dev, ext , timeout, opts, torcont, dontcont ) 
+{
+        Dial(${dev},${timeout},${opts});
+	NoOp(${DIALSTATUS} was chosen);
+        switch(${DIALSTATUS}) 
+		{
+        case TORTURE:
+		goto ${torcont}|s|begin;
+                break;
+        case DONTCALL:
+		goto ${dontcont}|s|begin;
+                break;
+        case BUSY:
+                Voicemail(b${ext});
+                break;
+        case ANSWER:
+		break;
+        case NOANSWER:
+                Voicemail(u${ext});
+                break;
+        default:
+                Voicemail(u${ext});
+        }
+}
+
+
+macro std-priv-exten_12( dev, ext , timeout, opts, torcont, dontcont ) 
+{
+        Dial(${dev},${timeout},${opts});
+	NoOp(${DIALSTATUS} was chosen);
+        switch(${DIALSTATUS}) 
+		{
+        case TORTURE:
+		goto ${torcont}|s|begin;
+                break;
+        case DONTCALL:
+		goto ${dontcont}|s|begin;
+                break;
+        case BUSY:
+                Voicemail(b${ext});
+                break;
+        case ANSWER:
+		break;
+        case NOANSWER:
+                Voicemail(u${ext});
+                break;
+        default:
+                Voicemail(u${ext});
+        }
+}
+
+
+macro std-priv-exten_13( dev, ext , timeout, opts, torcont, dontcont ) 
+{
+        Dial(${dev},${timeout},${opts});
+	NoOp(${DIALSTATUS} was chosen);
+        switch(${DIALSTATUS}) 
+		{
+        case TORTURE:
+		goto ${torcont}|s|begin;
+                break;
+        case DONTCALL:
+		goto ${dontcont}|s|begin;
+                break;
+        case BUSY:
+                Voicemail(b${ext});
+                break;
+        case ANSWER:
+		break;
+        case NOANSWER:
+                Voicemail(u${ext});
+                break;
+        default:
+                Voicemail(u${ext});
+        }
+}
+
+
+macro std-priv-exten_14( dev, ext , timeout, opts, torcont, dontcont ) 
+{
+        Dial(${dev},${timeout},${opts});
+	NoOp(${DIALSTATUS} was chosen);
+        switch(${DIALSTATUS}) 
+		{
+        case TORTURE:
+		goto ${torcont}|s|begin;
+                break;
+        case DONTCALL:
+		goto ${dontcont}|s|begin;
+                break;
+        case BUSY:
+                Voicemail(b${ext});
+                break;
+        case ANSWER:
+		break;
+        case NOANSWER:
+                Voicemail(u${ext});
+                break;
+        default:
+                Voicemail(u${ext});
+        }
+}
+
+
+macro std-priv-exten_15( dev, ext , timeout, opts, torcont, dontcont ) 
+{
+        Dial(${dev},${timeout},${opts});
+	NoOp(${DIALSTATUS} was chosen);
+        switch(${DIALSTATUS}) 
+		{
+        case TORTURE:
+		goto ${torcont}|s|begin;
+                break;
+        case DONTCALL:
+		goto ${dontcont}|s|begin;
+                break;
+        case BUSY:
+                Voicemail(b${ext});
+                break;
+        case ANSWER:
+		break;
+        case NOANSWER:
+                Voicemail(u${ext});
+                break;
+        default:
+                Voicemail(u${ext});
+        }
+}
+
+
+macro std-priv-exten_16( dev, ext , timeout, opts, torcont, dontcont ) 
+{
+        Dial(${dev},${timeout},${opts});
+	NoOp(${DIALSTATUS} was chosen);
+        switch(${DIALSTATUS}) 
+		{
+        case TORTURE:
+		goto ${torcont}|s|begin;
+                break;
+        case DONTCALL:
+		goto ${dontcont}|s|begin;
+                break;
+        case BUSY:
+                Voicemail(b${ext});
+                break;
+        case ANSWER:
+		break;
+        case NOANSWER:
+                Voicemail(u${ext});
+                break;
+        default:
+                Voicemail(u${ext});
+        }
+}
+
+
+macro std-priv-exten_17( dev, ext , timeout, opts, torcont, dontcont ) 
+{
+        Dial(${dev},${timeout},${opts});
+	NoOp(${DIALSTATUS} was chosen);
+        switch(${DIALSTATUS}) 
+		{
+        case TORTURE:
+		goto ${torcont}|s|begin;
+                break;
+        case DONTCALL:
+		goto ${dontcont}|s|begin;
+                break;
+        case BUSY:
+                Voicemail(b${ext});
+                break;
+        case ANSWER:
+		break;
+        case NOANSWER:
+                Voicemail(u${ext});
+                break;
+        default:
+                Voicemail(u${ext});
+        }
+}
+
+
+macro std-priv-exten_18( dev, ext , timeout, opts, torcont, dontcont ) 
+{
+        Dial(${dev},${timeout},${opts});
+	NoOp(${DIALSTATUS} was chosen);
+        switch(${DIALSTATUS}) 
+		{
+        case TORTURE:
+		goto ${torcont}|s|begin;
+                break;
+        case DONTCALL:
+		goto ${dontcont}|s|begin;
+                break;
+        case BUSY:
+                Voicemail(b${ext});
+                break;
+        case ANSWER:
+		break;
+        case NOANSWER:
+                Voicemail(u${ext});
+                break;
+        default:
+                Voicemail(u${ext});
+        }
+}
+
+
+macro std-priv-exten_19( dev, ext , timeout, opts, torcont, dontcont ) 
+{
+        Dial(${dev},${timeout},${opts});
+	NoOp(${DIALSTATUS} was chosen);
+        switch(${DIALSTATUS}) 
+		{
+        case TORTURE:
+		goto ${torcont}|s|begin;
+                break;
+        case DONTCALL:
+		goto ${dontcont}|s|begin;
+                break;
+        case BUSY:
+                Voicemail(b${ext});
+                break;
+        case ANSWER:
+		break;
+        case NOANSWER:
+                Voicemail(u${ext});
+                break;
+        default:
+                Voicemail(u${ext});
+        }
+}
+
+
+macro std-priv-exten_20( dev, ext , timeout, opts, torcont, dontcont ) 
+{
+        Dial(${dev},${timeout},${opts});
+	NoOp(${DIALSTATUS} was chosen);
+        switch(${DIALSTATUS}) 
+		{
+        case TORTURE:
+		goto ${torcont}|s|begin;
+                break;
+        case DONTCALL:
+		goto ${dontcont}|s|begin;
+                break;
+        case BUSY:
+                Voicemail(b${ext});
+                break;
+        case ANSWER:
+		break;
+        case NOANSWER:
+                Voicemail(u${ext});
+                break;
+        default:
+                Voicemail(u${ext});
+        }
+}
+
+
+macro std-priv-exten_21( dev, ext , timeout, opts, torcont, dontcont ) 
+{
+        Dial(${dev},${timeout},${opts});
+	NoOp(${DIALSTATUS} was chosen);
+        switch(${DIALSTATUS}) 
+		{
+        case TORTURE:
+		goto ${torcont}|s|begin;
+                break;
+        case DONTCALL:
+		goto ${dontcont}|s|begin;
+                break;
+        case BUSY:
+                Voicemail(b${ext});
+                break;
+        case ANSWER:
+		break;
+        case NOANSWER:
+                Voicemail(u${ext});
+                break;
+        default:
+                Voicemail(u${ext});
+        }
+}
+
+
+macro std-priv-exten_22( dev, ext , timeout, opts, torcont, dontcont ) 
+{
+        Dial(${dev},${timeout},${opts});
+	NoOp(${DIALSTATUS} was chosen);
+        switch(${DIALSTATUS}) 
+		{
+        case TORTURE:
+		goto ${torcont}|s|begin;
+                break;
+        case DONTCALL:
+		goto ${dontcont}|s|begin;
+                break;
+        case BUSY:
+                Voicemail(b${ext});
+                break;
+        case ANSWER:
+		break;
+        case NOANSWER:
+                Voicemail(u${ext});
+                break;
+        default:
+                Voicemail(u${ext});
+        }
+}
+
+
+macro std-priv-exten_23( dev, ext , timeout, opts, torcont, dontcont ) 
+{
+        Dial(${dev},${timeout},${opts});
+	NoOp(${DIALSTATUS} was chosen);
+        switch(${DIALSTATUS}) 
+		{
+        case TORTURE:
+		goto ${torcont}|s|begin;
+                break;
+        case DONTCALL:
+		goto ${dontcont}|s|begin;
+                break;
+        case BUSY:
+                Voicemail(b${ext});
+                break;
+        case ANSWER:
+		break;
+        case NOANSWER:
+                Voicemail(u${ext});
+                break;
+        default:
+                Voicemail(u${ext});
+        }
+}
+
+
+macro std-priv-exten_24( dev, ext , timeout, opts, torcont, dontcont ) 
+{
+        Dial(${dev},${timeout},${opts});
+	NoOp(${DIALSTATUS} was chosen);
+        switch(${DIALSTATUS}) 
+		{
+        case TORTURE:
+		goto ${torcont}|s|begin;
+                break;
+        case DONTCALL:
+		goto ${dontcont}|s|begin;
+                break;
+        case BUSY:
+                Voicemail(b${ext});
+                break;
+        case ANSWER:
+		break;
+        case NOANSWER:
+                Voicemail(u${ext});
+                break;
+        default:
+                Voicemail(u${ext});
+        }
+}
+
+
+macro std-priv-exten_25( dev, ext , timeout, opts, torcont, dontcont ) 
+{
+        Dial(${dev},${timeout},${opts});
+	NoOp(${DIALSTATUS} was chosen);
+        switch(${DIALSTATUS}) 
+		{
+        case TORTURE:
+		goto ${torcont}|s|begin;
+                break;
+        case DONTCALL:
+		goto ${dontcont}|s|begin;
+                break;
+        case BUSY:
+                Voicemail(b${ext});
+                break;
+        case ANSWER:
+		break;
+        case NOANSWER:
+                Voicemail(u${ext});
+                break;
+        default:
+                Voicemail(u${ext});
+        }
+}
+
+
+macro std-priv-exten_26( dev, ext , timeout, opts, torcont, dontcont ) 
+{
+        Dial(${dev},${timeout},${opts});
+	NoOp(${DIALSTATUS} was chosen);
+        switch(${DIALSTATUS}) 
+		{
+        case TORTURE:
+		goto ${torcont}|s|begin;
+                break;
+        case DONTCALL:
+		goto ${dontcont}|s|begin;
+                break;
+        case BUSY:
+                Voicemail(b${ext});
+                break;
+        case ANSWER:
+		break;
+        case NOANSWER:
+                Voicemail(u${ext});
+                break;
+        default:
+                Voicemail(u${ext});
+        }
+}
+
+
+macro std-priv-exten_27( dev, ext , timeout, opts, torcont, dontcont ) 
+{
+        Dial(${dev},${timeout},${opts});
+	NoOp(${DIALSTATUS} was chosen);
+        switch(${DIALSTATUS}) 
+		{
+        case TORTURE:
+		goto ${torcont}|s|begin;
+                break;
+        case DONTCALL:
+		goto ${dontcont}|s|begin;
+                break;
+        case BUSY:
+                Voicemail(b${ext});
+                break;
+        case ANSWER:
+		break;
+        case NOANSWER:
+                Voicemail(u${ext});
+                break;
+        default:
+                Voicemail(u${ext});
+        }
+}
+
+
+macro std-priv-exten_28( dev, ext , timeout, opts, torcont, dontcont ) 
+{
+        Dial(${dev},${timeout},${opts});
+	NoOp(${DIALSTATUS} was chosen);
+        switch(${DIALSTATUS}) 
+		{
+        case TORTURE:
+		goto ${torcont}|s|begin;
+                break;
+        case DONTCALL:
+		goto ${dontcont}|s|begin;
+                break;
+        case BUSY:
+                Voicemail(b${ext});
+                break;
+        case ANSWER:
+		break;
+        case NOANSWER:
+                Voicemail(u${ext});
+                break;
+        default:
+                Voicemail(u${ext});
+        }
+}
+
+
+macro std-priv-exten_29( dev, ext , timeout, opts, torcont, dontcont ) 
+{
+        Dial(${dev},${timeout},${opts});
+	NoOp(${DIALSTATUS} was chosen);
+        switch(${DIALSTATUS}) 
+		{
+        case TORTURE:
+		goto ${torcont}|s|begin;
+                break;
+        case DONTCALL:
+		goto ${dontcont}|s|begin;
+                break;
+        case BUSY:
+                Voicemail(b${ext});
+                break;
+        case ANSWER:
+		break;
+        case NOANSWER:
+                Voicemail(u${ext});
+                break;
+        default:
+                Voicemail(u${ext});
+        }
+}
+
+
+macro std-priv-exten_30( dev, ext , timeout, opts, torcont, dontcont ) 
+{
+        Dial(${dev},${timeout},${opts});
+	NoOp(${DIALSTATUS} was chosen);
+        switch(${DIALSTATUS}) 
+		{
+        case TORTURE:
+		goto ${torcont}|s|begin;
+                break;
+        case DONTCALL:
+		goto ${dontcont}|s|begin;
+                break;
+        case BUSY:
+                Voicemail(b${ext});
+                break;
+        case ANSWER:
+		break;
+        case NOANSWER:
+                Voicemail(u${ext});
+                break;
+        default:
+                Voicemail(u${ext});
+        }
+}
+
+
+macro std-priv-exten_31( dev, ext , timeout, opts, torcont, dontcont ) 
+{
+        Dial(${dev},${timeout},${opts});
+	NoOp(${DIALSTATUS} was chosen);
+        switch(${DIALSTATUS}) 
+		{
+        case TORTURE:
+		goto ${torcont}|s|begin;
+                break;
+        case DONTCALL:
+		goto ${dontcont}|s|begin;
+                break;
+        case BUSY:
+                Voicemail(b${ext});
+                break;
+        case ANSWER:
+		break;
+        case NOANSWER:
+                Voicemail(u${ext});
+                break;
+        default:
+                Voicemail(u${ext});
+        }
+}
+
+
+macro std-priv-exten_32( dev, ext , timeout, opts, torcont, dontcont ) 
+{
+        Dial(${dev},${timeout},${opts});
+	NoOp(${DIALSTATUS} was chosen);
+        switch(${DIALSTATUS}) 
+		{
+        case TORTURE:
+		goto ${torcont}|s|begin;
+                break;
+        case DONTCALL:
+		goto ${dontcont}|s|begin;
+                break;
+        case BUSY:
+                Voicemail(b${ext});
+                break;
+        case ANSWER:
+		break;
+        case NOANSWER:
+                Voicemail(u${ext});
+                break;
+        default:
+                Voicemail(u${ext});
+        }
+}
+
+
+macro std-priv-exten_33( dev, ext , timeout, opts, torcont, dontcont ) 
+{
+        Dial(${dev},${timeout},${opts});
+	NoOp(${DIALSTATUS} was chosen);
+        switch(${DIALSTATUS}) 
+		{
+        case TORTURE:
+		goto ${torcont}|s|begin;
+                break;
+        case DONTCALL:
+		goto ${dontcont}|s|begin;
+                break;
+        case BUSY:
+                Voicemail(b${ext});
+                break;
+        case ANSWER:
+		break;
+        case NOANSWER:
+                Voicemail(u${ext});
+                break;
+        default:
+                Voicemail(u${ext});
+        }
+}
+
+
+macro std-priv-exten_34( dev, ext , timeout, opts, torcont, dontcont ) 
+{
+        Dial(${dev},${timeout},${opts});
+	NoOp(${DIALSTATUS} was chosen);
+        switch(${DIALSTATUS}) 
+		{
+        case TORTURE:
+		goto ${torcont}|s|begin;
+                break;
+        case DONTCALL:
+		goto ${dontcont}|s|begin;
+                break;
+        case BUSY:
+                Voicemail(b${ext});
+                break;
+        case ANSWER:
+		break;
+        case NOANSWER:
+                Voicemail(u${ext});
+                break;
+        default:
+                Voicemail(u${ext});
+        }
+}
+
+
+macro std-priv-exten_35( dev, ext , timeout, opts, torcont, dontcont ) 
+{
+        Dial(${dev},${timeout},${opts});
+	NoOp(${DIALSTATUS} was chosen);
+        switch(${DIALSTATUS}) 
+		{
+        case TORTURE:
+		goto ${torcont}|s|begin;
+                break;
+        case DONTCALL:
+		goto ${dontcont}|s|begin;
+                break;
+        case BUSY:
+                Voicemail(b${ext});
+                break;
+        case ANSWER:
+		break;
+        case NOANSWER:
+                Voicemail(u${ext});
+                break;
+        default:
+                Voicemail(u${ext});
+        }
+}
+
+
+macro std-priv-exten_36( dev, ext , timeout, opts, torcont, dontcont ) 
+{
+        Dial(${dev},${timeout},${opts});
+	NoOp(${DIALSTATUS} was chosen);
+        switch(${DIALSTATUS}) 
+		{
+        case TORTURE:
+		goto ${torcont}|s|begin;
+                break;
+        case DONTCALL:
+		goto ${dontcont}|s|begin;
+                break;
+        case BUSY:
+                Voicemail(b${ext});
+                break;
+        case ANSWER:
+		break;
+        case NOANSWER:
+                Voicemail(u${ext});
+                break;
+        default:
+                Voicemail(u${ext});
+        }
+}
+
+
+macro std-priv-exten_37( dev, ext , timeout, opts, torcont, dontcont ) 
+{
+        Dial(${dev},${timeout},${opts});
+	NoOp(${DIALSTATUS} was chosen);
+        switch(${DIALSTATUS}) 
+		{
+        case TORTURE:
+		goto ${torcont}|s|begin;
+                break;
+        case DONTCALL:
+		goto ${dontcont}|s|begin;
+                break;
+        case BUSY:
+                Voicemail(b${ext});
+                break;
+        case ANSWER:
+		break;
+        case NOANSWER:
+                Voicemail(u${ext});
+                break;
+        default:
+                Voicemail(u${ext});
+        }
+}
+
+
+macro std-priv-exten_38( dev, ext , timeout, opts, torcont, dontcont ) 
+{
+        Dial(${dev},${timeout},${opts});
+	NoOp(${DIALSTATUS} was chosen);
+        switch(${DIALSTATUS}) 
+		{
+        case TORTURE:
+		goto ${torcont}|s|begin;
+                break;
+        case DONTCALL:
+		goto ${dontcont}|s|begin;
+                break;
+        case BUSY:
+                Voicemail(b${ext});
+                break;
+        case ANSWER:
+		break;
+        case NOANSWER:
+                Voicemail(u${ext});
+                break;
+        default:
+                Voicemail(u${ext});
+        }
+}
+
+
+macro std-priv-exten_39( dev, ext , timeout, opts, torcont, dontcont ) 
+{
+        Dial(${dev},${timeout},${opts});
+	NoOp(${DIALSTATUS} was chosen);
+        switch(${DIALSTATUS}) 
+		{
+        case TORTURE:
+		goto ${torcont}|s|begin;
+                break;
+        case DONTCALL:
+		goto ${dontcont}|s|begin;
+                break;
+        case BUSY:
+                Voicemail(b${ext});
+                break;
+        case ANSWER:
+		break;
+        case NOANSWER:
+                Voicemail(u${ext});
+                break;
+        default:
+                Voicemail(u${ext});
+        }
+}
+
+
+macro std-priv-exten_40( dev, ext , timeout, opts, torcont, dontcont ) 
+{
+        Dial(${dev},${timeout},${opts});
+	NoOp(${DIALSTATUS} was chosen);
+        switch(${DIALSTATUS}) 
+		{
+        case TORTURE:
+		goto ${torcont}|s|begin;
+                break;
+        case DONTCALL:
+		goto ${dontcont}|s|begin;
+                break;
+        case BUSY:
+                Voicemail(b${ext});
+                break;
+        case ANSWER:
+		break;
+        case NOANSWER:
+                Voicemail(u${ext});
+                break;
+        default:
+                Voicemail(u${ext});
+        }
+}
+
+
+macro std-priv-exten_41( dev, ext , timeout, opts, torcont, dontcont ) 
+{
+        Dial(${dev},${timeout},${opts});
+	NoOp(${DIALSTATUS} was chosen);
+        switch(${DIALSTATUS}) 
+		{
+        case TORTURE:
+		goto ${torcont}|s|begin;
+                break;
+        case DONTCALL:
+		goto ${dontcont}|s|begin;
+                break;
+        case BUSY:
+                Voicemail(b${ext});
+                break;
+        case ANSWER:
+		break;
+        case NOANSWER:
+                Voicemail(u${ext});
+                break;
+        default:
+                Voicemail(u${ext});
+        }
+}
+
+
+macro std-priv-exten_42( dev, ext , timeout, opts, torcont, dontcont ) 
+{
+        Dial(${dev},${timeout},${opts});
+	NoOp(${DIALSTATUS} was chosen);
+        switch(${DIALSTATUS}) 
+		{
+        case TORTURE:
+		goto ${torcont}|s|begin;
+                break;
+        case DONTCALL:
+		goto ${dontcont}|s|begin;
+                break;
+        case BUSY:
+                Voicemail(b${ext});
+                break;
+        case ANSWER:
+		break;
+        case NOANSWER:
+                Voicemail(u${ext});
+                break;
+        default:
+                Voicemail(u${ext});
+        }
+}
+
+
+macro std-priv-exten_43( dev, ext , timeout, opts, torcont, dontcont ) 
+{
+        Dial(${dev},${timeout},${opts});
+	NoOp(${DIALSTATUS} was chosen);
+        switch(${DIALSTATUS}) 
+		{
+        case TORTURE:
+		goto ${torcont}|s|begin;
+                break;
+        case DONTCALL:
+		goto ${dontcont}|s|begin;
+                break;
+        case BUSY:
+                Voicemail(b${ext});
+                break;
+        case ANSWER:
+		break;
+        case NOANSWER:
+                Voicemail(u${ext});
+                break;
+        default:
+                Voicemail(u${ext});
+        }
+}
+
+
+macro std-priv-exten_44( dev, ext , timeout, opts, torcont, dontcont ) 
+{
+        Dial(${dev},${timeout},${opts});
+	NoOp(${DIALSTATUS} was chosen);
+        switch(${DIALSTATUS}) 
+		{
+        case TORTURE:
+		goto ${torcont}|s|begin;
+                break;
+        case DONTCALL:
+		goto ${dontcont}|s|begin;
+                break;
+        case BUSY:
+                Voicemail(b${ext});
+                break;
+        case ANSWER:
+		break;
+        case NOANSWER:
+                Voicemail(u${ext});
+                break;
+        default:
+                Voicemail(u${ext});
+        }
+}
+
+
+macro std-priv-exten_45( dev, ext , timeout, opts, torcont, dontcont ) 
+{
+        Dial(${dev},${timeout},${opts});
+	NoOp(${DIALSTATUS} was chosen);
+        switch(${DIALSTATUS}) 
+		{
+        case TORTURE:
+		goto ${torcont}|s|begin;
+                break;
+        case DONTCALL:
+		goto ${dontcont}|s|begin;
+                break;
+        case BUSY:
+                Voicemail(b${ext});
+                break;
+        case ANSWER:
+		break;
+        case NOANSWER:
+                Voicemail(u${ext});
+                break;
+        default:
+                Voicemail(u${ext});
+        }
+}
+
+
+macro std-priv-exten_46( dev, ext , timeout, opts, torcont, dontcont ) 
+{
+        Dial(${dev},${timeout},${opts});
+	NoOp(${DIALSTATUS} was chosen);
+        switch(${DIALSTATUS}) 
+		{
+        case TORTURE:
+		goto ${torcont}|s|begin;
+                break;
+        case DONTCALL:
+		goto ${dontcont}|s|begin;
+                break;
+        case BUSY:
+                Voicemail(b${ext});
+                break;
+        case ANSWER:
+		break;
+        case NOANSWER:
+                Voicemail(u${ext});
+                break;
+        default:
+                Voicemail(u${ext});
+        }
+}
+
+
+macro std-priv-exten_47( dev, ext , timeout, opts, torcont, dontcont ) 
+{
+        Dial(${dev},${timeout},${opts});
+	NoOp(${DIALSTATUS} was chosen);
+        switch(${DIALSTATUS}) 
+		{
+        case TORTURE:
+		goto ${torcont}|s|begin;
+                break;
+        case DONTCALL:
+		goto ${dontcont}|s|begin;
+                break;
+        case BUSY:
+                Voicemail(b${ext});
+                break;
+        case ANSWER:
+		break;
+        case NOANSWER:
+                Voicemail(u${ext});
+                break;
+        default:
+                Voicemail(u${ext});
+        }
+}
+
+
+macro std-priv-exten_48( dev, ext , timeout, opts, torcont, dontcont ) 
+{
+        Dial(${dev},${timeout},${opts});
+	NoOp(${DIALSTATUS} was chosen);
+        switch(${DIALSTATUS}) 
+		{
+        case TORTURE:
+		goto ${torcont}|s|begin;
+                break;
+        case DONTCALL:
+		goto ${dontcont}|s|begin;
+                break;
+        case BUSY:
+                Voicemail(b${ext});
+                break;
+        case ANSWER:
+		break;
+        case NOANSWER:
+                Voicemail(u${ext});
+                break;
+        default:
+                Voicemail(u${ext});
+        }
+}
+
+
+macro std-priv-exten_49( dev, ext , timeout, opts, torcont, dontcont ) 
+{
+        Dial(${dev},${timeout},${opts});
+	NoOp(${DIALSTATUS} was chosen);
+        switch(${DIALSTATUS}) 
+		{
+        case TORTURE:
+		goto ${torcont}|s|begin;
+                break;
+        case DONTCALL:
+		goto ${dontcont}|s|begin;
+                break;
+        case BUSY:
+                Voicemail(b${ext});
+                break;
+        case ANSWER:
+		break;
+        case NOANSWER:
+                Voicemail(u${ext});
+                break;
+        default:
+                Voicemail(u${ext});
+        }
+}
+
+
+macro std-priv-exten_50( dev, ext , timeout, opts, torcont, dontcont ) 
+{
+        Dial(${dev},${timeout},${opts});
+	NoOp(${DIALSTATUS} was chosen);
+        switch(${DIALSTATUS}) 
+		{
+        case TORTURE:
+		goto ${torcont}|s|begin;
+                break;
+        case DONTCALL:
+		goto ${dontcont}|s|begin;
+                break;
+        case BUSY:
+                Voicemail(b${ext});
+                break;
+        case ANSWER:
+		break;
+        case NOANSWER:
+                Voicemail(u${ext});
+                break;
+        default:
+                Voicemail(u${ext});
+        }
+}
+
+
+macro std-priv-exten_51( dev, ext , timeout, opts, torcont, dontcont ) 
+{
+        Dial(${dev},${timeout},${opts});
+	NoOp(${DIALSTATUS} was chosen);
+        switch(${DIALSTATUS}) 
+		{
+        case TORTURE:
+		goto ${torcont}|s|begin;
+                break;
+        case DONTCALL:
+		goto ${dontcont}|s|begin;
+                break;
+        case BUSY:
+                Voicemail(b${ext});
+                break;
+        case ANSWER:
+		break;
+        case NOANSWER:
+                Voicemail(u${ext});
+                break;
+        default:
+                Voicemail(u${ext});
+        }
+}
+
+
+macro std-priv-exten_52( dev, ext , timeout, opts, torcont, dontcont ) 
+{
+        Dial(${dev},${timeout},${opts});
+	NoOp(${DIALSTATUS} was chosen);
+        switch(${DIALSTATUS}) 
+		{
+        case TORTURE:
+		goto ${torcont}|s|begin;
+                break;
+        case DONTCALL:
+		goto ${dontcont}|s|begin;
+                break;
+        case BUSY:
+                Voicemail(b${ext});
+                break;
+        case ANSWER:
+		break;
+        case NOANSWER:
+                Voicemail(u${ext});
+                break;
+        default:
+                Voicemail(u${ext});
+        }
+}
+
+
+macro std-priv-exten_53( dev, ext , timeout, opts, torcont, dontcont ) 
+{
+        Dial(${dev},${timeout},${opts});
+	NoOp(${DIALSTATUS} was chosen);
+        switch(${DIALSTATUS}) 
+		{
+        case TORTURE:
+		goto ${torcont}|s|begin;
+                break;
+        case DONTCALL:
+		goto ${dontcont}|s|begin;
+                break;
+        case BUSY:
+                Voicemail(b${ext});
+                break;
+        case ANSWER:
+		break;
+        case NOANSWER:
+                Voicemail(u${ext});
+                break;
+        default:
+                Voicemail(u${ext});
+        }
+}
+
+
+macro std-priv-exten_54( dev, ext , timeout, opts, torcont, dontcont ) 
+{
+        Dial(${dev},${timeout},${opts});
+	NoOp(${DIALSTATUS} was chosen);
+        switch(${DIALSTATUS}) 
+		{
+        case TORTURE:
+		goto ${torcont}|s|begin;
+                break;
+        case DONTCALL:
+		goto ${dontcont}|s|begin;
+                break;
+        case BUSY:
+                Voicemail(b${ext});
+                break;
+        case ANSWER:
+		break;
+        case NOANSWER:
+                Voicemail(u${ext});
+                break;
+        default:
+                Voicemail(u${ext});
+        }
+}
+
+
+macro std-priv-exten_55( dev, ext , timeout, opts, torcont, dontcont ) 
+{
+        Dial(${dev},${timeout},${opts});
+	NoOp(${DIALSTATUS} was chosen);
+        switch(${DIALSTATUS}) 
+		{
+        case TORTURE:
+		goto ${torcont}|s|begin;
+                break;
+        case DONTCALL:
+		goto ${dontcont}|s|begin;
+                break;
+        case BUSY:
+                Voicemail(b${ext});
+                break;
+        case ANSWER:
+		break;
+        case NOANSWER:
+                Voicemail(u${ext});
+                break;
+        default:
+                Voicemail(u${ext});
+        }
+}
+
+
+macro std-priv-exten_56( dev, ext , timeout, opts, torcont, dontcont ) 
+{
+        Dial(${dev},${timeout},${opts});
+	NoOp(${DIALSTATUS} was chosen);
+        switch(${DIALSTATUS}) 
+		{
+        case TORTURE:
+		goto ${torcont}|s|begin;
+                break;
+        case DONTCALL:
+		goto ${dontcont}|s|begin;
+                break;
+        case BUSY:
+                Voicemail(b${ext});
+                break;
+        case ANSWER:
+		break;
+        case NOANSWER:
+                Voicemail(u${ext});
+                break;
+        default:
+                Voicemail(u${ext});
+        }
+}
+
+
+macro std-priv-exten_57( dev, ext , timeout, opts, torcont, dontcont ) 
+{
+        Dial(${dev},${timeout},${opts});
+	NoOp(${DIALSTATUS} was chosen);
+        switch(${DIALSTATUS}) 
+		{
+        case TORTURE:
+		goto ${torcont}|s|begin;
+                break;
+        case DONTCALL:
+		goto ${dontcont}|s|begin;
+                break;
+        case BUSY:
+                Voicemail(b${ext});
+                break;
+        case ANSWER:
+		break;
+        case NOANSWER:
+                Voicemail(u${ext});
+                break;
+        default:
+                Voicemail(u${ext});
+        }
+}
+
+
+macro std-priv-exten_58( dev, ext , timeout, opts, torcont, dontcont ) 
+{
+        Dial(${dev},${timeout},${opts});
+	NoOp(${DIALSTATUS} was chosen);
+        switch(${DIALSTATUS}) 
+		{
+        case TORTURE:
+		goto ${torcont}|s|begin;
+                break;
+        case DONTCALL:
+		goto ${dontcont}|s|begin;
+                break;
+        case BUSY:
+                Voicemail(b${ext});
+                break;
+        case ANSWER:
+		break;
+        case NOANSWER:
+                Voicemail(u${ext});
+                break;
+        default:
+                Voicemail(u${ext});
+        }
+}
+
+
+macro std-priv-exten_59( dev, ext , timeout, opts, torcont, dontcont ) 
+{
+        Dial(${dev},${timeout},${opts});
+	NoOp(${DIALSTATUS} was chosen);
+        switch(${DIALSTATUS}) 
+		{
+        case TORTURE:
+		goto ${torcont}|s|begin;
+                break;
+        case DONTCALL:
+		goto ${dontcont}|s|begin;
+                break;
+        case BUSY:
+                Voicemail(b${ext});
+                break;
+        case ANSWER:
+		break;
+        case NOANSWER:
+                Voicemail(u${ext});
+                break;
+        default:
+                Voicemail(u${ext});
+        }
+}
+
+
+macro std-priv-exten_60( dev, ext , timeout, opts, torcont, dontcont ) 
+{
+        Dial(${dev},${timeout},${opts});
+	NoOp(${DIALSTATUS} was chosen);
+        switch(${DIALSTATUS}) 
+		{
+        case TORTURE:
+		goto ${torcont}|s|begin;
+                break;
+        case DONTCALL:
+		goto ${dontcont}|s|begin;
+                break;
+        case BUSY:
+                Voicemail(b${ext});
+                break;
+        case ANSWER:
+		break;
+        case NOANSWER:
+                Voicemail(u${ext});
+                break;
+        default:
+                Voicemail(u${ext});
+        }
+}
+
+
+macro std-priv-exten_61( dev, ext , timeout, opts, torcont, dontcont ) 
+{
+        Dial(${dev},${timeout},${opts});
+	NoOp(${DIALSTATUS} was chosen);
+        switch(${DIALSTATUS}) 
+		{
+        case TORTURE:
+		goto ${torcont}|s|begin;
+                break;
+        case DONTCALL:
+		goto ${dontcont}|s|begin;
+                break;
+        case BUSY:
+                Voicemail(b${ext});
+                break;
+        case ANSWER:
+		break;
+        case NOANSWER:
+                Voicemail(u${ext});
+                break;
+        default:
+                Voicemail(u${ext});
+        }
+}
+
+
+macro std-priv-exten_62( dev, ext , timeout, opts, torcont, dontcont ) 
+{
+        Dial(${dev},${timeout},${opts});
+	NoOp(${DIALSTATUS} was chosen);
+        switch(${DIALSTATUS}) 
+		{
+        case TORTURE:
+		goto ${torcont}|s|begin;
+                break;
+        case DONTCALL:
+		goto ${dontcont}|s|begin;
+                break;
+        case BUSY:
+                Voicemail(b${ext});
+                break;
+        case ANSWER:
+		break;
+        case NOANSWER:
+                Voicemail(u${ext});
+                break;
+        default:
+                Voicemail(u${ext});
+        }
+}
+
+
+macro std-priv-exten_63( dev, ext , timeout, opts, torcont, dontcont ) 
+{
+        Dial(${dev},${timeout},${opts});
+	NoOp(${DIALSTATUS} was chosen);
+        switch(${DIALSTATUS}) 
+		{
+        case TORTURE:
+		goto ${torcont}|s|begin;
+                break;
+        case DONTCALL:
+		goto ${dontcont}|s|begin;
+                break;
+        case BUSY:
+                Voicemail(b${ext});
+                break;
+        case ANSWER:
+		break;
+        case NOANSWER:
+                Voicemail(u${ext});
+                break;
+        default:
+                Voicemail(u${ext});
+        }
+}
+
+
+macro std-priv-exten_64( dev, ext , timeout, opts, torcont, dontcont ) 
+{
+        Dial(${dev},${timeout},${opts});
+	NoOp(${DIALSTATUS} was chosen);
+        switch(${DIALSTATUS}) 
+		{
+        case TORTURE:
+		goto ${torcont}|s|begin;
+                break;
+        case DONTCALL:
+		goto ${dontcont}|s|begin;
+                break;
+        case BUSY:
+                Voicemail(b${ext});
+                break;
+        case ANSWER:
+		break;
+        case NOANSWER:
+                Voicemail(u${ext});
+                break;
+        default:
+                Voicemail(u${ext});
+        }
+}
+
+
+macro std-priv-exten_65( dev, ext , timeout, opts, torcont, dontcont ) 
+{
+        Dial(${dev},${timeout},${opts});
+	NoOp(${DIALSTATUS} was chosen);
+        switch(${DIALSTATUS}) 
+		{
+        case TORTURE:
+		goto ${torcont}|s|begin;
+                break;
+        case DONTCALL:
+		goto ${dontcont}|s|begin;
+                break;
+        case BUSY:
+                Voicemail(b${ext});
+                break;
+        case ANSWER:
+		break;
+        case NOANSWER:
+                Voicemail(u${ext});
+                break;
+        default:
+                Voicemail(u${ext});
+        }
+}
+
+
+macro std-priv-exten_66( dev, ext , timeout, opts, torcont, dontcont ) 
+{
+        Dial(${dev},${timeout},${opts});
+	NoOp(${DIALSTATUS} was chosen);
+        switch(${DIALSTATUS}) 
+		{
+        case TORTURE:
+		goto ${torcont}|s|begin;
+                break;
+        case DONTCALL:
+		goto ${dontcont}|s|begin;
+                break;
+        case BUSY:
+                Voicemail(b${ext});
+                break;
+        case ANSWER:
+		break;
+        case NOANSWER:
+                Voicemail(u${ext});
+                break;
+        default:
+                Voicemail(u${ext});
+        }
+}
+
+
+macro std-priv-exten_67( dev, ext , timeout, opts, torcont, dontcont ) 
+{
+        Dial(${dev},${timeout},${opts});
+	NoOp(${DIALSTATUS} was chosen);
+        switch(${DIALSTATUS}) 
+		{
+        case TORTURE:
+		goto ${torcont}|s|begin;
+                break;
+        case DONTCALL:
+		goto ${dontcont}|s|begin;
+                break;
+        case BUSY:
+                Voicemail(b${ext});
+                break;
+        case ANSWER:
+		break;
+        case NOANSWER:
+                Voicemail(u${ext});
+                break;
+        default:
+                Voicemail(u${ext});
+        }
+}
+
+
+macro std-priv-exten_68( dev, ext , timeout, opts, torcont, dontcont ) 
+{
+        Dial(${dev},${timeout},${opts});
+	NoOp(${DIALSTATUS} was chosen);
+        switch(${DIALSTATUS}) 
+		{
+        case TORTURE:
+		goto ${torcont}|s|begin;
+                break;
+        case DONTCALL:
+		goto ${dontcont}|s|begin;
+                break;
+        case BUSY:
+                Voicemail(b${ext});
+                break;
+        case ANSWER:
+		break;
+        case NOANSWER:
+                Voicemail(u${ext});
+                break;
+        default:
+                Voicemail(u${ext});
+        }
+}
+
+
+macro std-priv-exten_69( dev, ext , timeout, opts, torcont, dontcont ) 
+{
+        Dial(${dev},${timeout},${opts});
+	NoOp(${DIALSTATUS} was chosen);
+        switch(${DIALSTATUS}) 
+		{
+        case TORTURE:
+		goto ${torcont}|s|begin;
+                break;
+        case DONTCALL:
+		goto ${dontcont}|s|begin;
+                break;
+        case BUSY:
+                Voicemail(b${ext});
+                break;
+        case ANSWER:
+		break;
+        case NOANSWER:
+                Voicemail(u${ext});
+                break;
+        default:
+                Voicemail(u${ext});
+        }
+}
+
+
+macro std-priv-exten_70( dev, ext , timeout, opts, torcont, dontcont ) 
+{
+        Dial(${dev},${timeout},${opts});
+	NoOp(${DIALSTATUS} was chosen);
+        switch(${DIALSTATUS}) 
+		{
+        case TORTURE:
+		goto ${torcont}|s|begin;
+                break;
+        case DONTCALL:
+		goto ${dontcont}|s|begin;
+                break;
+        case BUSY:
+                Voicemail(b${ext});
+                break;
+        case ANSWER:
+		break;
+        case NOANSWER:
+                Voicemail(u${ext});
+                break;
+        default:
+                Voicemail(u${ext});
+        }
+}
+
+
+macro std-priv-exten_71( dev, ext , timeout, opts, torcont, dontcont ) 
+{
+        Dial(${dev},${timeout},${opts});
+	NoOp(${DIALSTATUS} was chosen);
+        switch(${DIALSTATUS}) 
+		{
+        case TORTURE:
+		goto ${torcont}|s|begin;
+                break;
+        case DONTCALL:
+		goto ${dontcont}|s|begin;
+                break;
+        case BUSY:
+                Voicemail(b${ext});
+                break;
+        case ANSWER:
+		break;
+        case NOANSWER:
+                Voicemail(u${ext});
+                break;
+        default:
+                Voicemail(u${ext});
+        }
+}
+
+
+macro std-priv-exten_72( dev, ext , timeout, opts, torcont, dontcont ) 
+{
+        Dial(${dev},${timeout},${opts});
+	NoOp(${DIALSTATUS} was chosen);
+        switch(${DIALSTATUS}) 
+		{
+        case TORTURE:
+		goto ${torcont}|s|begin;
+                break;
+        case DONTCALL:
+		goto ${dontcont}|s|begin;
+                break;
+        case BUSY:
+                Voicemail(b${ext});
+                break;
+        case ANSWER:
+		break;
+        case NOANSWER:
+                Voicemail(u${ext});
+                break;
+        default:
+                Voicemail(u${ext});
+        }
+}
+
+
+macro std-priv-exten_73( dev, ext , timeout, opts, torcont, dontcont ) 
+{
+        Dial(${dev},${timeout},${opts});
+	NoOp(${DIALSTATUS} was chosen);
+        switch(${DIALSTATUS}) 
+		{
+        case TORTURE:
+		goto ${torcont}|s|begin;
+                break;
+        case DONTCALL:
+		goto ${dontcont}|s|begin;
+                break;
+        case BUSY:
+                Voicemail(b${ext});
+                break;
+        case ANSWER:
+		break;
+        case NOANSWER:
+                Voicemail(u${ext});
+                break;
+        default:
+                Voicemail(u${ext});
+        }
+}
+
+
+macro std-priv-exten( dev, ext , timeout, opts, torcont, dontcont ) 
+{
+        Dial(${dev},${timeout},${opts});
+	NoOp(${DIALSTATUS} was chosen);
+        switch(${DIALSTATUS}) 
+		{
+        case TORTURE:
+		goto ${torcont}|s|begin;
+                break;
+        case DONTCALL:
+		goto ${dontcont}|s|begin;
+                break;
+        case BUSY:
+                Voicemail(b${ext});
+                break;
+        case ANSWER:
+		break;
+        case NOANSWER:
+                Voicemail(u${ext});
+                break;
+        default:
+                Voicemail(u${ext});
+        }
+}
+
+macro fillcidname()
+{
+        if( "${CALLERID(number)}" = "" )   // nothing to work with, quit!!!
+                return;
+        Set(cidn=${DB(cidname/${CALLERID(num)})});
+        if( "${CALLERID(name)}" != "" )
+        {
+                if( ("${cidn}" = "Privacy Manager" & "${CALLERID(name)}" != "Privacy Manager") | "${cidn}" = "" ) // if the entry isn't in the database, 
+                                                                                // or if an entry exists, and it's "Privacy Manager", empty, (or add other useless possibilities).
+                { 
+                       Set(DB(cidname/${CALLERID(number)})=${CALLERID(name)});     // then set or override what's in the DB
+                }
+        }
+        // Now, we fill in the callerid info from the incoming entry, if it's stuff worth using
+        // Ignore fundamentally semi-anonymous information from local cell phones
+        // if the db has an entry for this number, and it's not a canned string from a cell phone company
+        if(  ( "${cidn}" != "" ) & ( "${CALLERID(name)}" = "" 
+                                                  | "${CALLERID(name)}" = "CODY,WY        "    
+                                                  | "${CALLERID(name)}" = "POWELL,WY      "    
+                                                  | "${CALLERID(name)}" = "WIRELESS CALLER"  
+                                                  | "${CALLERID(name)}" = "SUBSCRIBER,WIRE"  
+                                                  | "${CALLERID(name)}" = "CELLULAR ONE"  
+                                                  | "${CALLERID(name)}" = "Cellular One Customer"    
+                                                  | "${CALLERID(name)}" = "CELLULAR ONE   "    
+                                                  | "${CALLERID(name)}" = "Privacy Manager" 
+                                                  | "${CALLERID(name)}" = "RIVERTON,WY    "  
+                                                  | "${CALLERID(name)}" = "BASIN,WY       "  
+                                                  | "${CALLERID(name)}" = "BILLINGS,MT    "
+                                                  | "${CALLERID(name)}" = "PROVO,UT       "  
+                                                  | "${CALLERID(name)}" = "TOLL FREE      " ) )  // put stuff in the above, that the phone company tends to put in your callerid, 
+                                                                                                 // that you would rather override with DB info
+                                                                                                 // there's no way to guess them all, but you can get the most popular ones...
+                                                                                                 // why cell phones can't do CID like everybody else, ....?
+        {    
+                Set(CALLERID(name)=${cidn});  // Override what the phone company provides with what's in the DB for this number.
+        }
+}
+
+macro ciddial(dialnum, lookup, waittime, dialopts, ddev)
+{
+	Set(cidnu=${CALLERID(num)});
+	Set(cidn=${DB(cidname/${lookup})});
+	Set(CALLERID(name)=${cidn});
+	Dial(${ddev}/${dialnum}|${waittime}|${dialopts});
+	if( "${DIALSTATUS}" = "CHANUNAVAIL" )
+	{
+		BackGround(try_voip);
+		CALLERID(num)=7075679201;
+		Dial(SIP/1${lookup}@tctwest,${waittime},${dialopts});
+		if( "${DIALSTATUS}" = "CHANUNAVAIL" )
+		{
+			BackGround(try_cell);
+			CALLERID(num)=${cidnu}; // put the original number back 
+			Dial(Zap/2/${lookup},${waittime},${dialopts});
+		}
+	}
+}
+
+macro ciddial3(dialnum, lookup, waittime, dialopts, ddev)
+{
+	Set(cidnu=${CALLERID(num)});
+	Set(cidn=${DB(cidname/${lookup})});
+	Set(CALLERID(name)=${cidn});
+	Dial(${ddev}/${dialnum}|${waittime}|${dialopts});
+	if( "${DIALSTATUS}" = "CHANUNAVAIL" )
+	{
+		BackGround(try_cell);
+		Dial(Zap/2/${lookup},${waittime},${dialopts});
+	}
+}
+
+macro ciddial2(dialnum, lookup, waittime, dialopts, ddev) // give priority to tctwest, then the ZAP in emergencies
+{
+	Set(cidn=${DB(cidname/${lookup})});
+	Set(cidnu=${CALLERID(num)});
+	Set(CALLERID(name)=${cidn});
+	Set(CALLERID(num)=7075679201);
+	Dial(SIP/1${lookup}@tctwest,${waittime},${dialopts});
+	if( "${DIALSTATUS}" = "CHANUNAVAIL" )
+	{
+		Set(CALLERID(num)=${cidnu}); // put the original number back 
+		BackGround(try_zap);
+		Dial(${ddev}/${dialnum},${waittime}|${dialopts});
+		if( "${DIALSTATUS}" = "CHANUNAVAIL" )
+		{
+			BackGround(try_cell);
+			Dial(Zap/2/${lookup},${waittime},${dialopts});
+		}
+	}
+}
+
+macro callerid-liar()
+{
+	TrySystem(/usr/bin/play /var/lib/asterisk/sounds/priv-callerintros/LIAR.gsm&);
+	Background(priv-liar);  // Script: OOOps! Sorry! I don't allow men with ski masks pulled over their 
+                            //         faces to get in the front door, and unidentified callers won't fair
+                            //         any better. You entered *MY* phone number. That won't work.
+                            //         If you are telemarketing, cross me off the list, and don't call again.
+                            //         If you did this by mistake, forgive my defenses, and call again.
+                           // Alternate: (priv-liar2)
+				   // Script: You have chosen to try to deceive my system and withold your CallerID,
+                                   //           by entering my own phone number as YOUR CallerID. I find this 
+                                   //           offensive because you are being dishonest. I will not do business nor
+                                   //           waste my time talking to anyone who is less than honest and forthcoming.
+                                   //           Take me off your call list and do not call me again.
+	Hangup();
+}
+
+macro callerid-bad()
+{
+	mycid=${CALLERID(num)}:"1([0-9]+)";
+ 	Set(CALLERID(num)=${mycid});
+ 	Wait(0);
+}
+
+context privacyManagerFailed {
+ 	s => {
+		begin:
+ 		Background(PrivManInstructions);  // Script: OOps, that didn't go well. You need to enter *your* area code, and *your* 7 digit 
+                                               // phone number, for a total of 10 digits, or you'll be handed over to the monkeys. Let's
+                                               // try this again, and hopefully you can get past our front-line defenses!
+ 		PrivacyManager();
+ 		if( "${PRIVACYMGRSTATUS}" = "FAILED" )
+ 		{
+ 			Background(tt-allbusy);
+			Background(tt-somethingwrong);
+			Background(tt-monkeysintro);
+ 			Background(tt-monkeys);
+ 			Background(tt-weasels);
+ 			Hangup();
+ 		}
+ 		else
+ 		{
+ 			goto homeline|s|postPriv;
+ 		}
+ 	}
+}
+
+// Some comments
+// Some more comments
+
+context homeline {
+	s => {
+	begin:
+		Answer();
+		Set(repeatcount=0);
+		Zapateller(nocallerid);
+		PrivacyManager();
+		if( "${PRIVACYMGRSTATUS}" = "FAILED" )
+		{
+			TrySystem(/usr/bin/play /var/lib/asterisk/sounds/privmanfailed.gsm);
+			&std-priv-exten(Zap/3r1&Zap/5r1,2,25,mtw,telemarket,telemarket);
+			Hangup();
+			return;
+//			goto privacyManagerFailed|s|begin;
+		}
+	postPriv:
+		&fillcidname();
+		Set(CONFCIDNA=${CALLERID(name)});
+		Set(CONFCIDNU=${CALLERID(num)});
+		AGI(callall);
+		AGI(submit-announce.agi);
+		if( "${CALLERID(num)}" : "1" )
+		{
+			&callerid-bad();
+		}
+		if( "${CALLERID(num)}"  = "7077577685" & "${CALLERID(name)}" : "Privacy Manager" )
+		{
+			&callerid-liar();
+		}
+		TrySystem(/usr/local/bin/who-is-it ${CALLERID(num)} "${CALLERID(name)}"&);
+		Set(lds=${DB(playlds/${CALLERID(num)})});
+		if( "${lds}" = "1" )
+		{
+			SetMusicOnHold(mohlds);
+		}
+		direct=${DB(DirectCall/${CALLERID(num)})};
+		if( "${direct}" != "" & ${direct} != 0 )
+		{
+			verbose(direct is XXX#${direct}XXXX);
+			Playback(greetings/direct); // Welcome to the Murphy residence. This system will automatically try to connect you to...
+			Playback(/var/spool/asterisk/voicemail/default/${direct}/greet);
+			TrySystem(/usr/bin/play /var/lib/asterisk/sounds/call-for.gsm);
+			TrySystem(/usr/bin/play /var/spool/asterisk/voicemail/default/${direct}/greet.wav&);
+			switch(${direct})
+			{
+			case 1: //Steve
+				&std-priv-exten(Zap/6r3&Sip/murf,1,25,mpA(beep)tw,telemarket,telemarket);
+				goto s|loopback;
+			case 2: //Sonya
+		                &std-priv-exten(Zap/3r1&Zap/5r1,2,25,mtw,telemarket,telemarket);
+				goto s|loopback;
+			default: // all the kids
+				Set(z=${direct}-2);
+				goto homeline-kids|${z}|1;
+			}
+		}
+	loopback:
+		ifTime(*|*|20-25|dec) 
+		{ 
+			Playback(greetings/christmas); 
+		}
+		else ifTime(*|*|31|dec) 
+		{	 
+			Playback(greetings/newyear); 
+		}
+		else ifTime(*|*|1|jan)
+		{
+			Playback(greetings/newyear);
+		}
+		else ifTime(*|*|14|feb)
+		{
+			Playback(greetings/valentines);
+		}
+		else ifTime(*|*|17|mar) 
+		{
+			Playback(greetings/stPat);
+		}
+		else ifTime(*|*|31|oct) 
+		{
+			Playback(greetings/halloween);
+		}
+		else ifTime(*|mon|15-21|jan) 
+		{
+			Playback(greetings/mlkDay);
+		}
+		else ifTime(*|thu|22-28|nov)
+		{
+			Playback(greetings/thanksgiving);
+		}
+		else ifTime(*|mon|25-31|may)
+		{
+			Playback(greetings/memorial);
+		}
+		else ifTime(*|mon|1-7|sep)
+		{
+			Playback(greetings/labor);
+		}
+		else ifTime(*|mon|15-21|feb)
+		{
+			Playback(greetings/president);
+		}
+		else ifTime(*|sun|8-14|may)
+		{
+			Playback(greetings/mothers);
+		}
+		else ifTime(*|sun|15-21|jun)
+		{
+			Playback(greetings/fathers);
+		} 
+		else 
+		{
+			Playback(greetings/hello);   // None of the above? Just a plain hello will do
+		}  
+		Background(murphy-homeline-intro1);  // Script: Hello-- Welcome to the Murphy's! If you already know what
+                                                //  option you want, you don't have to wait for this entire spiel-- just
+                                                //  have at it.
+                                                //  If you are calling because this number is on a list of some sort, dial 6.
+                                                //  If you want Sonya, dial 1.
+                                                //  If you want one of the kids, dial 2.
+                                                //  If you want Steve, dial 3.
+						//  to play with your introduction, dial 5.
+                                                //  If we don't seem to be giving you the time of day, try 7.
+                                                //  Have a good day!
+		
+	}
+	1 => {  // Sonya
+			TrySystem(/usr/bin/play /var/lib/asterisk/sounds/call-for.gsm);
+			TrySystem(/usr/bin/play /var/spool/asterisk/voicemail/default/2/greet.wav&);
+			&std-priv-exten(Zap/3r1&Zap/5r1,2,25,mtw,telemarket,telemarket);
+			goto s|loopback;
+	}
+	2 => {  // Kids
+			goto homeline-kids|s|begin;
+	}
+	21 => {
+		Dial(IAX2/seaniax,20,T);
+		}
+	3 => {  // Steve
+			&std-priv-exten(Zap/6r3&Sip/murf,1,25,mpA(beep)tw,telemarket,telemarket);
+			goto s|loopback;
+	}
+	4 => {  // Voicemail 
+			VoicemailMain();
+			goto s|loopback;
+	}
+	5 => {   // play with intro
+			goto home-introduction|s|begin;
+	}
+	6 => {    // Telemarketers
+			goto telemarket|s|begin;
+	}
+	7 => {    // time of day, riddle
+			agi(tts-riddle.agi);
+			Background(gsm/what-time-it-is2);
+			SayUnixTime();
+			goto s|loopback;
+	}
+	792 => {   // Page All
+			goto pageall|s|begin;
+	}
+	793 => { // check the tone recognition
+			Read(zz,,0,,1,0);
+			SayDigits(${zz});
+	}
+	t => {
+		Set(repeatcount=${repeatcount} + 1);
+		if( ${repeatcount} < 3 )
+		{
+			goto s|loopback;  // just loopback isn't enough
+		}
+		Hangup();
+	}
+	i => {
+		Background(invalid);
+		goto s|loopback;
+	}
+	o => {
+		Congestion();
+	}
+	fax => {
+		Dial(Zap/4);
+	}
+}
+
+// Some comments
+// Some more comments
+
+context pageall {
+	s => {
+	begin:
+		AGI(callall);
+		MeetMe(5555,dtqp);
+		MeetMeAdmin(5555,K);
+		Hangup();
+	}
+
+	h => {
+	begin:
+		MeetMeAdmin(5555,K);
+		Background(conf-muted);
+		Hangup();
+	}
+}
+
+// Some comments
+// Some more comments
+
+context add-to-conference {
+	start => {
+		NoCDR();
+		MeetMe(5555,dmqp);
+	}
+	h => {
+		Hangup();
+	}
+}
+
+context home-introduction {
+	s => {
+	begin:
+		Background(intro-options);   // Script: To hear your Introduction, dial 1.
+						//         to record a new introduction, dial 2.
+						//         to return to the main menu, dial 3.
+						//         to hear what this is all about, dial 4.
+	}
+	1 => {
+		Playback(priv-callerintros/${CALLERID(num)});
+		goto s|begin;
+	}
+	2 => {
+		goto home-introduction-record|s|begin;
+	}
+	3 => {
+		goto homeline|s|loopback;
+	}
+	4 => {
+		Playback(intro-intro);     // Script:
+				// This may seem a little strange, but it really is a neat
+				// thing, both for you and for us. I've taped a short introduction
+				// for many of the folks who normally call us. Using the Caller ID
+				// from each incoming call, the system plays the introduction
+				// for that phone number over a speaker, just as the call comes in.
+				// This helps the folks
+				// here in the house more quickly determine who is calling.
+				// and gets the right ones to gravitate to the phone.
+				// You can listen to, and record a new intro for your phone number
+				// using this menu.
+		goto s|begin;
+	}
+	t => {
+		goto s|begin;
+	}
+	i => {
+		Background(invalid);
+		goto s|begin;
+	}
+	o => {
+		goto s|begin;
+	}
+}
+
+context home-introduction-record {
+	s => {
+	begin:
+		Background(intro-record-choices);    // Script:
+				//      If you want some advice about recording your
+				// 	introduction, dial 1. 
+				//      otherwise, dial 2, and introduce yourself after
+				//      the beep.
+	}
+	1 => {
+	Playback(intro-record);
+				//	Your introduction should be short and sweet and crisp.
+				//	Your introduction will be limited to 10 seconds.
+				//	This is NOT meant to be a voice mail message, so
+				//	please, don't say anything about why you are calling.
+				//	After we are done making the recording, your introduction
+				//	will be saved for playback. 
+				//	If you are the only person that would call from this number, 
+				//	please state your name.  Otherwise, state your business
+				//	or residence name instead. For instance, if you are 
+				//	friend of the family, say, Olie McPherson, and both
+				//	you and your kids might call here a lot, you might
+				//	say: "This is the distinguished Olie McPherson Residence!"
+				//	If you are the only person calling, you might say this:
+				//	"This is the illustrious Kermit McFrog! Pick up the Phone, someone!!"
+				//	If you are calling from a business, you might pronounce a more sedate introduction,like,
+				//	"Fritz from McDonalds calling.", or perhaps the more original introduction:
+				//	"John, from the Park County Morgue. You stab 'em, we slab 'em!".
+				//	Just one caution: the kids will hear what you record every time
+				//	you call. So watch your language!
+				//	I will begin recording after the tone. 
+				//	When you are done, hit the # key. Gather your thoughts and get 
+				//	ready. Remember, the # key will end the recording, and play back
+				//      your intro. Good Luck, and Thank you!"
+		goto 2|begin;
+	}
+	2 => {
+		begin:
+		Background(intro-start);
+				//  OK, here we go! After the beep, please give your introduction.
+		Background(beep);
+		Record(priv-callerintros/${CALLERID(num)}:gsm,3);
+		Background(priv-callerintros/${CALLERID(num)});
+		goto home-introduction|s|begin;
+	}
+	t => {
+		goto s|begin;
+	}
+	i => {
+		Background(invalid);
+		goto s|begin;
+	}
+	o => {
+		goto s|begin;
+	}
+}
+
+context homeline-kids {
+	s => {
+	begin:
+		Background(murphy-homeline-kids);        //  Which Kid? 1=Sean, 2:Eric, 3:Ryan, 4:Kyle, 5:Amber, 6:Alex, 7:Neal
+	}
+	1 => {  // SEAN
+			TrySystem(/usr/bin/play /var/lib/asterisk/sounds/call-for.gsm);
+			TrySystem(/usr/bin/play /var/spool/asterisk/voicemail/default/3/greet.wav&);
+			// &std-priv-exten(Zap/3r2&Zap/5r2,3,35,mtw,telemarket,telemarket);
+			&std-priv-exten(IAX2/seaniax&Zap/5r2,3,35,mtw,telemarket,telemarket);
+			goto homeline|s|loopback;
+	}
+	2 => {  // ERIC
+			TrySystem(/usr/bin/play /var/lib/asterisk/sounds/call-for.gsm);
+			TrySystem(/usr/bin/play /var/spool/asterisk/voicemail/default/4/greet.wav&);
+			Voicemail(u4);
+			goto homeline|s|loopback;
+			
+			// SetMusicOnHold(erics);
+			// TrySystem(/usr/bin/play /var/lib/asterisk/sounds/call-for.gsm);
+			// TrySystem(/usr/bin/play /var/spool/asterisk/voicemail/default/4/greet.wav&);
+			// &std-priv-exten(Zap/3r2&Zap/5r2,4,35,mtw,telemarket,telemarket);
+			// goto homeline|s|loopback;
+	}
+	3 => {  // RYAN
+			TrySystem(/usr/bin/play /var/lib/asterisk/sounds/call-for.gsm);
+			TrySystem(/usr/bin/play /var/spool/asterisk/voicemail/default/5/greet.wav&);
+			&std-priv-exten(Zap/3r2&Zap/5r2,5,35,mtw,telemarket,telemarket);
+			goto homeline|s|loopback;
+	}
+	4 => {  // KYLE
+			TrySystem(/usr/bin/play /var/lib/asterisk/sounds/call-for.gsm);
+			TrySystem(/usr/bin/play /var/spool/asterisk/voicemail/default/6/greet.wav&);
+			&std-priv-exten(Zap/3r2&Zap/5r2,6,35,mtw,telemarket,telemarket);
+			goto homeline|s|loopback;
+	}
+	5 => {
+			TrySystem(/usr/bin/play /var/lib/asterisk/sounds/call-for.gsm);
+			TrySystem(/usr/bin/play /var/spool/asterisk/voicemail/default/7/greet.wav&);
+			&std-priv-exten(Zap/3r2&Zap/5r2,7,35,mtw,telemarket,telemarket);
+			goto homeline|s|loopback;
+			
+	}
+	6 => {
+			TrySystem(/usr/bin/play /var/lib/asterisk/sounds/call-for.gsm);
+			TrySystem(/usr/bin/play /var/spool/asterisk/voicemail/default/8/greet.wav&);
+			&std-priv-exten(Zap/3r2&Zap/5r2,8,35,mtw,telemarket,telemarket);
+			goto homeline|s|loopback;
+	}
+	7 => {
+			TrySystem(/usr/bin/play /var/lib/asterisk/sounds/call-for.gsm);
+			TrySystem(/usr/bin/play /var/spool/asterisk/voicemail/default/9/greet.wav&);
+			&std-priv-exten(Zap/3r2&Zap/5r2,9,35,mtw,telemarket,telemarket);
+			goto homeline|s|loopback;
+	}
+	t => {
+		goto s|begin;
+	}
+	i => {
+		Background(invalid);
+		goto s|begin;
+	}
+	o => {
+		goto s|begin;
+	}
+}
+
+context voipworkline {
+	s => {
+	begin:
+		Answer();
+		TrySystem(/usr/local/bin/who-is-it ${CALLERID(num)} "${CALLERID(name)}"&);
+		goto workline|s|loopback;
+	}
+	7075679201 => {
+		Answer();
+		TrySystem(/usr/local/bin/who-is-it ${CALLERID(num)} "${CALLERID(name)}"&);
+		goto workline|s|loopback;
+	}
+}
+
+context workline {
+	s => {
+	begin:
+		Answer();
+		Wait(1);
+		Set(repeatcount=0);
+		Zapateller(nocallerid);
+//              PrivacyManager();
+//              if( "${PRIVACYMGRSTATUS}" = "FAILED" )
+//              {
+//                     goto privacyManagerFailed|s|begin;
+//              }
+		&fillcidname();
+		TrySystem(/usr/local/bin/who-is-it ${CALLERID(num)} "${CALLERID(name)}"&);
+	loopback:
+		Background(greetings/greeting);  //script: Hello
+		Background(murphy-office-intro1); //script: welcome to Steve Murphy's office. If you are dialing
+                                              //  this number because it was on a calling list of any sort, dial 6.
+                                              // Otherwise, dial 1, and hopefully, you will reach Steve.
+	}
+	1 => {
+		TrySystem(/usr/bin/play /var/lib/asterisk/sounds/call-for.gsm);
+		TrySystem(/usr/bin/play /var/spool/asterisk/voicemail/default/1/greet.wav&);
+		
+		&std-priv-exten(Zap/6&Sip/murf,1,30,mtw,telemarket,telemarket);
+		goto s|loopback;		
+	}
+	4 => {
+		VoicemailMain(); 
+		goto s|loopback;
+	}
+	6 => {
+		goto telemarket|s|begin;
+	}
+	793 => { // check the tone recognition
+			Read(zz,,0,,1,0);
+			SayDigits(${zz});
+	}
+	t => {
+		repeatcount=${repeatcount} + 1;
+		if( ${repeatcount} < 3 )
+		{
+			goto s|loopback;  // just loopback isn't enough
+		}
+		Hangup();
+	}
+	i => {
+		Background(invalid); 
+		goto s|loopback;
+	}
+	o => {
+		Congestion();
+	}
+	fax => {
+		Answer();
+		Dial(Zap/4);
+	}
+}
+
+context dialFWD {
+	ignorepat => 8;
+	ignorepat => 9;
+	_83. => {
+		Set(CALLERID(name)=${FWDCIDNAME});
+		Dial(IAX2/${FWDNUMBER}:${FWDPASSWORD}@iax2.fwdnet.net/${EXTEN:2},60,r);
+		Congestion();
+	}
+	_82NXX => {
+		Set(CALLERID(name)=${FWDCIDNAME});
+		Dial(IAX2/${FWDNUMBER}:${FWDPASSWORD}@iax2.fwdnet.net/${EXTEN:2},60,r);
+		Congestion();
+	}
+	_92NXX => {
+		Set(CALLERID(name)=${FWDCIDNAME});
+		Dial(IAX2/${FWDNUMBER}:${FWDPASSWORD}@iax2.fwdnet.net/${EXTEN:2},60,r);
+		Congestion();
+	}
+}
+
+context dialiaxtel {
+	ignorepat => 8;
+	ignorepat => 9;
+	_81700NXXXXXX => {
+		Dial(IAX2/zorch:zilchnoodle@iaxtel.com/${EXTEN:1}@iaxtel);
+	}
+	_81800NXXXXXX => {
+		Dial(IAX2/zorch:zilchnoodle@iaxtel.com/${EXTEN:1}@iaxtel);
+	}
+	_91700NXXXXXX => {
+		Dial(IAX2/zorch:zilchnoodle@iaxtel.com/${EXTEN:1}@iaxtel);
+	}
+	_91800NXXXXXX => {
+		Dial(IAX2/zorch:zilchnoodle@iaxtel.com/${EXTEN:1}@iaxtel);
+	}
+
+}
+
+context dialgoiax {
+	ignorepat => 9;
+	_93. => {
+		Set(CALLERID(name)="Joe Worker");
+		Dial(IAX2/878201007658:stickyfinger295@server1.goiax.com/${EXTEN:2},60,r);
+		Congestion();
+	}
+
+}
+
+context homefirst {
+	ignorepat => 9;
+	_91NXXNXXXXXX => {
+		&ciddial(${EXTEN:1},${EXTEN:2},30,TW,Zap/1);
+	}
+	_9754XXXX => {
+		&ciddial(${EXTEN:1},707${EXTEN:1},30,TW,Zap/1);
+	}
+	_9574XXXX => {
+		&ciddial(${EXTEN:1},707${EXTEN:1},30,TW,Zap/1);
+	}
+	_9202XXXX => {
+		&ciddial(${EXTEN:1},707${EXTEN:1},30,TW,Zap/1);
+	}
+	_9219XXXX => {
+		&ciddial(${EXTEN:1},707${EXTEN:1},30,TW,Zap/1);
+	}
+	_9254XXXX => {
+		&ciddial(${EXTEN:1},707${EXTEN:1},30,TW,Zap/1);
+	}
+	_9716XXXX => {
+		&ciddial(${EXTEN:1},707${EXTEN:1},30,TW,Zap/1);
+	}
+	_9NXXXXXX => {
+		&ciddial(1707${EXTEN:1},707${EXTEN:1},30,TW,Zap/1);
+	}
+	_9011. => {
+		&ciddial(${EXTEN:1},${EXTEN:1},30,TW,Zap/1);
+	}
+	_9911 => {
+		Dial(Zap/1/911,30,T);
+	}
+	_9411 => {
+		Dial(Zap/1/411,30,T);
+	}
+}
+
+context workfirst {
+	ignorepat => 9;
+	_91NXXNXXXXXX => {
+		&ciddial2(${EXTEN:1},${EXTEN:2},30,TW,Zap/1);
+	}
+	_9754XXXX => {
+		&ciddial2(${EXTEN:1},707${EXTEN:1},30,TW,Zap/1);
+	}
+	_9574XXXX => {
+		&ciddial2(${EXTEN:1},707${EXTEN:1},30,TW,Zap/1);
+	}
+	_9202XXXX => {
+		&ciddial2(${EXTEN:1},707${EXTEN:1},30,TW,Zap/1);
+	}
+	_9219XXXX => {
+		&ciddial2(${EXTEN:1},707${EXTEN:1},30,TW,Zap/1);
+	}
+	_9254XXXX => {
+		&ciddial2(${EXTEN:1},707${EXTEN:1},30,TW,Zap/1);
+	}
+	_9716XXXX => {
+		&ciddial2(${EXTEN:1},707${EXTEN:1},30,TW,Zap/1);
+	}
+	_9NXXXXXX => {
+		&ciddial2(1707${EXTEN:1},707${EXTEN:1},30,TW,Zap/1);
+	}
+	_9911 => {
+		Dial(Zap/1/911,30,T);
+	}
+	_9411 => {
+		Dial(Zap/1/411,30,T);
+	}
+}
+
+context force_cell {
+	ignorepat => 8;
+	_81NXXNXXXXXX => {
+		&ciddial(${EXTEN:1}#,${EXTEN:2},30,TW,Zap/2);
+	}
+	_8754XXXX => {
+		&ciddial(${EXTEN:1}#,707${EXTEN:1},30,TW,Zap/2);
+	}
+	_8574XXXX => {
+		&ciddial(${EXTEN:1}#,707${EXTEN:1},30,TW,Zap/2);
+	}
+	_8202XXXX => {
+		&ciddial(${EXTEN:1}#,707${EXTEN:1},30,TW,Zap/2);
+	}
+	_8219XXXX => {
+		&ciddial(${EXTEN:1}#,707${EXTEN:1},30,TW,Zap/2);
+	}
+	_8254XXXX => {
+		&ciddial(${EXTEN:1}#,707${EXTEN:1},30,TW,Zap/2);
+	}
+	_8716XXXX => {
+		&ciddial(${EXTEN:1}#,707${EXTEN:1},30,TW,Zap/2);
+	}
+	_8NXXXXXX => {
+		&ciddial(${EXTEN:1}#,707${EXTEN:1},30,TW,Zap/2);
+	}
+	_8911 => {
+		Dial(Zap/1/911|30|T);
+	}
+	_8411 => {
+		Dial(Zap/1/411|30|T);
+	}
+}
+
+context force_home {
+	ignorepat => 8;
+	_81NXXNXXXXXX => {
+		&ciddial3(${EXTEN:1}#,${EXTEN:2},30,TW,Zap/1);
+	}
+	_8754XXXX => {
+		&ciddial3(${EXTEN:1}#,707${EXTEN:1},30,TW,Zap/1);
+	}
+	_8574XXXX => {
+		&ciddial3(${EXTEN:1}#,707${EXTEN:1},30,TW,Zap/1);
+	}
+	_8202XXXX => {
+		&ciddial3(${EXTEN:1}#,707${EXTEN:1},30,TW,Zap/1);
+	}
+	_8219XXXX => {
+		&ciddial3(${EXTEN:1}#,707${EXTEN:1},30,TW,Zap/1);
+	}
+	_8254XXXX => {
+		&ciddial3(${EXTEN:1}#,707${EXTEN:1},30,TW,Zap/1);
+	}
+	_8716XXXX => {
+		&ciddial3(${EXTEN:1}#,707${EXTEN:1},30,TW,Zap/1);
+	}
+	_8NXXXXXX => {
+		&ciddial3(1707${EXTEN:1}#,707${EXTEN:1},30,TW,Zap/1);
+	}
+	_8911 => {
+		Dial(Zap/1/911|30|T);
+	}
+	_8411 => {
+		Dial(Zap/1/411|30|T);
+	}
+}
+
+context homeext {
+	ignorepat => 8;
+	ignorepat => 9;
+	includes {
+		 parkedcalls;
+		 homefirst;
+		 force_cell;
+	}
+	s => {
+	loopback:
+		Wait(0);
+	}
+	1 => {
+		&std-priv-exten(Zap/3&Zap/5,2,35,mtw,telemarket,telemarket);
+		goto s|loopback;
+	}
+	2 => {
+		&std-priv-exten(Zap/6&Zap/5,1,35,mpA(beep3)Tt,telemarket,telemarket);
+		goto s|loopback;
+	}
+	4 => {
+		VoicemailMain();
+	}
+	5 => {
+		Record(recording:gsm);
+		Background(recording);
+	}
+	6 => {
+		Background(recording);
+	}
+	760 => {
+		DateTime();
+		goto s|loopback;
+	}
+	761 => {
+		Record(announcement:gsm);
+		TrySystem(/usr/bin/play /var/lib/asterisk/sounds/announcement.gsm&);
+		goto s|loopback;
+	}
+	762 => {
+		agi(tts-riddle.agi);
+		Background(gsm/what-time-it-is2);
+		SayUnixTime();
+		goto s|loopback;
+	}
+	763 => {
+		Set(CALLERID(num)=);
+		Dial(Zap/6r3,35,mptA(beep3));   //results: it should ALWAYS ask for an intro; the intro should not be left behind
+		Hangup();
+	}
+	764 => {
+		Set(CALLERID(num)=);
+		Dial(Zap/6r3,35,mptnA(beep3));   //results: Don't save the intro; shouldn't anyway if no callerid
+		Hangup();
+	}
+	765 => {
+		Set(CALLERID(num)=);
+		Dial(Zap/6r3,35,mptNA(beep3));   //results: Don't screen if there's CALLERID; it should screen the call.
+		Hangup();
+	}
+	766 => {
+		Dial(Zap/6r3,35,mptNA(beep3));   //results: Don't screen if there's CALLERID; it should screen the call.
+		Hangup();
+	}
+	767 => {
+		Dial(Zap/6r3,35,mptnA(beep3));   //results: Don't save the intro; the interesting case, because callerID should be present.
+		Hangup();
+	}
+	769 => {
+		Playtones(dial);
+		Wait(2);
+		Playtones(busy);
+		Wait(2);
+		Playtones(ring);
+		Wait(2);
+		Playtones(congestion);
+		Wait(2);
+		Playtones(callwaiting);
+		Wait(2);
+		Playtones(dialrecall);
+		Wait(2);
+		Playtones(record);
+		Wait(2);
+		Playtones(info);
+		Wait(5);
+		Hangup();	
+	}
+	790 => {
+		MeetMe(790,p);
+	}
+	792 => {
+		goto pageall|s|begin;
+	}
+	795 => {
+		AGI(wakeup.agi);Congestion();
+	}
+	544716 => {  // Incoming call from FWD
+			TrySystem(/usr/local/bin/who-is-it ${CALLERID(num)} "${CALLERID(name)}"&);
+			goto s|loopback;
+	}
+
+	i => {
+		Background(invalid);
+		goto s|loopback;
+	}
+	o => {
+		goto s|loopback;
+	}
+	t => {
+		Congestion();
+	}
+}
+
+context fromvmhome {
+	1 => {
+		Dial(Zap/6&Sip/murf|20|Tt);
+	}
+	2 => {
+		Dial(Zap/3&Zap/5|20|Tt);
+	}
+	_707202XXXX => {
+		&ciddial(1${EXTEN:3},${EXTEN},30,TW,Zap/1);
+	}
+	_707219XXXX => {
+		&ciddial(1${EXTEN:3},${EXTEN},30,TW,Zap/1);
+	}
+	_707254XXXX => {
+		&ciddial(1${EXTEN:3},${EXTEN},30,TW,Zap/1);
+	}
+	_707716XXXX => {
+		&ciddial(1${EXTEN:3},${EXTEN},30,TW,Zap/1);
+	}
+	_707754XXXX => {
+		&ciddial(${EXTEN:3},${EXTEN},30,TW,Zap/1);
+	}
+	_707574XXXX => {
+		&ciddial(${EXTEN:3},${EXTEN},30,TW,Zap/1);
+	}
+	_NXXNXXXXXX => {
+		&ciddial(1${EXTEN},${EXTEN},30,TW,Zap/1);
+	}
+	_1NXXNXXXXXX => {                                // HAND DIALING
+		&ciddial(${EXTEN},${EXTEN:1},30,TW,Zap/1);
+	}
+	_754XXXX => {
+		&ciddial(${EXTEN},707${EXTEN},30,TW,Zap/1);
+	}
+	_574XXXX => {
+		&ciddial(${EXTEN},707${EXTEN},30,TW,Zap/1);
+	}
+	_NXXXXXX => {
+		&ciddial(1707${EXTEN},707${EXTEN},30,TW,Zap/1);
+	}
+	_911 => {
+		&ciddial(911,911,30,TW,Zap/1);
+	}
+	_411 => {
+		&ciddial(411,411,30,TW,Zap/1);
+	}
+}
+
+context fromvmwork {
+	1 => {
+		Dial(Zap/6&Sip/murf|20|Tt);
+	}
+	2 => {
+		Dial(Zap/3&Zap/5|20|Tt);
+	}
+	_707202XXXX => {
+		&ciddial(1${EXTEN:3},${EXTEN},30,TW,Zap/1);
+	}
+	_707219XXXX => {
+		&ciddial(1${EXTEN:3},${EXTEN},30,TW,Zap/1);
+	}
+	_707254XXXX => {
+		&ciddial(1${EXTEN:3},${EXTEN},30,TW,Zap/1);
+	}
+	_707716XXXX => {
+		&ciddial(1${EXTEN:3},${EXTEN},30,TW,Zap/1);
+	}
+	_707754XXXX => {
+		&ciddial(${EXTEN:3},${EXTEN},30,TW,Zap/1);
+	}
+	_707574XXXX => {
+		&ciddial(${EXTEN:3},${EXTEN},30,TW,Zap/1);
+	}
+	_NXXNXXXXXX => {
+		&ciddial(1${EXTEN},${EXTEN},30,TW,Zap/1);
+	}
+	_1NXXNXXXXXX => {                                // HAND DIALING
+		&ciddial(${EXTEN},${EXTEN:1},30,TW,Zap/1);
+	}
+	_754XXXX => {
+		&ciddial(${EXTEN},707${EXTEN},30,TW,Zap/1);
+	}
+	_574XXXX => {
+		&ciddial(${EXTEN},707${EXTEN},30,TW,Zap/1);
+	}
+	_NXXXXXX => {
+		&ciddial(1707${EXTEN},707${EXTEN},30,TW,Zap/1);
+	}
+	911 => {
+		&ciddial(911,911,30,TW,Zap/1);
+	}
+	411 => {
+		&ciddial(411,411,30,TW,Zap/1);
+	}
+}
+
+context fromSeanUniden {
+	includes
+	{
+		parkedcalls;
+	}
+	21 => {
+		Dial(IAX2/seaniax,20,T);
+		}
+	_707202XXXX => {
+		&ciddial(${EXTEN:3},${EXTEN},30,TW,Zap/1);
+	}
+	_707219XXXX => {
+		&ciddial(${EXTEN:3},${EXTEN},30,TW,Zap/1);
+	}
+	_707254XXXX => {
+		&ciddial(${EXTEN:3},${EXTEN},30,TW,Zap/1);
+	}
+	_707716XXXX => {
+		&ciddial(${EXTEN:3},${EXTEN},30,TW,Zap/1);
+	}
+	_707754XXXX => {
+		&ciddial(${EXTEN:3},${EXTEN},30,TW,Zap/1);
+	}
+	_707574XXXX => {
+		&ciddial(${EXTEN:3},${EXTEN},30,TW,Zap/1);
+	}
+	_NXXNXXXXXX => {
+		&ciddial(1${EXTEN},${EXTEN},30,TW,Zap/1);
+	}
+	_1NXXNXXXXXX => {
+		&ciddial(${EXTEN},${EXTEN:1},30,TW,Zap/1);
+	}
+	_754XXXX => {
+		&ciddial(${EXTEN},707${EXTEN},30,TW,Zap/1);
+	}
+	_574XXXX => {
+		&ciddial(${EXTEN},707${EXTEN},30,TW,Zap/1);
+	}
+	_NXXXXXX => {
+		&ciddial(1707${EXTEN},707${EXTEN},30,TW,Zap/1);
+	}
+	911 => {
+		&ciddial(911,911,30,TW,Zap/1);
+	}
+	411 => {
+		&ciddial(411,411,30,TW,Zap/1);
+	}
+}
+
+context workext {
+	ignorepat => 8;
+	ignorepat => 9;
+	includes {
+		 parkedcalls;
+		 workfirst;
+		 force_home;
+		 dialFWD;
+		 dialiaxtel;
+		 dialgoiax;
+	}
+	s => {
+	loopback:
+		Wait(0);
+	}
+	1 => {
+		Dial(Zap/3&Zap/5,20,tT);
+	}
+	2 => {
+		Dial(Zap/5&Zap/6,20,tT);
+	}
+	21 => {
+		Dial(IAX2/seaniax,20,T);
+		}
+	22 => {
+		Set(CALLERID(num)=1234567890);
+		Set(CALLERID(name)=TestCaller);
+		Dial(Zap/5,20,mP()A(beep)tw);
+		NoOp(here is dialstatus: ${DIALSTATUS}...);
+		goto s|loopback;
+	}
+	4 => {
+		VoicemailMain();
+		goto s|loopback;
+	}
+	5 => {
+		Record(recording:gsm);
+		Background(recording);
+	}
+	6 => {
+		ZapBarge();
+	}
+	760 => {
+		DateTime();
+		goto s|loopback;
+	}
+	761 => {
+		ZapBarge();
+		goto s|loopback;
+	}
+	765 => {
+		Playback(demo-echotest);
+		Echo();
+		Playback(demo-echodone);
+		goto s|loopback;
+	}
+	766 => {
+		Festival(The other thing to watch is neuro-electronics: the ability to interface technology with our neural system: My wife: Sigrid: has had a cochlear implant since 1996. This once profoundly deaf person now uses the phone: recognizes accents: and listens to movies and recorded books.);
+		goto s|loopback;
+	}
+	767 => {
+		agi(tts-riddle.agi);
+		Background(gsm/what-time-it-is2);
+		SayUnixTime();
+		goto s|loopback;
+	}
+	768 => {
+		agi(tts-computer.agi);
+	}
+	771 => {
+		eagi(eagi-test);
+		agi(my-agi-test);
+	}
+	772 => {
+		agi(wakeup.agi);
+	}
+	775 => {
+		if( ${EXTEN}=${EXTEN} )
+		{
+			BackGround(digits/1);
+		}
+		else
+		{
+			BackGround(digits/0);
+		}
+		if( ${EXTEN}=${LANGUAGE} )
+		{
+			BackGround(digits/1);
+		}
+		else
+		{
+			BackGround(digits/0);
+		}
+		BackGround(digits/2);
+	}
+	776 => {
+		Set(TEST=00359889811777);
+		if( ${TEST}= 00359889811777 )
+		{
+			BackGround(digits/1);
+		}
+		else
+		{
+			BackGround(digits/0);
+		}
+		if( ${TEST}= 00359889811888 )
+		{
+			BackGround(digits/1);
+		}
+		else
+		{
+			BackGround(digits/0);
+		}
+		Hangup();
+	}
+        790 => {
+                MeetMe(790,p);
+        }
+	792 => {
+		goto pageall|s|begin;
+	}
+	793 => {
+		#include "include1.ael2"
+	}
+	795 => {
+		AGI(wakeup.agi);
+		Congestion();
+	}
+	797 => {
+		Set(CONFCIDNA=${CALLERID(name)});
+		Set(CONFCIDNU=${CALLERID(num)});
+		AGI(callall);
+		AGI(submit-announce.agi);
+		Hangup();
+	}
+}
+
+context wakeup {
+	3 => {
+		Dial(Zap/3|30);
+	}
+	4 => {
+		Dial(Zap/4|30);
+
+	}
+	5 => {
+		Dial(Zap/5|30);
+
+	}
+	6 => {
+		Dial(Zap/6|30);
+
+	}
+	99 => {
+		Dial(IAX2/murfiaxphone|30);
+	}
+	97 => {
+		Dial(IAX2/ryaniax|30);
+	}
+	94 => {
+		Dial(IAX2/seaniax|30);
+	}
+}
+
+context announce-all {
+	s => {
+	begin:
+		MeetMe(5555,dtqp);
+		MeetMeAdmin(5555,K);
+		Hangup();
+	}
+	h => {
+		MeetMeAdmin(5555,K);
+		Hangup();
+	}
+}
+
+// now include the telemarketer torture scripts!
+
+#include "/etc/asterisk/telemarket_torture.ael2"
+
+
diff --git a/pbx/ael/ael-test/ael-test3/include1.ael2 b/pbx/ael/ael-test/ael-test3/include1.ael2
new file mode 100644
index 0000000000..80c562cb23
--- /dev/null
+++ b/pbx/ael/ael-test/ael-test3/include1.ael2
@@ -0,0 +1,3 @@
+	NoOp(Hello, this is included from include1.ael2);
+	#include "include2.ael2"
+
diff --git a/pbx/ael/ael-test/ael-test3/include2.ael2 b/pbx/ael/ael-test/ael-test3/include2.ael2
new file mode 100644
index 0000000000..8d892fb0c2
--- /dev/null
+++ b/pbx/ael/ael-test/ael-test3/include2.ael2
@@ -0,0 +1,4 @@
+	NoOp(This was included from include2.ael2);
+	#include "include3.ael2"
+	#include "include4.ael2"
+
diff --git a/pbx/ael/ael-test/ael-test3/include3.ael2 b/pbx/ael/ael-test/ael-test3/include3.ael2
new file mode 100644
index 0000000000..3c6c1e3dd2
--- /dev/null
+++ b/pbx/ael/ael-test/ael-test3/include3.ael2
@@ -0,0 +1,2 @@
+	NoOp(This is include3.ael2!);
+	#include "include5.ael2"
diff --git a/pbx/ael/ael-test/ael-test3/include4.ael2 b/pbx/ael/ael-test/ael-test3/include4.ael2
new file mode 100644
index 0000000000..7d3703a5e8
--- /dev/null
+++ b/pbx/ael/ael-test/ael-test3/include4.ael2
@@ -0,0 +1,2 @@
+	NoOp(This is include4.ael2! Isn't it cool!?!?!?!);
+	NoOp(4 doesn't include anything);
diff --git a/pbx/ael/ael-test/ael-test3/include5.ael2 b/pbx/ael/ael-test/ael-test3/include5.ael2
new file mode 100644
index 0000000000..0e18983efa
--- /dev/null
+++ b/pbx/ael/ael-test/ael-test3/include5.ael2
@@ -0,0 +1 @@
+	NoOp(Include5.ael2 doesn't include anything, either!);
diff --git a/pbx/ael/ael-test/ael-test4/apptest.ael2 b/pbx/ael/ael-test/ael-test4/apptest.ael2
new file mode 100644
index 0000000000..c477d8531b
--- /dev/null
+++ b/pbx/ael/ael-test/ael-test4/apptest.ael2
@@ -0,0 +1,146 @@
+// this is a quick test to see how many of the apps we can spot j options in
+// include this in a macro or extension
+// at this moment, there are 18 apps that accept the j option.
+
+	AddQueueMember(zork,iface,20,j);
+	ADSIProg(sfile);
+	AgentCallbackLogin(agent,s,30@cont);
+	AgentLogin(agent,s);
+	AgentMonitorOutgoing(dcn);
+	AGI(whatever);
+	AlarmReceiver();
+	Answer(2);
+	AppendCDRUserField(value);
+	Authenticate(pword,adjmr);
+	BackGround(filename,snm,eng);
+	BackgroundDetect(filename,20,2,10);
+	Busy(10);
+	ChangeMonitor(fnamebase);
+	ChanIsAvail(Zap/5,sj);
+	ChanSpy(prefix,bg()qrv);
+	Congestion(5);
+	ControlPlayback(filename,10,6,4,0,5,7,j);
+	DateTime(unixtime,tz,fmt);
+	DBdel(fam/key);
+	DBdeltree(fam);
+	DeadAGI(command);
+	Dial(zap/1,45,A()CdD()fgG()hHjL()m()M()nNoprS()tTwW);
+	Dictate(basedir);
+	Directory(cont,dcont,f);
+	DISA(68986869876,context);
+	DumpChan(verblev);
+	DUNDiLookup(90709780978,context,bj);
+	EAGI(command);
+	Echo();
+	EndWhile();
+	Exec(appname,args);
+	ExecIf(expr,app,data);
+	ExecIfTime(*,*,*,*,appname);
+	ExternalIVR(command,arg1);
+	Festival(text);
+	Flash();
+	ForkCDR(v);
+	GetCPEID();
+	Gosub(cont,exten,priority);
+	GosubIf(cond?label);
+	Goto(cont,exten,prior);
+	GotoIf(cond?t:f);
+	GotoIfTime(*,*,*,*?cont,ext,prior);
+	Hangup();
+	HasNewVoicemail(vmbox,var,j);
+	HasVoicemail(vmbox,var,j);
+	IAX2Provision(template);
+	ICES(xmlconfig);
+	ImportVar(nevar@chann,var);
+	Log(NOTICE,message);
+	LookupBlacklist(j);
+	LookupCIDName();
+	Macro(macro,arg1);
+	MacroExit();
+	MacroIf(expr?etc);
+	MailboxExists(mbox@cont,j);
+	Math(v,2+2);
+	MeetMe(5555,aAbcdDeimMpPqrstTovwxX);
+	MeetMeAdmin(5555,e,user);
+	MeetMeCount(5555,var);
+	Milliwatt();
+	MixMonitor(filename,abv()V()W(),command);
+	Monitor(file.fmt,base,mb);
+	MP3Player(location);
+	MusicOnHold(class);
+	NBScat();
+	NoCDR();
+	NoOp(ignored);
+	Page(Zap/1,dq);
+	Park(exten);
+	ParkAndAnnounce(template,5,238,retcont);
+	ParkedCall(exten);
+	PauseQueueMember(queue,zap,j);
+	Pickup(ext@cont);
+	Playback(file,j);
+	PlayTones(arg);
+	PrivacyManager(3,4,j);
+	Progress();
+	Queue(queuename,dhHnrtTwW,http://www.where.what,over,5);
+	Random(30,cont,ext,pri);
+	Read(var,fname,10,skip,2,5);
+	ReadFile(var=file,10);
+	RealTime(fam,2,val,prefix);
+	RealTimeUpdate(fam,2,val,2,newval);
+	Record(file,2,10,anqst);
+	RemoveQueueMember(queuename,iface,j);
+	ResetCDR(wav);
+	RetryDial(annound,4,2);
+	Return();
+	Ringing();
+	RxFAX(fname,caller);
+	SayAlpha(string);
+	SayDigits(string);
+	SayNumber(digits);
+	SayPhonetic(string);
+	SayUnixTime(unixtime,tz,fmt);
+	SendDTMF(digits,10);
+	SendImage(filename);
+	SendText(text,j);
+	SendURL(URL);
+	Set(a=b);
+	SetAMAFlags();
+	SetCallerID(clid,a);
+	SetCallerPres(allowed_passed_screen);
+	SetCDRUserField(value);
+	SetGlobalVar(var=val);
+	SetMusicOnHold(class);
+	SetTransferCapability(SPEECH);
+	SIPAddHeader(header);
+	SIPDtmfMode(inband,info,rfc);
+	SIPGetHeader(var@headername);
+	SMS(name);
+	SoftHangup(zap/1,a);
+	StackPop();
+	StartMusicOnHold(class);
+	StopMonitor();
+	StopMusicOnHold();
+	StopPlayTones();
+	System(command);
+	TestClient(testid);
+	TestServer();
+	Transfer(zap/1,j);
+	TrySystem(command);
+	TxFAX(filename,caller,debug);
+	UnpauseQueueMember(queuename,iface,j);
+	UserEvent(eventanme,body);
+	Verbose(5,message);
+	VMAuthenticate(mailbox@cont,s);
+	VoiceMail(mailbox@cont,bg()suj);
+	VoiceMailMain(mailbox@cont,pg()s);
+	Wait(2);
+	WaitExten(3,m());
+	WaitForRing(2);
+	WaitForSilence(2,y);
+	WaitMusicOnHold(2);
+	While(expr);
+	Zapateller(answer,5);
+	ZapBarge(channel);
+	ZapRAS(arg);
+	ZapScan(group);
+	ZapSendKeypadFacility();
diff --git a/pbx/ael/ael-test/ael-test4/extensions.ael b/pbx/ael/ael-test/ael-test4/extensions.ael
new file mode 100644
index 0000000000..838aa24892
--- /dev/null
+++ b/pbx/ael/ael-test/ael-test4/extensions.ael
@@ -0,0 +1,8 @@
+context test1
+{
+	test2 => 
+	{
+		#include "apptest.ael2";
+	}
+}
+
diff --git a/pbx/ael/ael-test/ael-test5/extensions.ael b/pbx/ael/ael-test/ael-test5/extensions.ael
new file mode 100644
index 0000000000..304275a006
--- /dev/null
+++ b/pbx/ael/ael-test/ael-test5/extensions.ael
@@ -0,0 +1,833 @@
+///////////////////////////////////////////////////////////////////////////////
+// Helpdesk Queue
+
+context hd-queue {
+	s => {
+		NoOp(Add a background sound to tell the user their options);
+		Queue(helpdesk|t);
+		NoOp(Put in options to apologize and send user to voicemail);
+	};
+
+	0 => goto default|0|1;
+	1 => {
+		Dial(u41950@svm1.shsu.edu);
+		Congestion(10);
+		Hangup;
+	};
+};
+
+
+context l903-calling {
+	_9903NXXXXXX => {
+		Realtime(l903_ext,exchange,${EXTEN:4:3},l903_);
+		if ("${l903_exchange}foo" = "foo") {
+			Playback(num-outside-area);
+			SayDigits(1);
+			Playback(and-area-code);
+			Playback(before-the-number);
+			Hangup;
+		};
+		&dialout(${EXTEN});
+		Congestion(10);
+		Hangup;
+	};
+};
+///////////////////////////////////////////////////////////////////////////////
+// Extensions pulled from houston.conf
+// Converted the extension list to the database
+
+context houston-calling {
+	_9713NXXXXXX => {
+		Realtime(hou_713_ext,exchange,${EXTEN:4:3},hou_713_);
+		if ("${hou_713_exchange}foo" = "foo") {
+			Playback(num-outside-area);
+			SayDigits(1);
+			Playback(and-area-code);
+			Playback(before-the-number);
+			Hangup;
+		};
+		&dialout(${EXTEN});
+		Congestion(10);
+		Hangup;
+	};
+
+	_9281NXXXXXX => {
+		Realtime(hou_281_ext,exchange,${EXTEN:4:3},hou_281_);
+		if ("${hou_281_exchange}foo" = "foo") {
+			Playback(num-outside-area);
+			SayDigits(1);
+			Playback(and-area-code);
+			Playback(before-the-number);
+			Hangup;
+		};
+		&dialout(${EXTEN});
+		Congestion(10);
+		Hangup;
+	};
+
+	_9832NXXXXXX => {
+		Realtime(hou_832_ext,exchange,${EXTEN:4:3},hou_832_);
+		if ("${hou_832_exchange}foo" = "foo") {
+			Playback(num-outside-area);
+			SayDigits(1);
+			Playback(and-area-code);
+			Playback(before-the-number);
+			Hangup;
+		};
+		&dialout(${EXTEN});
+		Congestion(10);
+		Hangup;
+	};
+};
+
+
+///////////////////////////////////////////////////////////////////////////////
+// Extensions pulled from huntsville.conf
+// Converted the extension list to the database
+
+context huntsville-calling {
+	_9NXXXXXX => {
+		Realtime(hv_ext,exchange,${EXTEN:1:3},hv_);
+		if ("${hv_exchange}foo" = "foo") {
+			Playback(num-outside-area);
+			SayDigits(1);
+			Playback(and-area-code);
+			Playback(before-the-number);
+			Hangup;
+		};
+		&dialout(${EXTEN});
+		Congestion(10);
+		Hangup;
+	};
+
+	_NXXXXXX => {
+		NoOp(Stripping last four to see what extension we're dialing);
+		Set(LAST4=${EXTEN:3});
+		StripLSD(4);
+	};
+
+	i => Playback(pbx-invalid);
+	h => Hangup;
+};
+
+///////////////////////////////////////////////////////////////////////////////
+// Extensions pulled from macros.conf
+
+macro dialout( number ) {
+	Realtime(call_info,exten,${CALLERIDNUM:5},mon_);
+	if ("${mon_monitor}" = "YES") {
+		Dial(SIP/${number}@sgw1.shsu.edu,,wW);
+		Dial(SIP/${number}@sgw2.shsu.edu,,wW);
+	} else {
+		Dial(SIP/${number}@sgw1.shsu.edu);
+		Dial(SIP/${number}@sgw2.shsu.edu);
+	};
+};
+
+// Standard extension macro:
+//  ${ext} - Extension
+macro stdexten( ext ) {
+	Realtime(sipusers,name,${ext},sip_user_);
+	Realtime(call_info,exten|${ext},info_);
+	if ("${sip_user_name}foo" = "foo") {
+		Wait(1);
+		&dialout(${ext});
+		Congestion(10);
+		Hangup;
+	};
+	NoOp(${CALLERIDNUM});
+	RealtimeUpdate(call_info,exten,${ext},calltrace,${CALLERIDNUM});
+	System(/usr/local/bin/db_update.sh call_info calltrace ${CALLERIDNUM} exten ${ext} &);
+	&checkdnd(${ext});
+	&checkcf(${ext});
+	Realtime(call_info,exten,${CALLERIDNUM:5},mon_);
+	if ("${mon_monitor}" = "YES") {
+		Dial(SIP/${info_forwardto},25,wW);
+	} else {
+		Dial(SIP/${info_forwardto},25);
+	};
+	switch ("${DIALSTATUS}") {
+		case "BUSY":
+			&checkcfb(${ext});
+			break;
+		case "CHANUNAVAIL":
+			Dial(IAX2/asterisk:password@scm2.shsu.edu/${info_forwardto},25,wW);
+			MailboxExists(${ext});
+//			if ("${VMBOXEXISTSSTATUS}" = "FAILED") {
+//				Congestion(10);
+//				Hangup;
+//			};
+			&uvm(${ext});
+			Hangup;
+			break;
+		case "CONGESTION":
+			MailboxExists(${ext});
+			if ("${VMBOXEXISTSSTATUS}" = "FAILED") {
+				Congestion(10);
+				Hangup;
+			};
+			&bvm(${ext});
+			Hangup;
+			break;
+		default:
+			MailboxExists(${ext});
+			if ("${VMBOXEXISTSSTATUS}" = "FAILED") {
+				Congestion(10);
+				Hangup;
+			};
+			&uvm(${ext});
+			Hangup;
+	};
+	Hangup;
+};
+
+macro uvm( ext ) {
+	Dial(SIP/u${ext}@svm1.shsu.edu);
+	Playback(im-sorry);
+	Playback(voice-mail-system);
+	Playback(down);
+	Congestion(10);
+	Hangup;
+};
+
+macro bvm( ext ) {
+	Dial(SIP/b${ext}@svm1.shsu.edu);
+	Playback(im-sorry);
+	Playback(voice-mail-system);
+	Playback(down);
+	Congestion(10);
+	Hangup;
+};
+
+macro checkdnd( ext ) {
+	if ("${info_donotdisturb}foo" = "foo") {
+		NoOp(Do Not Disturb is not active);
+	} else
+		&uvm(${ext});
+};
+
+macro checkcf( ext ) {
+	if ("${info_forwardto}foo" = "foo")
+		if ("${ext}" = "43974") {
+			Set(info_forwardto=${ext}&SCCP/${ext});
+		} else {
+			Set(info_forwardto=${ext}&SIP/${ext}w);
+		};
+};
+
+macro checkcfb( ext ) {
+	if ("${info_forwardbusy}foo" = "foo") {
+		Wait(1);
+		MailboxExists(${ext});
+		if ("${VMBOXEXISTSSTATUS}" = "FAILED") {
+			&dialout(${ext});
+			Hangup;
+		};
+		&bvm(${ext});
+		Hangup;
+	};
+	&stdexten(${info_forwardbusy});
+};
+
+///////////////////////////////////////////////////////////////////////////////
+// Extensions pulled from test.conf
+
+context test-include {
+	includes {
+		test-digium;
+		test-sounds;
+		test-phinfo;
+	};
+};
+
+context test-digium {
+	*500 => {
+		Dial(IAX2/guest@misery.digium.com/s@default);
+		Playback(demo-nogo);
+		Hangup;
+	};
+};
+
+context test-sounds {
+	*501 => {
+		Answer;
+		Musiconhold;
+		Wait(1);
+		Hangup;
+	};
+};
+
+context test-phinfo {
+	*505 => {
+		Answer;
+		NoOp(${CALLERIDNUM:5});
+		SayDigits(${CALLERIDNUM:5});
+		Hangup;
+	};
+};
+
+///////////////////////////////////////////////////////////////////////////////
+// Extensions pulled from external.conf
+
+context long-distance {
+	includes {
+		local;
+	};
+
+	_91XXXXXXXXXX => &dialout(${EXTEN});
+	_9011. => &dialout(${EXTEN});
+};
+
+context local {
+	includes {
+		default;
+	};
+
+	911 => &dialout(911);
+	9911 => &dialout(9911);
+
+	_9NXXXXXX => goto huntsville-calling|${EXTEN}|1;
+	_936NXXXXXX => {
+		goto 9${EXTEN:3}|1;
+		Congestion(10);
+		Hangup;
+	};
+
+	_832NXXXXXX => {
+		goto 9${EXTEN}|1;
+		Congestion(10);
+		Hangup;
+	};
+
+	_713NXXXXXX => {
+		goto 9${EXTEN}|1 ;
+		Congestion(10);
+		Hangup;
+	};
+
+	_281NXXXXXX => {
+		goto 9${EXTEN}|1;
+		Congestion(10);
+		Hangup;
+
+	};
+
+	_NXXNXXXXXX => {
+		goto 9${EXTEN}|1;
+		goto 91${EXTEN}|1;
+		Congestion(10);
+		Hangup;
+	};
+
+	_91800NXXXXXX => &dialout(${EXTEN});
+	_91866NXXXXXX => &dialout(${EXTEN});
+	_91877NXXXXXX => &dialout(${EXTEN});
+	_91888NXXXXXX => &dialout(${EXTEN});
+	_91900NXXXXXX => &dialout(${EXTEN});
+	_91976NXXXXXX => &dialout(${EXTEN});
+	_9713NXXXXXX => goto houston-calling|${EXTEN}|1;
+	_9281NXXXXXX => goto houston-calling|${EXTEN}|1;
+	_9832NXXXXXX => goto houston-calling|${EXTEN}|1;
+	_9903NXXXXXX => goto l903-calling|${EXTEN}|1;
+
+	_31NXXNXXXXXX => &dialout(${EXTEN});
+
+	h => Hangup;
+};
+
+///////////////////////////////////////////////////////////////////////////////
+// Extensions pulled from internal.conf
+
+context from-scm2 {
+	_4XXXX => {
+		NoOp(DIALING SIP EXTENSION ${EXTEN} - FROM ${CALLERIDNUM});
+		Dial(SIP/${EXTEN},20,wW);
+		Hangup;
+	};
+
+	_6XXXX => {
+		NoOp(DIALING SIP EXTENSION ${EXTEN} - FROM ${CALLERIDNUM});
+		Dial(SIP/${EXTEN},20,wW);
+		Hangup;
+	};
+};
+
+///////////////////////////////////////////////////////////
+// All internal extensions work through the default context
+// Phones that can only make internal calls should be in
+// this context.
+///////////////////////////////////////////////////////////
+
+context default {
+// Include the contexts in the files that allow us to make these phone calls
+	includes {
+		vm-include;
+		apps-include;
+		test-include;
+	};
+
+// ALWAYS have an 'h' extension
+	h => {
+		NoOp(Hangup cause was: ${HANGUPCAUSE});
+		Hangup;
+	};
+
+// We like to hear that we dialed an invalid extension
+	i => Playback(pbx-invalid);
+
+// Dial the operator
+	0 => &dialout(0);
+
+// Send voicemail calls to the vm-* contexts to be handled
+	voicemail => goto vm-direct|s|1;
+	5555 => goto vm-direct|s|1;
+	62100 => goto vm-extension|s|1;
+
+// These are our campus extensions, send them to the macro
+	_6XXXX => &stdexten(${EXTEN});
+	_4XXXX => &stdexten(${EXTEN});
+// These are campus extensions as well, might need to take this out though.
+	_9294XXXX => goto _4XXXX|1;
+	_9496XXXX => goto _6XXXX|1;
+
+// These allows us to dial from the directory in our phone without worrying about dialing 9
+	_936294XXXX => {
+		goto ${EXTEN:5}|1;
+		goto 9${EXTEN:3}|1;
+		Congestion(10);
+		Hangup;
+	};
+
+	_936496XXXX => {
+		goto ${EXTEN:5}|1;
+		goto 9${EXTEN:3}|1;
+		Congestion(10);
+		Hangup;
+	};
+};
+
+///////////////////////////////////////////////////////////////////////////////
+// Extensions pulled from apps.conf
+
+context apps-include {
+	includes {
+		app-agents;
+		app-dnd;
+		app-callforward;
+		app-calltrace;
+		app-conferences;
+		app-ssd;
+		app-psd;
+		app-idblock;
+		app-helpdesk;
+		app-dictate;
+		app-set-monitor;
+	};
+};
+
+context app-agents {
+	*54 => {
+		Answer;
+		Wait(1);
+		Read(agent_no|agent-user);
+		AgentCallbackLogin(${agent_no}|s${CALLERIDNUM:5});
+		Playback(agent-loginok);
+		Hangup;
+	};
+
+	*55 => {
+		Answer;
+		Wait(1);
+		AgentCallbackLogin(${agent_no});
+		Hangup;
+	};
+};
+
+context app-calltrace {
+// caller dials this to find out the last call missed and possibly call back
+	*69 => goto app-calltrace-perform|s|1;
+};
+
+context app-calltrace-perform {
+	s => {
+		Answer;
+		Wait(1);
+		Background(info-about-last-call);
+		Background(telephone-number);
+		RealTime(call_info|exten|${CALLERIDNUM:5}|ct_);
+		if ("${ct_calltrace}foo" = "foo") {
+			Playback(loligo/from-unknown-caller);
+			Hangup;
+		} else {
+			SayDigits("${ct_calltrace}");
+			Set(TIMEOUT(digit)=3);
+			Set(TIMEOUT(response)=7);
+			Background(loligo/to-call-this-number);
+			Background(press-1);
+			Background(loligo/silence/5);
+		};
+	};
+
+	1 => goto local|${ct_calltrace}|1;
+
+	i => {
+		Playback(vm-goodbye);
+		Hangup;
+	};
+
+	t => {
+		Playback(vm-goodbye);
+		Hangup;
+	};
+};
+
+context app-set-monitor {
+	*50 => {
+		Realtime(call_info,exten,${CALLERIDNUM:5},mon_set_);
+		if ("${mon_set_monitor}" = "YES") {
+			RealtimeUpdate(call_info,exten,${CALLERIDNUM:5},monitor|);
+			System(/usr/local/bin/db_update.sh call_info monitor '' exten ${CALLERIDNUM:5} &);
+		} else {
+			RealtimeUpdate(call_info,exten,${CALLERIDNUM:5},monitor,YES);
+			System(/usr/local/bin/db_update.sh call_info monitor YES exten ${CALLERIDNUM:5} &);
+		};
+		NoOp(${mon_set_monitor});
+		Hangup;
+	};
+};
+
+context app-dnd {
+	*78 => {
+		Answer;
+		Wait(1);
+		RealtimeUpdate(call_info,exten,${CALLERIDNUM:5},donotdisturb,YES);
+		System(/usr/local/bin/db_update.sh call_info donotdisturb YES exten ${CALLERIDNUM:5} &);
+		Playback(do-not-disturb);
+		Playback(loligo/activated);
+		Hangup;
+	};
+
+	*79 => {
+		Answer;
+		Wait(1);
+		RealtimeUpdate(call_info,exten,${CALLERIDNUM:5},donotdisturb|);
+		System(/usr/local/bin/db_update.sh call_info donotdisturb '' exten ${CALLERIDNUM:5} &);
+		Playback(do-not-disturb);
+		Playback(loligo/de-activated);
+		Hangup;
+	};
+};
+
+context app-callforward {
+	// forwards calling extension to input number *72{EXTEN}
+	_*72. => {
+		RealtimeUpdate(call_info,exten,${CALLERIDNUM:5},forwardto,${EXTEN:3});
+		System(/usr/local/bin/db_update.sh call_info forwardto ${EXTEN:3} exten ${CALLERIDNUM:5} &);
+		Answer;
+		Wait(1);
+		Playback(loligo/call-fwd-unconditional);
+		Playback(loligo/for);
+		Playback(loligo/extension);
+		SayDigits(${CALLERIDNUM:5});
+		Playback(loligo/is-set-to);
+		SayDigits(${EXTEN:3});
+		Hangup;
+	};
+
+	// prompts for extension to forward to
+	*72 => {
+		Answer;
+		Wait(1);
+		Playback(please-enter-your);
+		Playback(extension);
+		Background(then-press-pound);
+		VMAuthenticate(|s);
+		Background(loligo/ent-target-attendant);
+		Read(toext,loligo/then-press-pound);
+		Wait(1);
+		RealtimeUpdate(call_info,exten,${AUTH_MAILBOX},forwardto,${toext});
+		System(/usr/local/bin/db_update.sh call_info forwardto ${toext} exten ${AUTH_MAILBOX} &);
+		Playback(loligo/call-fwd-unconditional);
+		Playback(loligo/for);
+		Playback(loligo/extension);
+		SayDigits(${AUTH_MAILBOX});
+		Playback(loligo/is-set-to);
+		SayDigits(${toext});
+		Hangup;
+	};
+
+	// cancels dialed extension call forward
+	_*73. => {
+		Realtime(voicemail,mailbox,${EXTEN:3},auth_);
+		Answer;
+		Wait(1);
+		Authenticate(${auth_password});
+		RealtimeUpdate(call_info,exten,${EXTEN:3},forwardto,);
+		System(/usr/local/bin/db_update.sh call_info forwardto '' exten ${EXTEN:3} &);
+		Wait(1);
+		SayDigits(${EXTEN:3});
+		Playback(loligo/call-fwd-cancelled);
+		Hangup;
+	};
+
+	// cancels call forward for calling extension
+	*73 => {
+		RealtimeUpdate(call_info,exten,${CALLERIDNUM:5},forwardto,);
+		System(/usr/local/bin/db_update.sh call_info forwardto '' exten ${CALLERIDNUM:5} &);
+		Answer;
+		Wait(1);
+		Playback(loligo/call-fwd-cancelled);
+		Hangup;
+	};
+
+	// dialed call forward on busy
+	_*90. => {
+		RealtimeUpdate(call_info,exten,${CALLERIDNUM:5},forwardbusy,${EXTEN:3});
+		System(/usr/local/bin/db_update.sh call_info forwardbusy ${EXTEN:3} exten ${CALLERIDNUM:5} &);
+		Answer;
+		Wait(1);
+		Playback(loligo/call-fwd-on-busy);
+		Playback(loligo/for);
+		Playback(loligo/extension);
+		SayDigits(${CALLERIDNUM:5});
+		Playback(loligo/is-set-to);
+		SayDigits(${EXTEN:3});
+		Hangup;
+	};
+
+	// cancels call forward on busy for calling extension
+	*91 => {
+		RealtimeUpdate(call_info,exten,${CALLERIDNUM:5},forwardbusy|);
+		System(/usr/local/bin/db_update.sh call_info forwardbusy '' exten ${CALLERIDNUM:5} &);
+		Answer;
+		Wait(1);
+		Playback(loligo/call-fwd-on-busy);
+		Playback(loligo/de-activated);
+		Hangup;
+	};
+
+	h => Hangup;
+};
+
+context app-idblock {
+	_*67. => {
+		Set(CALLERID(name)=Anonymous);
+		&stdexten(${EXTEN:3});
+	};
+};
+
+context app-dictate {
+	*1 => {
+		Dictate();
+		Hangup;
+	};
+};
+
+context app-ssd {
+// *59 <xx> <y.> - Set system speed dial <xx> to digits <y.>
+// *59 <xx> 0    - Delete system speed dial <xx>
+// *59 <xx>      - Review system speed dial <xx>
+// *1xx          - Dial speed dial <xx>
+	_*59XXX. => {
+		Answer;
+		RealtimeUpdate(ssd,sd,${EXTEN:3:2},extension,${EXTEN:5});
+		System(/usr/local/bin/db_update.sh systemsd extension ${EXTEN:5} sd ${EXTEN:3:2} &);
+		Wait(1);
+		Playback(loligo/speed-dial);
+		SayDigits(${EXTEN:3:2});
+		Playback(loligo/has-been-set-to);
+		SayDigits(${EXTEN:5});
+		Hangup;
+	};
+
+	_*59XX0 => {
+		Answer;
+		RealtimeUpdate(ssd,sd,${EXTEN:3:2},extension,);
+		System(/usr/local/bin/db_update.sh systemsd extension '' sd ${EXTEN:3:2} &);
+		Wait(1);
+		Playback(loligo/speed-dial);
+		SayDigits(${EXTEN:3:2});
+		Playback(loligo/has-been-cleared);
+		Hangup;
+	};
+
+	_*59XX => {
+		Answer;
+		Realtime(ssd,sd,${EXTEN:3},ssd_);
+		if ("${ssd_extension}foo" = "foo") {
+			Playback(loligo/speed-dial);
+			SayDigits(${EXTEN:3:2});
+			Playback(loligo/is-not-set);
+			Hangup;
+		};
+		Wait(1);
+		Playback(loligo/speed-dial);
+		SayDigits(${EXTEN:3:2});
+		Playback(loligo/is-set-to);
+		SayDigits(${ssd_extension});
+		Hangup;
+	};
+
+	// NTC = number to call
+	_*1XX => {
+		Realtime(ssd,sd,${EXTEN:2},ssd_);
+		if ("${ssd_extension}foo" = "foo") {
+			Answer;
+			Wait(1);
+			Playback(loligo/speed-dial);
+			SayDigits(${EXTEN:2});
+			Playback(loligo/is-not-set);
+			Hangup;
+		};
+		&stdexten(${ssd_extension});
+		Congestion(10);
+		Hangup;
+	};
+};
+
+macro check-psd-exists ( ext ) {
+	Realtime(psd,extension,${ext},psd_);
+	if ("${psd_extension}foo" = "foo") {
+		System(/usr/local/bin/create_psd.sh ${ext});
+	} else
+		NoOp(PSD set for ${ext});
+};
+
+context app-psd {
+// *89 <xx> <y.> - Set personal speed dial <xx> to digits <y.>
+// *89 <xx> 0    - Delete personal speed dial <xx>
+// *89 <xx>      - Review personal speed dial <xx>
+// *2xx          - Dial personal speed dial <xx>
+	_*89XXX. => {
+		&check-psd-exists(${CALLERIDNUM:5});
+		Answer;
+		RealtimeUpdate(psd,extension,${CALLERIDNUM:5},s${EXTEN:3:2},${EXTEN:5});
+		System(/usr/local/bin/db_update.sh personalsd s${EXTEN:3:2} ${EXTEN:5} extension ${CALLERIDNUM:5} &);
+		Wait(1);
+		Playback(loligo/speed-dial);
+		SayDigits(${EXTEN:3:2});
+		Playback(loligo/has-been-set-to);
+		SayDigits(${EXTEN:5});
+		Hangup;
+	};
+
+	_*89XX0 => {
+		&check-psd-exists(${CALLERIDNUM:5});
+		Answer;
+		RealtimeUpdate(psd|extension|${CALLERIDNUM:5}|s${EXTEN:3:2}|);
+		System(/usr/local/bin/db_update.sh personalsd s${EXTEN:3:2} '' extension ${CALLERIDNUM:5} &);
+		Wait(1);
+		Playback(loligo/speed-dial);
+		SayDigits(${EXTEN:3:2});
+		Playback(loligo/has-been-cleared);
+		Hangup;
+	};
+
+	_*89XX => {
+		&check-psd-exists(${CALLERIDNUM:5});
+		Answer;
+		Realtime(psd|extension|${CALLERIDNUM:5}|psd_);
+		Wait(1);
+		if ("${psd_s${EXTEN:3:2}}foo" = "foo") {
+			Playback(loligo/speed-dial);
+			SayDigits(${EXTEN:3:2});
+			Playback(loligo/is-not-set);
+			Hangup;
+		};
+		Playback(loligo/speed-dial);
+		SayDigits(${EXTEN:3:2});
+		Playback(loligo/is-set-to);
+		SayDigits(${psd_s${EXTEN:3:2}});
+		Hangup;
+	};
+
+	// NTC = number to call
+	_*2XX => {
+		&check-psd-exists(${CALLERIDNUM:5});
+		Realtime(psd|extension|${CALLERIDNUM:5}|psd_);
+		if ("${psd_s${EXTEN:2}}foo" = "foo") {
+			Answer;
+			Wait(1);
+			Playback(loligo/speed-dial);
+			SayDigits(${EXTEN:2});
+			Playback(loligo/is-not-set);
+			Hangup;
+		};
+		&stdexten(${psd_s${EXTEN:2}});
+		Congestion(10);
+		Hangup;
+	};
+};
+
+context app-helpdesk {
+	*4357 => {
+		&stdexten(41950);
+		Congestion;
+	};
+};
+
+context app-conferences {
+// waiting for room number announcement
+	*86 => goto app-conf-hidden|s|1;
+};
+
+context app-conf-hidden {
+	s => {
+		Wait(1);
+		Playback(loligo/please-enter-the);
+		Playback(loligo/extension);
+		read(roomtoenter,loligo/then-press-pound);
+		Meetme(${roomtoenter});
+		Waitexten(8);
+		Hangup;
+	};
+
+	_1. => Meetme(${EXTEN});
+};
+
+///////////////////////////////////////////////////////////////////////////////
+// Extensions pulled from vm.conf:
+
+context vm-include {
+	includes {
+		vm-direct;
+		vm-extension;
+		vm-directory;
+	};
+};
+
+context vm-direct {
+	s => {
+		Dial(SIP/5555@svm1.shsu.edu,20);
+		Playback(im-sorry);
+		Playback(voice-mail-system);
+		Playback(down);
+		Playback(extra/pls-try-call-later);
+		Congestion(10);
+		Hangup;
+	};
+};
+
+context vm-extension {
+	s => {
+		Dial(SIP/62100@svm1.shsu.edu,20);
+		Playback(im-sorry);
+		Playback(voice-mail-system);
+		Playback(down);
+		Playback(extra/pls-try-call-later);
+		Congestion(10);
+		Hangup;
+	};
+};
+
+context vm-directory {
+	5556 => {
+		Dial(SIP/5556@svm1.shsu.edu);
+		Playback(im-sorry);
+		Playback(voice-mail-system);
+		Playback(down);
+		Playback(extra/pls-try-call-later);
+		Congestion(10);
+		Hangup;
+	};
+};
diff --git a/pbx/ael/ael-test/ael-test6/extensions.ael b/pbx/ael/ael-test/ael-test6/extensions.ael
new file mode 100644
index 0000000000..890c7111cc
--- /dev/null
+++ b/pbx/ael/ael-test/ael-test6/extensions.ael
@@ -0,0 +1,833 @@
+///////////////////////////////////////////////////////////////////////////////
+// Helpdesk Queue
+
+context hd-queue {
+	s => {
+		NoOp(Add a background sound to tell the user their options);
+		Queue(helpdesk|t);
+		NoOp(Put in options to apologize and send user to voicemail);
+	};
+
+	0 => goto default|0|1;
+	1 => {
+		Dial(u41950@svm1.shsu.edu);
+		Congestion(10);
+		Hangup;
+	};
+};
+
+
+context l903-calling {
+	_9903NXXXXXX => {
+		Realtime(l903_ext|exchange|${EXTEN:4:3}|l903_);
+		if ("${l903_exchange}foo" = "foo") {
+			Playback(num-outside-area);
+			SayDigits(1);
+			Playback(and-area-code);
+			Playback(before-the-number);
+			Hangup;
+		};
+		&dialout(${EXTEN});
+		Congestion(10);
+		Hangup;
+	};
+};
+///////////////////////////////////////////////////////////////////////////////
+// Extensions pulled from houston.conf
+// Converted the extension list to the database
+
+context houston-calling {
+	_9713NXXXXXX => {
+		Realtime(hou_713_ext|exchange|${EXTEN:4:3}|hou_713_);
+		if ("${hou_713_exchange}foo" = "foo") {
+			Playback(num-outside-area);
+			SayDigits(1);
+			Playback(and-area-code);
+			Playback(before-the-number);
+			Hangup;
+		};
+		&dialout(${EXTEN});
+		Congestion(10);
+		Hangup;
+	};
+
+	_9281NXXXXXX => {
+		Realtime(hou_281_ext|exchange|${EXTEN:4:3}|hou_281_);
+		if ("${hou_281_exchange}foo" = "foo") {
+			Playback(num-outside-area);
+			SayDigits(1);
+			Playback(and-area-code);
+			Playback(before-the-number);
+			Hangup;
+		};
+		&dialout(${EXTEN});
+		Congestion(10);
+		Hangup;
+	};
+
+	_9832NXXXXXX => {
+		Realtime(hou_832_ext|exchange|${EXTEN:4:3}|hou_832_);
+		if ("${hou_832_exchange}foo" = "foo") {
+			Playback(num-outside-area);
+			SayDigits(1);
+			Playback(and-area-code);
+			Playback(before-the-number);
+			Hangup;
+		};
+		&dialout(${EXTEN});
+		Congestion(10);
+		Hangup;
+	};
+};
+
+
+///////////////////////////////////////////////////////////////////////////////
+// Extensions pulled from huntsville.conf
+// Converted the extension list to the database
+
+context huntsville-calling {
+	_9NXXXXXX => {
+		Realtime(hv_ext|exchange|${EXTEN:1:3}|hv_);
+		if ("${hv_exchange}foo" = "foo") {
+			Playback(num-outside-area);
+			SayDigits(1);
+			Playback(and-area-code);
+			Playback(before-the-number);
+			Hangup;
+		};
+		&dialout(${EXTEN});
+		Congestion(10);
+		Hangup;
+	};
+
+	_NXXXXXX => {
+		NoOp(Stripping last four to see what extension we're dialing);
+		Set(LAST4=${EXTEN:3});
+		StripLSD(4);
+	};
+
+	i => Playback(pbx-invalid);
+	h => Hangup;
+};
+
+///////////////////////////////////////////////////////////////////////////////
+// Extensions pulled from macros.conf
+
+macro dialout( number ) {
+	Realtime(call_info|exten|${CALLERIDNUM:5}|mon_);
+	if ("${mon_monitor}" = "YES") {
+		Dial(SIP/${number}@sgw1.shsu.edu,,wW);
+		Dial(SIP/${number}@sgw2.shsu.edu,,wW);
+	} else {
+		Dial(SIP/${number}@sgw1.shsu.edu);
+		Dial(SIP/${number}@sgw2.shsu.edu);
+	};
+};
+
+// Standard extension macro:
+//  ${ext} - Extension
+macro stdexten( ext ) {
+	Realtime(sipusers|name|${ext}|sip_user_);
+	Realtime(call_info|exten|${ext}|info_);
+	if ("${sip_user_name}foo" = "foo") {
+		Wait(1);
+		&dialout(${ext});
+		Congestion(10);
+		Hangup;
+	};
+	NoOp(${CALLERIDNUM});
+	RealtimeUpdate(call_info|exten|${ext}|calltrace|${CALLERIDNUM});
+	System(/usr/local/bin/db_update.sh call_info calltrace ${CALLERIDNUM} exten ${ext} &);
+	&checkdnd(${ext});
+	&checkcf(${ext});
+	Realtime(call_info|exten|${CALLERIDNUM:5}|mon_);
+	if ("${mon_monitor}" = "YES") {
+		Dial(SIP/${info_forwardto},25,wW);
+	} else {
+		Dial(SIP/${info_forwardto},25);
+	};
+	switch ("${DIALSTATUS}") {
+		case "BUSY":
+			&checkcfb(${ext});
+			break;
+		case "CHANUNAVAIL":
+			Dial(IAX2/asterisk:password@scm2.shsu.edu/${info_forwardto},25,wW);
+			MailboxExists(${ext});
+//			if ("${VMBOXEXISTSSTATUS}" = "FAILED") {
+//				Congestion(10);
+//				Hangup;
+//			};
+			&uvm(${ext});
+			Hangup;
+			break;
+		case "CONGESTION":
+			MailboxExists(${ext});
+			if ("$(VMBOXEXISTSSTATUS}" = "FAILED") {
+				Congestion(10);
+				Hangup;
+			};
+			&bvm(${ext});
+			Hangup;
+			break;
+		default:
+			MailboxExists(${ext});
+			if ("$(VMBOXEXISTSSTATUS}" = "FAILED") {
+				Congestion(10);
+				Hangup;
+			};
+			&uvm(${ext});
+			Hangup;
+	};
+	Hangup;
+};
+
+macro uvm( ext ) {
+	Dial(SIP/u${ext}@svm1.shsu.edu);
+	Playback(im-sorry);
+	Playback(voice-mail-system);
+	Playback(down);
+	Congestion(10);
+	Hangup;
+};
+
+macro bvm( ext ) {
+	Dial(SIP/b${ext}@svm1.shsu.edu);
+	Playback(im-sorry);
+	Playback(voice-mail-system);
+	Playback(down);
+	Congestion(10);
+	Hangup;
+};
+
+macro checkdnd( ext ) {
+	if ("${info_donotdisturb}foo" = "foo") {
+		NoOp(Do Not Disturb is not active);
+	} else
+		&uvm(${ext});
+};
+
+macro checkcf( ext ) {
+	if ("${info_forwardto}foo" = "foo")
+		if ("${ext}" = "43974") {
+			Set(info_forwardto=${ext}&SCCP/${ext});
+		} else {
+			Set(info_forwardto=${ext}&SIP/${ext}w);
+		};
+};
+
+macro checkcfb( ext ) {
+	if ("${info_forwardbusy}foo" = "foo") {
+		Wait(1);
+		MailboxExists(${ext});
+		if ("$(VMBOXEXISTSSTATUS}" = "FAILED") {
+			&dialout(${ext});
+			Hangup;
+		};
+		&bvm(${ext});
+		Hangup;
+	};
+	&stdexten(${info_forwardbusy});
+};
+
+///////////////////////////////////////////////////////////////////////////////
+// Extensions pulled from test.conf
+
+context test-include {
+	includes {
+		test-digium;
+		test-sounds;
+		test-phinfo;
+	};
+};
+
+context test-digium {
+	*500 => {
+		Dial(IAX2/guest@misery.digium.com/s@default);
+		Playback(demo-nogo);
+		Hangup;
+	};
+};
+
+context test-sounds {
+	*501 => {
+		Answer;
+		Musiconhold;
+		Wait(1);
+		Hangup;
+	};
+};
+
+context test-phinfo {
+	*505 => {
+		Answer;
+		NoOp(${CALLERIDNUM:5});
+		SayDigits(${CALLERIDNUM:5});
+		Hangup;
+	};
+};
+
+///////////////////////////////////////////////////////////////////////////////
+// Extensions pulled from external.conf
+
+context long-distance {
+	includes {
+		local;
+	};
+
+	_91XXXXXXXXXX => &dialout(${EXTEN});
+	_9011. => &dialout(${EXTEN});
+};
+
+context local {
+	includes {
+		default;
+	};
+
+	911 => &dialout(911);
+	9911 => &dialout(9911);
+
+	_9NXXXXXX => goto huntsville-calling|${EXTEN}|1;
+	_936NXXXXXX => {
+		Goto 9${EXTEN:3}|1;
+		Congestion(10);
+		Hangup;
+	};
+
+	_832NXXXXXX => {
+		goto 9${EXTEN}|1;
+		Congestion(10);
+		Hangup;
+	};
+
+	_713NXXXXXX => {
+		goto 9${EXTEN}|1 ;
+		Congestion(10);
+		Hangup;
+	};
+
+	_281NXXXXXX => {
+		goto 9${EXTEN}|1;
+		Congestion(10);
+		Hangup;
+
+	};
+
+	_NXXNXXXXXX => {
+		goto 9${EXTEN}|1;
+		goto 91${EXTEN}|1;
+		Congestion(10);
+		Hangup;
+	};
+
+	_91800NXXXXXX => &dialout(${EXTEN});
+	_91866NXXXXXX => &dialout(${EXTEN});
+	_91877NXXXXXX => &dialout(${EXTEN});
+	_91888NXXXXXX => &dialout(${EXTEN});
+	_91900NXXXXXX => &dialout(${EXTEN});
+	_91976NXXXXXX => &dialout(${EXTEN});
+	_9713NXXXXXX => goto houston-calling|${EXTEN}|1;
+	_9281NXXXXXX => goto houston-calling|${EXTEN}|1;
+	_9832NXXXXXX => goto houston-calling|${EXTEN}|1;
+	_9903NXXXXXX => goto l903-calling|${EXTEN}|1;
+
+	_31NXXNXXXXXX => &dialout(${EXTEN});
+
+	h => Hangup;
+};
+
+///////////////////////////////////////////////////////////////////////////////
+// Extensions pulled from internal.conf
+
+context from-scm2 {
+	_4XXXX => {
+		NoOp(DIALING SIP EXTENSION ${EXTEN} - FROM ${CALLERIDNUM});
+		Dial(SIP/${EXTEN},20,wW);
+		Hangup;
+	};
+
+	_6XXXX => {
+		NoOp(DIALING SIP EXTENSION ${EXTEN} - FROM ${CALLERIDNUM});
+		Dial(SIP/${EXTEN},20,wW);
+		Hangup;
+	};
+};
+
+///////////////////////////////////////////////////////////
+// All internal extensions work through the default context
+// Phones that can only make internal calls should be in
+// this context.
+///////////////////////////////////////////////////////////
+
+context default {
+// Include the contexts in the files that allow us to make these phone calls
+	includes {
+		vm-include;
+		apps-include;
+		test-include;
+	};
+
+// ALWAYS have an 'h' extension
+	h => {
+		NoOp(Hangup cause was: ${HANGUPCAUSE});
+		Hangup;
+	};
+
+// We like to hear that we dialed an invalid extension
+	i => Playback(pbx-invalid);
+
+// Dial the operator
+	0 => &dialout(0);
+
+// Send voicemail calls to the vm-* contexts to be handled
+	voicemail => goto vm-direct|s|1;
+	5555 => goto vm-direct|s|1;
+	62100 => goto vm-extension|s|1;
+
+// These are our campus extensions, send them to the macro
+	_6XXXX => &stdexten(${EXTEN});
+	_4XXXX => &stdexten(${EXTEN});
+// These are campus extensions as well, might need to take this out though.
+	_9294XXXX => goto _4XXXX|1;
+	_9496XXXX => goto _6XXXX|1;
+
+// These allows us to dial from the directory in our phone without worrying about dialing 9
+	_936294XXXX => {
+		goto ${EXTEN:5}|1;
+		goto 9${EXTEN:3}|1;
+		Congestion(10);
+		Hangup;
+	};
+
+	_936496XXXX => {
+		goto ${EXTEN:5}|1;
+		goto 9${EXTEN:3}|1;
+		Congestion(10);
+		Hangup;
+	};
+};
+
+///////////////////////////////////////////////////////////////////////////////
+// Extensions pulled from apps.conf
+
+context apps-include {
+	includes {
+		app-agents;
+		app-dnd;
+		app-callforward;
+		app-calltrace;
+		app-conferences;
+		app-ssd;
+		app-psd;
+		app-idblock;
+		app-helpdesk;
+		app-dictate;
+		app-set-monitor;
+	};
+};
+
+context app-agents {
+	*54 => {
+		Answer;
+		Wait(1);
+		Read(agent_no|agent-user);
+		AgentCallbackLogin(${agent_no}|s${CALLERIDNUM:5});
+		Playback(agent-loginok);
+		Hangup;
+	};
+
+	*55 => {
+		Answer;
+		Wait(1);
+		AgentCallbackLogin(${agent_no});
+		Hangup;
+	};
+};
+
+context app-calltrace {
+// caller dials this to find out the last call missed and possibly call back
+	*69 => goto app-calltrace-perform|s|1;
+};
+
+context app-calltrace-perform {
+	s => {
+		Answer;
+		Wait(1);
+		Background(info-about-last-call);
+		Background(telephone-number);
+		RealTime(call_info|exten|${CALLERIDNUM:5}|ct_);
+		if ("${ct_calltrace}foo" = "foo") {
+			Playback(loligo/from-unknown-caller);
+			Hangup;
+		} else {
+			SayDigits("${ct_calltrace}");
+			Set(TIMEOUT(digit)=3);
+			Set(TIMEOUT(response)=7);
+			Background(loligo/to-call-this-number);
+			Background(press-1);
+			Background(loligo/silence/5);
+		};
+	};
+
+	1 => goto local|${ct_calltrace}|1;
+
+	i => {
+		Playback(vm-goodbye);
+		Hangup;
+	};
+
+	t => {
+		Playback(vm-goodbye);
+		Hangup;
+	};
+};
+
+context app-set-monitor {
+	*50 => {
+		Realtime(call_info|exten|${CALLERIDNUM:5}|mon_set_);
+		if ("${mon_set_monitor}" = "YES") {
+			RealtimeUpdate(call_info|exten|${CALLERIDNUM:5}|monitor|);
+			System(/usr/local/bin/db_update.sh call_info monitor '' exten ${CALLERIDNUM:5} &);
+		} else {
+			RealtimeUpdate(call_info|exten|${CALLERIDNUM:5}|monitor|YES);
+			System(/usr/local/bin/db_update.sh call_info monitor YES exten ${CALLERIDNUM:5} &);
+		};
+		NoOp(${mon_set_monitor});
+		Hangup;
+	};
+};
+
+context app-dnd {
+	*78 => {
+		Answer;
+		Wait(1);
+		RealtimeUpdate(call_info|exten|${CALLERIDNUM:5}|donotdisturb|YES);
+		System(/usr/local/bin/db_update.sh call_info donotdisturb YES exten ${CALLERIDNUM:5} &);
+		Playback(do-not-disturb);
+		Playback(loligo/activated);
+		Hangup;
+	};
+
+	*79 => {
+		Answer;
+		Wait(1);
+		RealtimeUpdate(call_info|exten|${CALLERIDNUM:5}|donotdisturb|);
+		System(/usr/local/bin/db_update.sh call_info donotdisturb '' exten ${CALLERIDNUM:5} &);
+		Playback(do-not-disturb);
+		Playback(loligo/de-activated);
+		Hangup;
+	};
+};
+
+context app-callforward {
+	// forwards calling extension to input number *72{EXTEN}
+	_*72. => {
+		RealtimeUpdate(call_info|exten|${CALLERIDNUM:5}|forwardto|${EXTEN:3});
+		System(/usr/local/bin/db_update.sh call_info forwardto ${EXTEN:3} exten ${CALLERIDNUM:5} &);
+		Answer;
+		Wait(1);
+		Playback(loligo/call-fwd-unconditional);
+		Playback(loligo/for);
+		Playback(loligo/extension);
+		SayDigits(${CALLERIDNUM:5});
+		Playback(loligo/is-set-to);
+		SayDigits(${EXTEN:3});
+		Hangup;
+	};
+
+	// prompts for extension to forward to
+	*72 => {
+		Answer;
+		Wait(1);
+		Playback(please-enter-your);
+		Playback(extension);
+		Background(then-press-pound);
+		VMAuthenticate(|s);
+		Background(loligo/ent-target-attendant);
+		Read(toext,loligo/then-press-pound);
+		Wait(1);
+		RealtimeUpdate(call_info|exten|${AUTH_MAILBOX}|forwardto|${toext});
+		System(/usr/local/bin/db_update.sh call_info forwardto ${toext} exten ${AUTH_MAILBOX} &);
+		Playback(loligo/call-fwd-unconditional);
+		Playback(loligo/for);
+		Playback(loligo/extension);
+		SayDigits(${AUTH_MAILBOX});
+		Playback(loligo/is-set-to);
+		SayDigits(${toext});
+		Hangup;
+	};
+
+	// cancels dialed extension call forward
+	_*73. => {
+		Realtime(voicemail|mailbox|${EXTEN:3}|auth_);
+		Answer;
+		Wait(1);
+		Authenticate(${auth_password});
+		RealtimeUpdate(call_info|exten|${EXTEN:3}|forwardto|);
+		System(/usr/local/bin/db_update.sh call_info forwardto '' exten ${EXTEN:3} &);
+		Wait(1);
+		SayDigits(${EXTEN:3});
+		Playback(loligo/call-fwd-cancelled);
+		Hangup;
+	};
+
+	// cancels call forward for calling extension
+	*73 => {
+		RealtimeUpdate(call_info|exten|${CALLERIDNUM:5}|forwardto|);
+		System(/usr/local/bin/db_update.sh call_info forwardto '' exten ${CALLERIDNUM:5} &);
+		Answer;
+		Wait(1);
+		Playback(loligo/call-fwd-cancelled);
+		Hangup;
+	};
+
+	// dialed call forward on busy
+	_*90. => {
+		RealtimeUpdate(call_info|exten|${CALLERIDNUM:5}|forwardbusy|${EXTEN:3});
+		System(/usr/local/bin/db_update.sh call_info forwardbusy ${EXTEN:3} exten ${CALLERIDNUM:5} &);
+		Answer;
+		Wait(1);
+		Playback(loligo/call-fwd-on-busy);
+		Playback(loligo/for);
+		Playback(loligo/extension);
+		SayDigits(${CALLERIDNUM:5});
+		Playback(loligo/is-set-to);
+		SayDigits(${EXTEN:3});
+		Hangup;
+	};
+
+	// cancels call forward on busy for calling extension
+	*91 => {
+		RealtimeUpdate(call_info|exten|${CALLERIDNUM:5}|forwardbusy|);
+		System(/usr/local/bin/db_update.sh call_info forwardbusy '' exten ${CALLERIDNUM:5} &);
+		Answer;
+		Wait(1);
+		Playback(loligo/call-fwd-on-busy);
+		Playback(loligo/de-activated);
+		Hangup;
+	};
+
+	h => Hangup;
+};
+
+context app-idblock {
+	_*67. => {
+		Set(CALLERID(name)=Anonymous);
+		&stdexten(${EXTEN:3});
+	};
+};
+
+context app-dictate {
+	*1 => {
+		Dictate();
+		Hangup;
+	};
+};
+
+context app-ssd {
+// *59 <xx> <y.> - Set system speed dial <xx> to digits <y.>
+// *59 <xx> 0    - Delete system speed dial <xx>
+// *59 <xx>      - Review system speed dial <xx>
+// *1xx          - Dial speed dial <xx>
+	_*59XXX. => {
+		Answer;
+		RealtimeUpdate(ssd|sd|${EXTEN:3:2}|extension|${EXTEN:5});
+		System(/usr/local/bin/db_update.sh systemsd extension ${EXTEN:5} sd ${EXTEN:3:2} &);
+		Wait(1);
+		Playback(loligo/speed-dial);
+		SayDigits(${EXTEN:3:2});
+		Playback(loligo/has-been-set-to);
+		SayDigits(${EXTEN:5});
+		Hangup;
+	};
+
+	_*59XX0 => {
+		Answer;
+		RealtimeUpdate(ssd|sd|${EXTEN:3:2}|extension|);
+		System(/usr/local/bin/db_update.sh systemsd extension '' sd ${EXTEN:3:2} &);
+		Wait(1);
+		Playback(loligo/speed-dial);
+		SayDigits(${EXTEN:3:2});
+		Playback(loligo/has-been-cleared);
+		Hangup;
+	};
+
+	_*59XX => {
+		Answer;
+		Realtime(ssd|sd|${EXTEN:3}|ssd_);
+		if ("${ssd_extension}foo" = "foo") {
+			Playback(loligo/speed-dial);
+			SayDigits(${EXTEN:3:2});
+			Playback(loligo/is-not-set);
+			Hangup;
+		};
+		Wait(1);
+		Playback(loligo/speed-dial);
+		SayDigits(${EXTEN:3:2});
+		Playback(loligo/is-set-to);
+		SayDigits(${ssd_extension});
+		Hangup;
+	};
+
+	// NTC = number to call
+	_*1XX => {
+		Realtime(ssd|sd|${EXTEN:2}|ssd_);
+		if ("${ssd_extension}foo" = "foo") {
+			Answer;
+			Wait(1);
+			Playback(loligo/speed-dial);
+			SayDigits(${EXTEN:2});
+			Playback(loligo/is-not-set);
+			Hangup;
+		};
+		&stdexten(${ssd_extension});
+		Congestion(10);
+		Hangup;
+	};
+};
+
+macro check-psd-exists ( ext ) {
+	Realtime(psd|extension|${ext}|psd_);
+	if ("${psd_extension}foo" = "foo") {
+		System(/usr/local/bin/create_psd.sh ${ext});
+	} else
+		NoOp(PSD set for ${ext});
+};
+
+context app-psd {
+// *89 <xx> <y.> - Set personal speed dial <xx> to digits <y.>
+// *89 <xx> 0    - Delete personal speed dial <xx>
+// *89 <xx>      - Review personal speed dial <xx>
+// *2xx          - Dial personal speed dial <xx>
+	_*89XXX. => {
+		&check-psd-exists(${CALLERIDNUM:5});
+		Answer;
+		RealtimeUpdate(psd|extension|${CALLERIDNUM:5}|s${EXTEN:3:2}|${EXTEN:5});
+		System(/usr/local/bin/db_update.sh personalsd s${EXTEN:3:2} ${EXTEN:5} extension ${CALLERIDNUM:5} &);
+		Wait(1);
+		Playback(loligo/speed-dial);
+		SayDigits(${EXTEN:3:2});
+		Playback(loligo/has-been-set-to);
+		SayDigits(${EXTEN:5});
+		Hangup;
+	};
+
+	_*89XX0 => {
+		&check-psd-exists(${CALLERIDNUM:5});
+		Answer;
+		RealtimeUpdate(psd|extension|${CALLERIDNUM:5}|s${EXTEN:3:2}|);
+		System(/usr/local/bin/db_update.sh personalsd s${EXTEN:3:2} '' extension ${CALLERIDNUM:5} &);
+		Wait(1);
+		Playback(loligo/speed-dial);
+		SayDigits(${EXTEN:3:2});
+		Playback(loligo/has-been-cleared);
+		Hangup;
+	};
+
+	_*89XX => {
+		&check-psd-exists(${CALLERIDNUM:5});
+		Answer;
+		Realtime(psd|extension|${CALLERIDNUM:5}|psd_);
+		Wait(1);
+		if ("${psd_s${EXTEN:3:2}}foo" = "foo") {
+			Playback(loligo/speed-dial);
+			SayDigits(${EXTEN:3:2});
+			Playback(loligo/is-not-set);
+			Hangup;
+		};
+		Playback(loligo/speed-dial);
+		SayDigits(${EXTEN:3:2});
+		Playback(loligo/is-set-to);
+		SayDigits(${psd_s${EXTEN:3:2}});
+		Hangup;
+	};
+
+	// NTC = number to call
+	_*2XX => {
+		&check-psd-exists(${CALLERIDNUM:5});
+		Realtime(psd|extension|${CALLERIDNUM:5}|psd_);
+		if ("${psd_s${EXTEN:2}}foo" = "foo") {
+			Answer;
+			Wait(1);
+			Playback(loligo/speed-dial);
+			SayDigits(${EXTEN:2});
+			Playback(loligo/is-not-set);
+			Hangup;
+		};
+		&stdexten(${psd_s${EXTEN:2}});
+		Congestion(10);
+		Hangup;
+	};
+};
+
+context app-helpdesk {
+	*4357 => {
+		&stdexten(41950);
+		Congestion;
+	};
+};
+
+context app-conferences {
+// waiting for room number announcement
+	*86 => goto app-conf-hidden|s|1;
+};
+
+context app-conf-hidden {
+	s => {
+		Wait(1);
+		Playback(loligo/please-enter-the);
+		Playback(loligo/extension);
+		read(roomtoenter,loligo/then-press-pound);
+		Meetme(${roomtoenter});
+		Waitexten(8);
+		Hangup;
+	};
+
+	_1. => Meetme(${EXTEN});
+};
+
+///////////////////////////////////////////////////////////////////////////////
+// Extensions pulled from vm.conf:
+
+context vm-include {
+	includes {
+		vm-direct;
+		vm-extension;
+		vm-directory;
+	};
+};
+
+context vm-direct {
+	s => {
+		Dial(SIP/5555@svm1.shsu.edu,20);
+		Playback(im-sorry);
+		Playback(voice-mail-system);
+		Playback(down);
+		Playback(extra/pls-try-call-later);
+		Congestion(10);
+		Hangup;
+	};
+};
+
+context vm-extension {
+	s => {
+		Dial(SIP/62100@svm1.shsu.edu,20);
+		Playback(im-sorry);
+		Playback(voice-mail-system);
+		Playback(down);
+		Playback(extra/pls-try-call-later);
+		Congestion(10);
+		Hangup;
+	};
+};
+
+context vm-directory {
+	5556 => {
+		Dial(SIP/5556@svm1.shsu.edu);
+		Playback(im-sorry);
+		Playback(voice-mail-system);
+		Playback(down);
+		Playback(extra/pls-try-call-later);
+		Congestion(10);
+		Hangup;
+	};
+};
diff --git a/pbx/ael/ael-test/ael-test7/extensions.ael b/pbx/ael/ael-test/ael-test7/extensions.ael
new file mode 100644
index 0000000000..52f9a077ac
--- /dev/null
+++ b/pbx/ael/ael-test/ael-test7/extensions.ael
@@ -0,0 +1,460 @@
+//
+// Example AEL config file
+//
+
+globals {
+	CONSOLE=Console/dsp;
+	TRUNKMSD=0;					//MSD digits to strip (usually 1 or 0)
+	TRUNCPROTO=SIP;
+	TRUNK=sunrocket;
+	PSTN=pstn-spa3k;
+	PSTNPROTO=SIP;
+	TARIOPROTO=SIP;
+	TARIO=tario;
+	CPPROTO=SIP;
+	CPACKET1=callpacket1;
+	CPACKET2=callpacket2;
+	SELLVOIP=1577040314;
+	SVPROTO=IAX2;
+};
+
+
+macro stdexten (ext , dev ) {
+	PrivacyManager(3,10);
+	if("${PRIVACYMGRSTATUS}" = "FAILED") {
+		Playback(vm-goodbye);
+		Hangup();
+	};
+
+	AGI(calleridnamelookup.agi);
+        Dial(${dev}/${ext},30,t);
+        switch(${DIALSTATUS}) {
+        case BUSY:
+                Voicemail(b${ext});
+                break;
+        default:
+                Voicemail(u${ext});
+        };
+        catch a {
+                VoiceMailMain(${ext});
+                return;
+        };
+};
+
+macro announce_minutes(minutes) {
+	Playback(vm-youhave);
+	SayNumber(${minutes});
+	Playback(vm-minutes);
+	Wait(1);
+};
+
+// Check if given provider allows only some free minutes per month
+// and announce number of free minutes remaining.
+// The limit will be reset monthly by cron job.
+// The macro sets the following variables:
+// MINUTES_LIMIT - number of free minutes per month
+// MINUTES_USED - number of free minutes used in the current month
+// PROVIDER - provider name
+
+macro checkanddial(prov,proto,ext,arg1,arg2,arg3,arg4) {
+	Set(MINUTES_LIMIT=0);
+	Set(MINUTES_USED=0);
+	Set(PROVIDER=${prov});
+
+	if(${DB_EXISTS(Provider/${prov}/used)})
+		Set(MINUTES_USED=${DB_RESULT});
+	
+	country_c = 0;
+	switch(${LEN(${ext})}) {	//assuming all international numbers are 11 digits long.
+	case 10:			//NXXNXXXXXX
+		country_c=1;
+		break;
+	case 11:			//XNXXNXXXXXX
+		country_c = ${ext:0:1};
+		break;
+	default:			//011XNXXNXXXXXX
+		country_c = ${ext:3:1};
+		break;
+	};
+		
+	if("${prov}" = "${TRUNK}" & ${country_c} != 1) {	// SunRocket international calls
+		Set(MINUTES_LIMIT=${DB(Provider/${prov}/limit)});
+		&announce_minutes($[${MINUTES_LIMIT} - ${MINUTES_USED}]);
+	};
+	if("${prov}" = "${CPACKET1}" | "${prov}" = "${CPACKET2}") {			// Callpacket has a limit on domestic calls
+		Set(MINUTES_LIMIT=${DB(Provider/${prov}/limit)});
+		&announce_minutes($[${MINUTES_LIMIT} - ${MINUTES_USED}]);
+	};
+	DeadAGI(dial.agi,${proto}/${ext}@${prov},${arg1},${arg2},${arg3},${arg4});
+};
+
+macro trunkdial(ext) {	// Dial sunrocket and set correct collerid
+	if("${CALLERID(number)}" = "1") {
+		Set(CALLERID(number)=7322271653);
+	} else {
+		Set(CALLERID(number)=7326260100);
+	};
+	Set(CALLERID(name)=Sergey Okhapkin);
+	&checkanddial(${TRUNK},${TRUNCPROTO},${ext},60,T);
+	Hangup;
+};
+
+macro checklocal(ext) {	// lookup the number in DB and call the number via pstn or sunrocket
+	Set(AREACODE=${ext:0:3});
+	Set(EXCHANGE=${ext:3:3});
+	Set(IS_LOCAL=${DB_EXISTS(localnum/${AREACODE}/${EXCHANGE})});
+	if(${IS_LOCAL}) {
+		&checkanddial(${PSTN},${PSTNPROTO},${ext},60,T);
+		if ("${DIALSTATUS}" = "BUSY")
+			&trunkdial(${ext});
+	} else
+		&trunkdial(${ext});
+};
+
+macro autodial(ext) {	// Find Least Cost Route
+	LCDial(${ext},60,T);
+	if("${DIALSTATUS}" = "NOPROVIDER")
+		Playback(invalid);
+	Hangup();
+};
+
+context default {	// Calls to us
+	s => {
+		Wait(1);
+		Answer;
+start:
+		Set(TIMEOUT(digit)=3);
+		Set(TIMEOUT(response)=10);
+repeat:
+		for (x=0; ${x} < 5; x=${x} + 1) {
+			Background(home/greeting);
+			WaitExten();
+		};
+	};
+	t => jump *;
+	i => {	// invalid extension
+		Playback(invalid);
+		goto s|repeat;
+	};
+	_* => {
+		Playback(vm-goodbye);
+		Wait(1);
+		Hangup;
+	};
+	1 => &stdexten(1,SIP/1);
+	2 => &stdexten(2,SIP/2);
+	3 => &stdexten(3,SIP/3);
+
+	2271653 => jump 1;
+	7322271653 => jump 1;
+	17322271653 => jump 1;
+
+	6260100 => jump 2;
+	7326260100 => jump 2;
+	17326260100 => jump 2;
+	8058701100 => jump 2;
+	3103622835 => jump 2;
+	sos => jump 2;
+	1400898 => jump 2;
+
+	6260101 => jump s;
+	7326260101 => jump s;
+	17326260101 => jump s;
+
+	2271677 => jump 3;
+	7322271677 => jump 3;
+	17322271677 => jump 3;
+	galka => jump 3;
+	911 => Dial(${PSTNPROTO}/911@${PSTN},60,);
+	380 => Dial(SIP/topspeen@212.40.38.70,60,T);
+
+	// Fun stuff
+	100 => {
+		SayUnixTime();
+		goto s|start;
+	};
+	101 => {	// Voicemail
+		VoicemailMain(${CALLERID(number)});
+		Hangup;
+	};
+	102 => MusicOnHold();
+//	103 => {
+//		Wait(1);
+//start:
+//		Read(NUMBER,vm-enter-num-to-call);
+//		LCDial(${NUMBER},T);
+//		goto start;
+//	};
+	105 => jump s@phrase-menu;
+	7312 => {
+		ForkCDR;
+		Set(CALLERID(name)=Sergey Okhapkin);
+		Set(CALLERID(number)=7326260100);
+		DISA(1111|home);
+	};
+};
+
+context goiax {
+	s => {
+		Answer();
+		Ringing();
+		Wait(1);
+start:
+		Read(NUMBER,vm-enter-num-to-call);
+		Set(CALLERID(name)=Central NJ);
+		Dial(IAX2/14301@fwdOUT/q${NUMBER},60,T);
+		goto start;
+	};
+
+};
+
+context phrase-menu {
+
+	s => {
+		Answer;			// Answer the line
+		TIMEOUT(digit)=2; 	// Set Digit Timeout to 5 seconds
+		TIMEOUT(response)=10; 	// Set Response Timeout to 10 seconds
+		BackGround(custom/phrase-menu);	//  Play main menu.
+	};
+	1 => {				// Phrase Recording
+		Wait(1);
+		Read(PHRASEID|custom/enter-phrase-num);
+		Wait(2); 		// give yourself 2 secs to take a breath and wait for beep
+		Record(custom/${PHRASEID}:gsm);
+		Wait(2);
+		Playback(custom/${PHRASEID});
+		Wait(1);
+		jump s;
+	};
+	2 => {				// Phrase review
+		Wait(1);
+		Read(PHRASEID|custom/enter-phrase-num);
+		Wait(1);
+		Playback(custom/${PHRASEID});
+		Wait(1);
+		jump s;
+	};
+	t => Hangup;
+	i => {
+		Playback(custom/invalid-option);
+		jump s;
+	};
+};
+
+context outbound {
+	// North America seven-, ten- and eleven digits
+	_NXXXXXX => &autodial(1732${EXTEN});
+	_NXXNXXXXXX => &autodial(1${EXTEN});
+	_ZNXXNXXXXX. => &autodial(${EXTEN});
+	// Toll free numbers via PSTN
+//	_1800NXXXXXX => &checkanddial(${PSTN},${PSTNPROTO},${EXTEN},60,T);
+//	_1888NXXXXXX => &checkanddial(${PSTN},${PSTNPROTO},${EXTEN},60,T);
+//	_1877NXXXXXX => &checkanddial(${PSTN},${PSTNPROTO},${EXTEN},60,T);
+//	_1866NXXXXXX => &checkanddial(${PSTN},${PSTNPROTO},${EXTEN},60,T);
+
+	_011. => {	//International context accessed through trunk
+		&trunkdial(${EXTEN});
+	};
+	_012. => {	//fwdOUT
+		Set(CALLERID(name)=Central NJ);
+		Dial(IAX2/14301@fwdOUT/q${EXTEN:3},60,T);
+	};                     
+	_013X. => {	//NECC
+		Dial(${PSTNPROTO}/011${EXTEN:3}@${PSTN},60,T);
+	};
+	_0131. => {	//NECC to US
+		Dial(${PSTNPROTO}/${EXTEN:3}@${PSTN},60,T);
+	};
+	_014. => {	//TARIO by SIP ID
+		Set(CALLERID(name)=Sergey Okhapkin);
+		Set(CALLERID(number)=1400898);
+		Dial(${TARIOPROTO}/${EXTEN:3}@${TARIO},60,T);
+	};
+	_0157. => {	//TARIO outbound Russia
+		Set(CALLERID(name)=Sergey Okhapkin);
+		Set(CALLERID(number)=1400898);
+		Dial(${TARIOPROTO}/8${EXTEN:4}@${TARIO},60,T);
+	};
+//	_015. => {	//TARIO outbound international
+//		CALLERID(name)="Sergey Okhapkin";
+//		CALLERID(number)=1400898;
+//		Dial(${TARIOPROTO}/810${EXTEN:3}@${TARIO},60,T);
+//	};
+	_0161NXXNXXXXXX => {	//Callpacket outbound USA/Canada
+		&checkanddial(${CPACKET1},${CPPROTO},${EXTEN:3},60,T);
+	};
+	_0171NXXNXXXXXX => {	//Callpacket outbound USA/Canada
+		&checkanddial(${CPACKET2},${CPPROTO},${EXTEN:3},60,T);
+	};
+	_0181NXXNXXXXXX => {	//sellvoip outbound USA/Canada
+		Dial(${SVPROTO}/${SELLVOIP}@${SELLVOIP}/${EXTEN:3},60,T);
+	};
+	_019. => {	//Voipbuster
+		Dial(IAX2/sokhapkin@voipbuster/00${EXTEN:3},60,T);
+	};
+};
+
+context home {		//calls from us
+	includes {
+		default;
+		outbound;
+	};
+};
+
+context sunrocket-in {
+	7322271653 => jump s;
+	7326260100 => jump 2@default;
+	s => {
+		if("${CALLERID(number)}" = "sunrocketcom")
+			Set(CALLERID(number)=);
+		switch(${CALLERID(RDNIS)}) {
+		case 7326260100:
+			jump 2@default;
+			break;
+		case 7326260101:
+			jump s@default;
+			break;
+		default:
+			jump 1@default;
+			break;
+		};
+	};
+};
+
+context pstn-in {
+	3 => {
+		if ("${CALLERID(number)}" = "7322271677")
+			Set(CALLERID(number)=);
+		jump 3@default;
+	};
+};
+
+context tario.net-in {
+	_X. => {
+		Set(CALLERID(name)=);
+		if("${CALLERID(number):-11:1}" = "8")
+			Set(CALLERID(number)=7${CALLERID(number):1});
+		if("${SIP_HEADER(To)}" = "<sip:2271677@sipnet.ru>") {
+			jump 3@default;
+		} else if("${SIP_HEADER(To)}" = "<sip:2271653@sipnet.ru>") {
+			jump 1@default;
+		} else
+			jump 2@default;                                                     
+	};
+};
+
+context from-callpacket {
+	8058701100 => jump 2@default;
+	3103622835 => {
+		Answer;
+		Ringing;
+		Wait(10);
+		Voicemail(b3103622835);
+		Hangup;
+	};
+	a => Hangup;
+};
+
+context fromfwdOUT {	//  make sure we only accept US and Canada calls, limit to 30 minutes
+	includes {
+		fromfwdOUT-catchbad;
+		fromfwdOUT-isgood;
+		fromfwdOUT-catchall;
+	};
+};
+
+context fromfwdOUT-isgood {
+	_17326260100 => jump 2@default;
+	_17326260101 => jump s@default;
+	_17322271653 => jump 1@default;
+	_17322271677 => jump 3@default;
+	_1NXXNXXXXXX => {
+		Set(CALLERID(name)=Sergey Okhapkin);
+//		Set(CALLERID(number)=7326260100);
+//		Dial(${TRUNCPROTO}/*67${EXTEN:${TRUNKMSD}}@${TRUNK},60,,L(1800000:60000));
+		Dial(${CPPROTO}/${EXTEN}@${CPACKET2},60,,L(1800000:60000));
+	};
+};
+
+context fromfwdOUT-catchbad {	//block bahamas, etc
+	_1900. => congestion    ; //N11
+	_1XXX976. => congestion ; //N11
+	_1XXX555. => congestion ; //N11
+	_1X11. => congestion    ; //N11
+	_1867. => congestion    ; //Yukon (sorry mike)
+
+		// exten => _1NPA Country
+	_1242. => congestion;   //BAHAMAS
+	_1246. => congestion;   //BARBADOS
+	_1264. => congestion;   //ANGUILLA
+	_1268. => congestion;   //ANTIGUA/BARBUDA
+	_1284. => congestion;   //BRITISH VIRGIN ISLANDS
+	_1345. => congestion;   //CAYMAN ISLANDS
+	_1441. => congestion;   //BERMUDA
+	_1473. => congestion;   //GRENADA
+	_1649. => congestion;   //TURKS & CAICOS ISLANDS
+	_1664. => congestion;   //MONTSERRAT
+	_1758. => congestion;   //ST. LUCIA
+	_1767. => congestion;   //DOMINICA
+	_1784. => congestion;   //ST. VINCENT & GRENADINES
+	_1809. => congestion;   //DOMINICAN REPUBLIC
+	_1829. => congestion;   //DOMINICAN REPUBLIC
+	_1868. => congestion;   //TRINIDAD AND TOBAGO
+	_1869. => congestion;   //ST. KITTS AND NEVIS
+	_1876. => congestion;   //JAMAICA
+	_1787. => congestion;   //Puerto Rico 787, 939 $0.07
+	_1939. => congestion;   //Puerto Rico 787, 939 $0.07
+	_1671. => congestion;   //Guam 671 $0.08
+	_1340. => congestion;   //U.S. Virgin Islands 340 $0.06
+};
+
+context fromfwdOUT-catchall {
+	_X. => Congestion;
+	h => Hangup    ;	//hangup event
+	i => Hangup    ;	//invalid event
+	t => Hangup    ;	//timeout event
+};
+
+context ael-demo {
+	s => {
+		Wait(1);
+		Answer();
+		TIMEOUT(digit)=5;
+		TIMEOUT(response)=10;
+restart:
+		Background(demo-congrats);
+instructions:
+		for (x=0; ${x} < 3; x=${x} + 1) {
+			Background(demo-instruct);
+			WaitExten();
+		};
+	};
+	2 => {
+		Background(demo-moreinfo);
+		goto s|instructions;
+	};
+	3 => {
+		LANGUAGE()=fr;
+		goto s|restart;
+	};
+	500 => {
+		Playback(demo-abouttotry);
+		Dial(IAX2/guest@misery.digium.com);
+		Playback(demo-nogo);
+		goto s|instructions;
+	};
+	600 => {
+		Playback(demo-echotest);
+		Echo();
+		Playback(demo-echodone);
+		goto s|instructions;
+	};
+	_1234 => &std-exten-ael(${EXTEN}, "IAX2");
+	# => {
+		Playback(demo-thanks);
+		Hangup();
+	};
+	t => jump #;
+	i => Playback(invalid);
+};
+
diff --git a/pbx/ael/ael-test/ref.ael-test1 b/pbx/ael/ael-test/ref.ael-test1
new file mode 100644
index 0000000000..28d5c4bc4a
--- /dev/null
+++ b/pbx/ael/ael-test/ref.ael-test1
@@ -0,0 +1,11 @@
+Executed ast_register_file_version();
+LOG: lev:2 file:pbx_ael.c  line:3428 func: pbx_load_module  Starting AEL load process.
+LOG: lev:2 file:pbx_ael.c  line:3435 func: pbx_load_module  AEL load process: calculated config file name './extensions.ael'.
+LOG: lev:2 file:pbx_ael.c  line:3438 func: pbx_load_module  AEL load process: parsed config file name './extensions.ael'.
+LOG: lev:3 file:pbx_ael.c  line:891 func: check_dow  Warning: file ./extensions.ael, line 67-67: The day (m0n) must be one of 'sun', 'mon', 'tue', 'wed', 'thu', 'fri', or 'sat'!
+LOG: lev:3 file:pbx_ael.c  line:849 func: check_timerange  Warning: file ./extensions.ael, line 78-78: The end time (25:00) is out of range!
+LOG: lev:2 file:pbx_ael.c  line:3441 func: pbx_load_module  AEL load process: checked config file name './extensions.ael'.
+LOG: lev:2 file:pbx_ael.c  line:3443 func: pbx_load_module  AEL load process: compiled config file name './extensions.ael'.
+LOG: lev:2 file:pbx_ael.c  line:3446 func: pbx_load_module  AEL load process: merged config file name './extensions.ael'.
+LOG: lev:2 file:pbx_ael.c  line:3449 func: pbx_load_module  AEL load process: verified config file name './extensions.ael'.
+LOG: lev:4 file:ael2_parse  line:261 func: main  5 contexts, 13 extensions, 156 priorities
diff --git a/pbx/ael/ael-test/ref.ael-test2 b/pbx/ael/ael-test/ref.ael-test2
new file mode 100644
index 0000000000..77ba08cfb1
--- /dev/null
+++ b/pbx/ael/ael-test/ref.ael-test2
@@ -0,0 +1,15 @@
+Executed ast_register_file_version();
+LOG: lev:2 file:pbx_ael.c  line:3428 func: pbx_load_module  Starting AEL load process.
+LOG: lev:2 file:pbx_ael.c  line:3435 func: pbx_load_module  AEL load process: calculated config file name './extensions.ael'.
+LOG: lev:2 file:ael.flex  line:467 func: ael_yylex    --Read in included file ./apptest.ael2, 3474 chars
+LOG: lev:3 file:ael.y  line:405 func: ael_yyparse  ==== File: ./apptest.ael2, Line 46, Cols: 8-11: Suggestion: Use the goto statement instead of the Goto() application call in AEL.
+LOG: lev:2 file:pbx_ael.c  line:3438 func: pbx_load_module  AEL load process: parsed config file name './extensions.ael'.
+LOG: lev:3 file:pbx_ael.c  line:2081 func: check_pval_item  Warning: file ./apptest.ael2, line 35-35: application call to EndWhile needs to be re-written using AEL if, while, goto, etc. keywords instead!
+LOG: lev:3 file:pbx_ael.c  line:2081 func: check_pval_item  Warning: file ./apptest.ael2, line 37-37: application call to ExecIf needs to be re-written using AEL if, while, goto, etc. keywords instead!
+LOG: lev:4 file:pbx_ael.c  line:1100 func: check_goto  Error: file ./apptest.ael2, line 46-46: goto:  no context cont could be found that matches the goto target!
+LOG: lev:3 file:pbx_ael.c  line:2081 func: check_pval_item  Warning: file ./apptest.ael2, line 47-47: application call to GotoIf needs to be re-written using AEL if, while, goto, etc. keywords instead!
+LOG: lev:3 file:pbx_ael.c  line:2081 func: check_pval_item  Warning: file ./apptest.ael2, line 48-48: application call to GotoIfTime needs to be re-written using AEL if, while, goto, etc. keywords instead!
+LOG: lev:3 file:pbx_ael.c  line:2081 func: check_pval_item  Warning: file ./apptest.ael2, line 85-85: application call to Random needs to be re-written using AEL if, while, goto, etc. keywords instead!
+LOG: lev:3 file:pbx_ael.c  line:2081 func: check_pval_item  Warning: file ./apptest.ael2, line 141-141: application call to While needs to be re-written using AEL if, while, goto, etc. keywords instead!
+LOG: lev:4 file:pbx_ael.c  line:3451 func: pbx_load_module  Sorry, but 0 syntax errors and 1 semantic errors were detected. It doesn't make sense to compile.
+LOG: lev:4 file:ael2_parse  line:261 func: main  0 contexts, 0 extensions, 0 priorities
diff --git a/pbx/ael/ael-test/ref.ael-test3 b/pbx/ael/ael-test/ref.ael-test3
new file mode 100644
index 0000000000..161fd4f5ec
--- /dev/null
+++ b/pbx/ael/ael-test/ref.ael-test3
@@ -0,0 +1,18 @@
+Executed ast_register_file_version();
+LOG: lev:2 file:pbx_ael.c  line:3428 func: pbx_load_module  Starting AEL load process.
+LOG: lev:2 file:pbx_ael.c  line:3435 func: pbx_load_module  AEL load process: calculated config file name './extensions.ael'.
+LOG: lev:2 file:ael.flex  line:467 func: ael_yylex    --Read in included file ./include1.ael2, 78 chars
+LOG: lev:2 file:ael.flex  line:467 func: ael_yylex    --Read in included file ./include2.ael2, 98 chars
+LOG: lev:2 file:ael.flex  line:467 func: ael_yylex    --Read in included file ./include3.ael2, 57 chars
+LOG: lev:2 file:ael.flex  line:467 func: ael_yylex    --Read in included file ./include5.ael2, 56 chars
+LOG: lev:2 file:ael.flex  line:467 func: ael_yylex    --Read in included file ./include4.ael2, 87 chars
+LOG: lev:2 file:ael.flex  line:467 func: ael_yylex    --Read in included file /etc/asterisk/telemarket_torture.ael2, 28036 chars
+LOG: lev:2 file:pbx_ael.c  line:3438 func: pbx_load_module  AEL load process: parsed config file name './extensions.ael'.
+LOG: lev:3 file:pbx_ael.c  line:2186 func: check_pval_item  Warning: file ./extensions.ael, line 5-5: expression Console/dsp has operators, but no variables. Interesting...
+LOG: lev:3 file:pbx_ael.c  line:2186 func: check_pval_item  Warning: file ./extensions.ael, line 8-8: expression "Joe-Worker" has operators, but no variables. Interesting...
+LOG: lev:3 file:pbx_ael.c  line:2186 func: check_pval_item  Warning: file ./extensions.ael, line 10-10: expression Zap/6  has operators, but no variables. Interesting...
+LOG: lev:2 file:pbx_ael.c  line:3441 func: pbx_load_module  AEL load process: checked config file name './extensions.ael'.
+LOG: lev:2 file:pbx_ael.c  line:3443 func: pbx_load_module  AEL load process: compiled config file name './extensions.ael'.
+LOG: lev:2 file:pbx_ael.c  line:3446 func: pbx_load_module  AEL load process: merged config file name './extensions.ael'.
+LOG: lev:2 file:pbx_ael.c  line:3449 func: pbx_load_module  AEL load process: verified config file name './extensions.ael'.
+LOG: lev:4 file:ael2_parse  line:261 func: main  172 contexts, 858 extensions, 2326 priorities
diff --git a/pbx/ael/ael-test/ref.ael-test4 b/pbx/ael/ael-test/ref.ael-test4
new file mode 100644
index 0000000000..77ba08cfb1
--- /dev/null
+++ b/pbx/ael/ael-test/ref.ael-test4
@@ -0,0 +1,15 @@
+Executed ast_register_file_version();
+LOG: lev:2 file:pbx_ael.c  line:3428 func: pbx_load_module  Starting AEL load process.
+LOG: lev:2 file:pbx_ael.c  line:3435 func: pbx_load_module  AEL load process: calculated config file name './extensions.ael'.
+LOG: lev:2 file:ael.flex  line:467 func: ael_yylex    --Read in included file ./apptest.ael2, 3474 chars
+LOG: lev:3 file:ael.y  line:405 func: ael_yyparse  ==== File: ./apptest.ael2, Line 46, Cols: 8-11: Suggestion: Use the goto statement instead of the Goto() application call in AEL.
+LOG: lev:2 file:pbx_ael.c  line:3438 func: pbx_load_module  AEL load process: parsed config file name './extensions.ael'.
+LOG: lev:3 file:pbx_ael.c  line:2081 func: check_pval_item  Warning: file ./apptest.ael2, line 35-35: application call to EndWhile needs to be re-written using AEL if, while, goto, etc. keywords instead!
+LOG: lev:3 file:pbx_ael.c  line:2081 func: check_pval_item  Warning: file ./apptest.ael2, line 37-37: application call to ExecIf needs to be re-written using AEL if, while, goto, etc. keywords instead!
+LOG: lev:4 file:pbx_ael.c  line:1100 func: check_goto  Error: file ./apptest.ael2, line 46-46: goto:  no context cont could be found that matches the goto target!
+LOG: lev:3 file:pbx_ael.c  line:2081 func: check_pval_item  Warning: file ./apptest.ael2, line 47-47: application call to GotoIf needs to be re-written using AEL if, while, goto, etc. keywords instead!
+LOG: lev:3 file:pbx_ael.c  line:2081 func: check_pval_item  Warning: file ./apptest.ael2, line 48-48: application call to GotoIfTime needs to be re-written using AEL if, while, goto, etc. keywords instead!
+LOG: lev:3 file:pbx_ael.c  line:2081 func: check_pval_item  Warning: file ./apptest.ael2, line 85-85: application call to Random needs to be re-written using AEL if, while, goto, etc. keywords instead!
+LOG: lev:3 file:pbx_ael.c  line:2081 func: check_pval_item  Warning: file ./apptest.ael2, line 141-141: application call to While needs to be re-written using AEL if, while, goto, etc. keywords instead!
+LOG: lev:4 file:pbx_ael.c  line:3451 func: pbx_load_module  Sorry, but 0 syntax errors and 1 semantic errors were detected. It doesn't make sense to compile.
+LOG: lev:4 file:ael2_parse  line:261 func: main  0 contexts, 0 extensions, 0 priorities
diff --git a/pbx/ael/ael-test/ref.ael-test5 b/pbx/ael/ael-test/ref.ael-test5
new file mode 100644
index 0000000000..25ad9b9189
--- /dev/null
+++ b/pbx/ael/ael-test/ref.ael-test5
@@ -0,0 +1,9 @@
+Executed ast_register_file_version();
+LOG: lev:2 file:pbx_ael.c  line:3428 func: pbx_load_module  Starting AEL load process.
+LOG: lev:2 file:pbx_ael.c  line:3435 func: pbx_load_module  AEL load process: calculated config file name './extensions.ael'.
+LOG: lev:2 file:pbx_ael.c  line:3438 func: pbx_load_module  AEL load process: parsed config file name './extensions.ael'.
+LOG: lev:2 file:pbx_ael.c  line:3441 func: pbx_load_module  AEL load process: checked config file name './extensions.ael'.
+LOG: lev:2 file:pbx_ael.c  line:3443 func: pbx_load_module  AEL load process: compiled config file name './extensions.ael'.
+LOG: lev:2 file:pbx_ael.c  line:3446 func: pbx_load_module  AEL load process: merged config file name './extensions.ael'.
+LOG: lev:2 file:pbx_ael.c  line:3449 func: pbx_load_module  AEL load process: verified config file name './extensions.ael'.
+LOG: lev:4 file:ael2_parse  line:261 func: main  38 contexts, 90 extensions, 484 priorities
diff --git a/pbx/ael/ael-test/ref.ael-test6 b/pbx/ael/ael-test/ref.ael-test6
new file mode 100644
index 0000000000..28ff7ad051
--- /dev/null
+++ b/pbx/ael/ael-test/ref.ael-test6
@@ -0,0 +1,20 @@
+Executed ast_register_file_version();
+LOG: lev:2 file:pbx_ael.c  line:3428 func: pbx_load_module  Starting AEL load process.
+LOG: lev:2 file:pbx_ael.c  line:3435 func: pbx_load_module  AEL load process: calculated config file name './extensions.ael'.
+LOG: lev:4 file:ael.flex  line:193 func: ael_yylex  File=./extensions.ael, line=165, column=21: Mismatched '}' in expression!
+LOG: lev:4 file:ael.y  line:674 func: ael_yyerror  ==== File: ./extensions.ael, Line 165, Cols: 23-23: Error: syntax error, unexpected '=', expecting ')'
+LOG: lev:4 file:ael.flex  line:317 func: ael_yylex  File=./extensions.ael, line=174, column=63: Mismatched '}' in expression!
+LOG: lev:4 file:ael.flex  line:317 func: ael_yylex  File=./extensions.ael, line=180, column=46: Mismatched '}' in expression!
+LOG: lev:4 file:ael.y  line:674 func: ael_yyerror  ==== File: ./extensions.ael, Line 184, Cols: 0-4: Error: syntax error, unexpected 'macro'
+LOG: lev:4 file:ael.flex  line:193 func: ael_yylex  File=./extensions.ael, line=222, column=21: Mismatched '}' in expression!
+LOG: lev:4 file:ael.y  line:674 func: ael_yyerror  ==== File: ./extensions.ael, Line 222, Cols: 23-23: Error: syntax error, unexpected '=', expecting ')'
+LOG: lev:4 file:ael.flex  line:317 func: ael_yylex  File=./extensions.ael, line=228, column=37: Mismatched '}' in expression!
+LOG: lev:4 file:ael.y  line:674 func: ael_yyerror  ==== File: ./extensions.ael, Line 235, Cols: 0-6: Error: syntax error, unexpected 'context'
+LOG: lev:4 file:ael.y  line:674 func: ael_yyerror  ==== File: ./extensions.ael, Line 344, Cols: 32-32: Error: syntax error, unexpected ';', expecting '{'
+LOG: lev:4 file:ael.y  line:674 func: ael_yyerror  ==== File: ./extensions.ael, Line 350, Cols: 32-32: Error: syntax error, unexpected ';', expecting '{'
+LOG: lev:4 file:ael.y  line:674 func: ael_yyerror  ==== File: ./extensions.ael, Line 461, Cols: 10-13: Error: syntax error, unexpected 'else'
+LOG: lev:2 file:pbx_ael.c  line:3438 func: pbx_load_module  AEL load process: parsed config file name './extensions.ael'.
+LOG: lev:4 file:pbx_ael.c  line:1100 func: check_goto  Error: file ./extensions.ael, line 11-11: goto:  no context default could be found that matches the goto target!
+LOG: lev:4 file:pbx_ael.c  line:2036 func: check_pval_item  Error: file ./extensions.ael, line 206-206: macro call to non-existent uvm !
+LOG: lev:4 file:pbx_ael.c  line:3451 func: pbx_load_module  Sorry, but 7 syntax errors and 2 semantic errors were detected. It doesn't make sense to compile.
+LOG: lev:4 file:ael2_parse  line:261 func: main  0 contexts, 0 extensions, 0 priorities
diff --git a/pbx/ael/ael-test/ref.ael-test7 b/pbx/ael/ael-test/ref.ael-test7
new file mode 100644
index 0000000000..b95eaf4983
--- /dev/null
+++ b/pbx/ael/ael-test/ref.ael-test7
@@ -0,0 +1,13 @@
+Executed ast_register_file_version();
+LOG: lev:2 file:pbx_ael.c  line:3428 func: pbx_load_module  Starting AEL load process.
+LOG: lev:2 file:pbx_ael.c  line:3435 func: pbx_load_module  AEL load process: calculated config file name './extensions.ael'.
+LOG: lev:2 file:pbx_ael.c  line:3438 func: pbx_load_module  AEL load process: parsed config file name './extensions.ael'.
+LOG: lev:3 file:pbx_ael.c  line:2186 func: check_pval_item  Warning: file ./extensions.ael, line 6-6: expression Console/dsp has operators, but no variables. Interesting...
+LOG: lev:3 file:pbx_ael.c  line:2186 func: check_pval_item  Warning: file ./extensions.ael, line 10-10: expression pstn-spa3k has operators, but no variables. Interesting...
+LOG: lev:4 file:pbx_ael.c  line:2055 func: check_pval_item  Error: file ./extensions.ael, line 98-98: The macro call to checkanddial has 5 arguments, but the macro definition has 7 arguments
+LOG: lev:4 file:pbx_ael.c  line:2055 func: check_pval_item  Error: file ./extensions.ael, line 107-107: The macro call to checkanddial has 5 arguments, but the macro definition has 7 arguments
+LOG: lev:4 file:pbx_ael.c  line:2055 func: check_pval_item  Error: file ./extensions.ael, line 284-284: The macro call to checkanddial has 5 arguments, but the macro definition has 7 arguments
+LOG: lev:4 file:pbx_ael.c  line:2055 func: check_pval_item  Error: file ./extensions.ael, line 287-287: The macro call to checkanddial has 5 arguments, but the macro definition has 7 arguments
+LOG: lev:4 file:pbx_ael.c  line:2036 func: check_pval_item  Error: file ./extensions.ael, line 452-452: macro call to non-existent std-exten-ael !
+LOG: lev:4 file:pbx_ael.c  line:3451 func: pbx_load_module  Sorry, but 0 syntax errors and 5 semantic errors were detected. It doesn't make sense to compile.
+LOG: lev:4 file:ael2_parse  line:261 func: main  0 contexts, 0 extensions, 0 priorities
diff --git a/pbx/ael/ael-test/runtests b/pbx/ael/ael-test/runtests
new file mode 100755
index 0000000000..c0d148de48
--- /dev/null
+++ b/pbx/ael/ael-test/runtests
@@ -0,0 +1,14 @@
+#!/bin/bash
+
+for i in ael-test*; do
+	echo -n Test: $i..................
+	(cd $i; ../../../../utils/aelparse -n -d | grep -v -i 'seconds' > ../res.$i)
+	if (diff -q res.$i ref.$i > /dev/null 2>&1 ) then
+		echo PASSED
+		rm res.$i
+	else
+		echo %%%%%%FAILED%%%%%%
+		diff -u ref.$i res.$i
+	fi
+
+done
diff --git a/pbx/ael/ael-test/setref b/pbx/ael/ael-test/setref
new file mode 100755
index 0000000000..b483f05ae1
--- /dev/null
+++ b/pbx/ael/ael-test/setref
@@ -0,0 +1,7 @@
+#!/bin/bash
+
+for i in res.*; do
+	refname=`echo $i | sed 's/^res/ref/'`
+	echo $refname
+	mv $i $refname
+done
diff --git a/pbx/ael/ael.flex b/pbx/ael/ael.flex
new file mode 100644
index 0000000000..bcc2cf90e3
--- /dev/null
+++ b/pbx/ael/ael.flex
@@ -0,0 +1,633 @@
+%{
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 2006, Digium, Inc.
+ *
+ * Steve Murphy <murf@parsetree.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+/*! \file
+ *
+ * \brief Flex scanner description of tokens used in AEL2 .
+ * 
+ */#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include "asterisk.h"
+#include "asterisk/logger.h"
+#include "ael.tab.h"
+#include "asterisk/ael_structs.h"
+
+static char pbcstack[400];
+static int pbcpos = 0;
+
+static int parencount = 0;
+static int commaout = 0;
+int my_lineno = 1;
+int my_col = 0;
+char *my_file = 0;
+char *prev_word;
+#define MAX_INCLUDE_DEPTH 50
+
+void reset_parencount(yyscan_t yyscanner );
+void reset_semicount(yyscan_t yyscanner );
+void reset_argcount(yyscan_t yyscanner );
+struct pval *ael2_parse(char *filename, int *errors);
+int ael_yyget_column  (yyscan_t yyscanner);
+void ael_yyset_column (int  column_no , yyscan_t yyscanner);
+int ael_yyparse (struct parse_io *);
+static void pbcpush(char x);
+static int pbcpop(char x);
+static void pbcwhere(char *text, int *line, int *col );
+static int c_prevword(void);
+
+struct stackelement
+{
+     char *fname;
+	 int lineno;
+     int colno;
+	 YY_BUFFER_STATE bufstate;
+};
+struct stackelement  include_stack[MAX_INCLUDE_DEPTH];
+int include_stack_index = 0;
+
+%}
+
+%x paren semic argg
+%option prefix="ael_yy"
+%option batch
+%option outfile="ael_lex.c"
+%option reentrant
+%option bison-bridge
+%option bison-locations
+/* %option yylineno I've tried hard, but haven't been able to use this */
+%option noyywrap
+
+%%
+\{	{yylloc->first_line = yylloc->last_line = my_lineno; yylloc->last_column=my_col+yyleng-1; yylloc->first_column=my_col;my_col+=yyleng;return LC;}
+\}	{yylloc->first_line = yylloc->last_line = my_lineno; yylloc->last_column=my_col+yyleng-1; yylloc->first_column=my_col;my_col+=yyleng;return RC;}
+\(	{yylloc->first_line = yylloc->last_line = my_lineno; yylloc->last_column=my_col+yyleng-1; yylloc->first_column=my_col;my_col+=yyleng;return LP;}
+\)	{yylloc->first_line = yylloc->last_line = my_lineno; yylloc->last_column=my_col+yyleng-1; yylloc->first_column=my_col;my_col+=yyleng;return RP;}
+\;	{yylloc->first_line = yylloc->last_line = my_lineno; yylloc->last_column=my_col+yyleng-1; yylloc->first_column=my_col;my_col+=yyleng;return SEMI;}
+\=	{yylloc->first_line = yylloc->last_line = my_lineno; yylloc->last_column=my_col+yyleng-1; yylloc->first_column=my_col;my_col+=yyleng;return EQ;}
+\,	{yylloc->first_line = yylloc->last_line = my_lineno; yylloc->last_column=my_col+yyleng-1; yylloc->first_column=my_col;my_col+=yyleng;return COMMA;}
+\:	{yylloc->first_line = yylloc->last_line = my_lineno; yylloc->last_column=my_col+yyleng-1; yylloc->first_column=my_col;my_col+=yyleng;return COLON;}
+\&	{yylloc->first_line = yylloc->last_line = my_lineno; yylloc->last_column=my_col+yyleng-1; yylloc->first_column=my_col;my_col+=yyleng;return AMPER;}
+\|	{yylloc->first_line = yylloc->last_line = my_lineno; yylloc->last_column=my_col+yyleng-1; yylloc->first_column=my_col;my_col+=yyleng;return BAR;}
+\=\>	{yylloc->first_line = yylloc->last_line = my_lineno; yylloc->last_column=my_col+yyleng-1; yylloc->first_column=my_col;my_col+=yyleng;return EXTENMARK;}
+\@	{yylloc->first_line = yylloc->last_line = my_lineno; yylloc->last_column=my_col+yyleng-1; yylloc->first_column=my_col;my_col+=yyleng;return AT;}
+\/\/[^\n]*  {/*comment*/}
+context	{yylloc->first_line = yylloc->last_line = my_lineno; yylloc->last_column=my_col+yyleng-1; yylloc->first_column=my_col;my_col+=yyleng;return KW_CONTEXT;}
+abstract	{yylloc->first_line = yylloc->last_line = my_lineno; yylloc->last_column=my_col+yyleng-1; yylloc->first_column=my_col;my_col+=yyleng;return KW_ABSTRACT;}
+macro	{yylloc->first_line = yylloc->last_line = my_lineno; yylloc->last_column=my_col+yyleng-1; yylloc->first_column=my_col;my_col+=yyleng;return KW_MACRO;};
+globals	{yylloc->first_line = yylloc->last_line = my_lineno; yylloc->last_column=my_col+yyleng-1; yylloc->first_column=my_col;my_col+=yyleng;return KW_GLOBALS;}
+ignorepat	{yylloc->first_line = yylloc->last_line = my_lineno; yylloc->last_column=my_col+yyleng-1; yylloc->first_column=my_col;my_col+=yyleng;return KW_IGNOREPAT;}
+switch	{yylloc->first_line = yylloc->last_line = my_lineno; yylloc->last_column=my_col+yyleng-1; yylloc->first_column=my_col;my_col+=yyleng;return KW_SWITCH;}
+if	{yylloc->first_line = yylloc->last_line = my_lineno; yylloc->last_column=my_col+yyleng-1; yylloc->first_column=my_col;my_col+=yyleng;return KW_IF;}
+ifTime	{yylloc->first_line = yylloc->last_line = my_lineno; yylloc->last_column=my_col+yyleng-1; yylloc->first_column=my_col;my_col+=yyleng;return KW_IFTIME;}
+random	{yylloc->first_line = yylloc->last_line = my_lineno; yylloc->last_column=my_col+yyleng-1; yylloc->first_column=my_col;my_col+=yyleng;return KW_RANDOM;}
+regexten	{yylloc->first_line = yylloc->last_line = my_lineno; yylloc->last_column=my_col+yyleng-1; yylloc->first_column=my_col;my_col+=yyleng;return KW_REGEXTEN;}
+hint	{yylloc->first_line = yylloc->last_line = my_lineno; yylloc->last_column=my_col+yyleng-1; yylloc->first_column=my_col;my_col+=yyleng;return KW_HINT;}
+else	{yylloc->first_line = yylloc->last_line = my_lineno; yylloc->last_column=my_col+yyleng-1; yylloc->first_column=my_col;my_col+=yyleng;return KW_ELSE;}
+goto	{yylloc->first_line = yylloc->last_line = my_lineno; yylloc->last_column=my_col+yyleng-1; yylloc->first_column=my_col;my_col+=yyleng;return KW_GOTO;}
+jump	{yylloc->first_line = yylloc->last_line = my_lineno; yylloc->last_column=my_col+yyleng-1; yylloc->first_column=my_col;my_col+=yyleng;return KW_JUMP;}
+return	{yylloc->first_line = yylloc->last_line = my_lineno; yylloc->last_column=my_col+yyleng-1; yylloc->first_column=my_col;my_col+=yyleng;return KW_RETURN;}
+break	{yylloc->first_line = yylloc->last_line = my_lineno; yylloc->last_column=my_col+yyleng-1; yylloc->first_column=my_col;my_col+=yyleng;return KW_BREAK;}
+continue	{yylloc->first_line = yylloc->last_line = my_lineno; yylloc->last_column=my_col+yyleng-1; yylloc->first_column=my_col;my_col+=yyleng;return KW_CONTINUE;}
+for	{yylloc->first_line = yylloc->last_line = my_lineno; yylloc->last_column=my_col+yyleng-1; yylloc->first_column=my_col;my_col+=yyleng;return KW_FOR;}
+while	{yylloc->first_line = yylloc->last_line = my_lineno; yylloc->last_column=my_col+yyleng-1; yylloc->first_column=my_col;my_col+=yyleng;return KW_WHILE;}
+case	{yylloc->first_line = yylloc->last_line = my_lineno; yylloc->last_column=my_col+yyleng-1; yylloc->first_column=my_col;my_col+=yyleng;return KW_CASE;}
+default	{yylloc->first_line = yylloc->last_line = my_lineno; yylloc->last_column=my_col+yyleng-1; yylloc->first_column=my_col;my_col+=yyleng;return KW_DEFAULT;}
+pattern	{yylloc->first_line = yylloc->last_line = my_lineno; yylloc->last_column=my_col+yyleng-1; yylloc->first_column=my_col;my_col+=yyleng;return KW_PATTERN;}
+catch	{yylloc->first_line = yylloc->last_line = my_lineno; yylloc->last_column=my_col+yyleng-1; yylloc->first_column=my_col;my_col+=yyleng;return KW_CATCH;}
+switches	{yylloc->first_line = yylloc->last_line = my_lineno; yylloc->last_column=my_col+yyleng-1; yylloc->first_column=my_col;my_col+=yyleng;return KW_SWITCHES;}
+eswitches	{yylloc->first_line = yylloc->last_line = my_lineno; yylloc->last_column=my_col+yyleng-1; yylloc->first_column=my_col;my_col+=yyleng;return KW_ESWITCHES;}
+includes	{yylloc->first_line = yylloc->last_line = my_lineno; yylloc->last_column=my_col+yyleng-1; yylloc->first_column=my_col;my_col+=yyleng;return KW_INCLUDES;}
+
+\n		{my_lineno++;my_col=0;}
+[ ]+	{/* nothing */ my_col+=yyleng;}
+[	]+	{/* nothing */ int wid = 8-(my_col%8); my_col+=wid;}
+
+[-a-zA-Z0-9'"_/.\<\>\*\+!$#\[\]][-a-zA-Z0-9'"_/.!\*\+\<\>\{\}$#\[\]]*	{
+                                               yylloc->first_line = yylloc->last_line = my_lineno;yylloc->last_column=my_col+yyleng-1; yylloc->first_column=my_col; /* set up the ptr */
+                                               yylval->str = strdup(yytext);  
+                                               /* printf("\nGot WORD %s[%d][%d:%d]\n", yylval->str, my_lineno ,yylloc->first_column,yylloc->last_column );  */
+                                               my_col+=yyleng; 
+                                               prev_word = yylval->str;
+                                               return word;
+                                        }
+
+<paren>[^()\[\]\{\}]*\)	{yylloc->first_line = my_lineno; yylloc->first_column=my_col; 
+                         if ( pbcpop(')') ) {
+                             /* error */
+                             int l4,c4;
+                             pbcwhere(yytext, &l4, &c4);
+                             ast_log(LOG_ERROR,"File=%s, line=%d, column=%d: Mismatched ')' in expression: %s !\n", my_file, my_lineno+l4, c4, yytext);
+                             BEGIN(0);
+                             yylloc->last_line = my_lineno+l4;
+                             yylloc->last_column=c4; 
+                             my_col=c4;
+                             my_lineno += l4;
+		                     yylval->str = strdup(yytext);
+                             prev_word = 0;
+                             return word;
+                         }
+                 parencount--;
+                 if ( parencount >= 0) {
+                   yymore();
+                 } else { 
+                   int l4,c4;
+                   pbcwhere(yytext, &l4, &c4);
+                   yylloc->last_line = my_lineno+l4;
+				   yylloc->last_column=c4; 
+                   yylval->str = strdup(yytext); 
+                   *(yylval->str+strlen(yylval->str)-1)=0;
+                   /* printf("Got paren word %s\n", yylval->str); */ 
+                   unput(')'); 
+	               my_col=c4;
+                   my_lineno += l4;
+                   BEGIN(0); 
+                   return word;
+                 } 
+                }
+
+<paren>[^()\[\]\{\}]*\(	{yylloc->first_line = my_lineno; yylloc->first_column=my_col; 
+                  parencount++; pbcpush('(');
+                  yymore();
+                 }
+<paren>[^()\[\]\{\}]*\[	{yylloc->first_line = my_lineno;yylloc->first_column=my_col; yymore(); pbcpush('['); }
+<paren>[^()\[\]\{\}]*\]	{yylloc->first_line = my_lineno;yylloc->first_column=my_col; 
+                         if ( pbcpop(']') ) {
+                             /* error */
+                             int l4,c4;
+                             pbcwhere(yytext, &l4, &c4);
+                             ast_log(LOG_ERROR,"File=%s, line=%d, column=%d: Mismatched ']' in expression!\n", my_file, my_lineno+l4, c4);
+                             BEGIN(0);
+                             yylloc->last_line = my_lineno+l4;
+                             yylloc->last_column=c4; 
+                             my_col=c4;
+                             my_lineno += l4;
+		                     yylval->str = strdup(yytext);
+                             return word;
+                         }
+                         yymore();
+                        }
+<paren>[^()\[\]\{\}]*\{	{yylloc->first_line = my_lineno;yylloc->first_column=my_col;  yymore(); pbcpush('{'); }
+<paren>[^()\[\]\{\}]*\}	{yylloc->first_line = my_lineno;
+                         yylloc->first_column=my_col; 
+                         if ( pbcpop('}') ) {
+                             /* error */
+                             int l4,c4;
+                             pbcwhere(yytext, &l4, &c4);
+                             ast_log(LOG_ERROR,"File=%s, line=%d, column=%d: Mismatched '}' in expression!\n", my_file, my_lineno+l4, c4);
+                             BEGIN(0);
+                             yylloc->last_line = my_lineno+l4;
+                             yylloc->last_column=c4; 
+                             my_col=c4;
+                             my_lineno += l4;
+		                     yylval->str = strdup(yytext);
+                             return word;
+                         }
+                         yymore();
+                        }
+
+
+<argg>[^(),\{\}\[\]]*\)	{/* printf("ARGG:%s\n",yytext); */
+					int linecount = 0;
+                    int colcount = my_col;
+					char *pt = yytext;
+
+					yylloc->first_line = my_lineno;
+                    yylloc->first_column=my_col; 
+                         if ( pbcpop(')') ) {
+                             /* error */
+                             int l4,c4;
+                             pbcwhere(yytext, &l4, &c4);
+                             ast_log(LOG_ERROR,"File=%s, line=%d, column=%d: Mismatched ')' in expression!\n", my_file, my_lineno+l4, c4);
+                             BEGIN(0);
+                             yylloc->last_line = my_lineno+l4;
+                             yylloc->last_column=c4; 
+                             my_col=c4;
+                             my_lineno += l4;
+		                     yylval->str = strdup(yytext);
+                             return word;
+                         }
+                   
+
+					while (*pt) {
+                       if (*pt == '\n') {
+                           linecount++;
+                           colcount=0;
+                       }
+                       pt++;
+                       colcount++;
+                    }
+                    yylloc->last_line = my_lineno+linecount;
+                    yylloc->last_column=colcount; 
+                    parencount--;
+                    if( parencount >= 0){ 
+                        yymore(); 
+                    } else { 
+                        yylval->str = strdup(yytext); 
+					   if(yyleng > 1 ) 
+                              *(yylval->str+yyleng-1)=0;
+                       /* printf("Got argg word '%s'\n", yylval->str);  */
+                       BEGIN(0); 
+                       if ( !strcmp(yylval->str,")") ) { 
+                             free(yylval->str); 
+                             yylval->str = 0; 
+                             my_col+=1;
+                             return RP;  
+                       } else {
+                             unput(')');
+                             my_col=colcount;
+							 my_lineno+=linecount;
+                             return word;
+                       }
+                    } 
+                }
+<argg>[^(),\{\}\[\]]*\(	  { /* printf("ARGG:%s\n",yytext); */
+                      /* printf("GOT AN LP!!!\n"); */
+                      yylloc->first_line = my_lineno;
+                      yylloc->first_column=my_col; 
+                      parencount++; 
+                      pbcpush('(');
+                      yymore();
+                  }
+
+<argg>[^(),\{\}\[\]]*\,	{  /* printf("ARGG:%s\n",yytext); */
+                  if( parencount != 0) { 
+					/* printf("Folding in a comma!\n"); */ 
+					yymore();
+				  } else  { 
+                     /* printf("got a comma!\n\n");  */
+					 int linecount = 0;
+                     int colcount = my_col;
+					 char *pt;
+
+					 pt = yytext;
+					 while (*pt) {
+                        if ( *pt == '\n' ) {
+                           linecount++;
+                           colcount=0;
+                        }
+                        pt++;
+                        colcount++;
+                     }
+                     yylloc->first_line = my_lineno; 
+                     yylloc->last_line = my_lineno+linecount; 
+                     yylloc->last_column=colcount; 
+                     yylloc->first_column=my_col;
+                     if( !commaout ) { 
+						if( !strcmp(yytext,"," ) ) 
+							{commaout = 0; my_col+=1; return COMMA;} 
+						yylval->str = strdup(yytext); /* printf("Got argg2 word %s\n", yylval->str); */ 
+						unput(','); 
+						commaout = 1; 
+						if(yyleng > 1 ) 
+							*(yylval->str+yyleng-1)=0;
+                        my_lineno+=linecount;
+						my_col=colcount;
+						return word;
+					 } else {
+                            commaout = 0;
+							my_col+=1;
+							return COMMA;
+						}
+                   }
+				}
+
+<argg>[^(),\{\}\[\]]*\{	{/*printf("ARGG:%s\n",yytext);*/yylloc->first_line = my_lineno;yylloc->first_column=my_col; pbcpush('{'); yymore();  }
+<argg>[^(),\{\}\[\]]*\}	{/*printf("ARGG:%s\n",yytext);*/yylloc->first_line = my_lineno;yylloc->first_column=my_col; 
+                         if ( pbcpop('}') ) {
+                             /* error */
+                             int l4,c4;
+                             pbcwhere(yytext, &l4, &c4);
+                             ast_log(LOG_ERROR,"File=%s, line=%d, column=%d: Mismatched '}' in expression!\n", my_file, my_lineno+l4, my_col+c4);
+                             BEGIN(0);
+                             yylloc->last_line = my_lineno+l4;
+                             yylloc->last_column=my_col+c4; 
+                             my_col=c4;
+                             my_lineno += l4;
+		                     yylval->str = strdup(yytext);
+                             return word;
+                         }
+                         yymore();
+				}
+<argg>[^(),\{\}\[\]]*\[	{/*printf("ARGG:%s\n",yytext);*/yylloc->first_line = my_lineno;yylloc->first_column=my_col; yymore(); pbcpush('['); }
+<argg>[^(),\{\}\[\]]*\]	{/*printf("ARGG:%s\n",yytext);*/yylloc->first_line = my_lineno;yylloc->first_column=my_col; 
+                         if ( pbcpop(']') ) {
+                             /* error */
+                             int l4,c4;
+                             pbcwhere(yytext, &l4, &c4);
+                             ast_log(LOG_ERROR,"File=%s, line=%d, column=%d: Mismatched ']' in expression!\n", my_file, my_lineno+l4, c4);
+                             BEGIN(0);
+                             yylloc->last_line = my_lineno+l4;
+                             yylloc->last_column=c4; 
+                             my_col=c4;
+                             my_lineno += l4;
+		                     yylval->str = strdup(yytext);
+                             return word;
+                         }
+                         yymore();
+				}
+
+
+<semic>[^;()\{\}\[\]]*\[	{/*printf("SEMIC:%s\n",yytext);*/yylloc->first_line = my_lineno;yylloc->first_column=my_col; yymore(); pbcpush('['); }
+<semic>[^;()\{\}\[\]]*\]	{/*printf("SEMIC:%s\n",yytext);*/yylloc->first_line = my_lineno;yylloc->first_column=my_col; 
+                         if ( pbcpop(']') ) {
+                             /* error */
+                             int l4,c4;
+                             pbcwhere(yytext, &l4, &c4);
+                             ast_log(LOG_ERROR,"File=%s, line=%d, column=%d: Mismatched ']' in expression!\n", my_file, my_lineno+l4, c4);
+                             BEGIN(0);
+                             yylloc->last_line = my_lineno+l4;
+                             yylloc->last_column=c4; 
+                             my_col=c4;
+                             my_lineno += l4;
+		                     yylval->str = strdup(yytext);
+                             return word;
+                         }
+                         yymore();}
+<semic>[^;()\{\}\[\]]*\{	{/*printf("SEMIC:%s\n",yytext);*/yylloc->first_line = my_lineno;yylloc->first_column=my_col; yymore(); pbcpush('{');}
+<semic>[^;()\{\}\[\]]*\}	{/*printf("SEMIC:%s\n",yytext);*/yylloc->first_line = my_lineno;yylloc->first_column=my_col; 
+                         if ( pbcpop('}') ) {
+                             /* error */
+                             int l4,c4;
+                             pbcwhere(yytext, &l4, &c4);
+                             ast_log(LOG_ERROR,"File=%s, line=%d, column=%d: Mismatched '}' in expression!\n", my_file, my_lineno+l4, my_col+c4);
+                             BEGIN(0);
+                             yylloc->last_line = my_lineno+l4;
+                             yylloc->last_column=my_col+c4; 
+                             my_col=c4;
+                             my_lineno += l4;
+		                     yylval->str = strdup(yytext);
+                             return word;
+                         }
+                         yymore();}
+<semic>[^;()\{\}\[\]]*\(	{/*printf("SEMIC:%s\n",yytext);*/yylloc->first_line = my_lineno;yylloc->first_column=my_col; yymore(); pbcpush('(');}
+<semic>[^;()\{\}\[\]]*\)	{/*printf("SEMIC:%s\n",yytext);*/yylloc->first_line = my_lineno;yylloc->first_column=my_col; 
+                         if ( pbcpop(')') ) {
+                             /* error */
+                             int l4,c4;
+                             pbcwhere(yytext, &l4, &c4);
+                             ast_log(LOG_ERROR,"File=%s, line=%d, column=%d: Mismatched ')' in expression!\n", my_file, my_lineno+l4, my_col+c4);
+                             BEGIN(0);
+                             yylloc->last_line = my_lineno+l4;
+                             yylloc->last_column=my_col+c4; 
+                             my_col=c4;
+                             my_lineno += l4;
+		                     yylval->str = strdup(yytext);
+                             return word;
+                         }
+                         yymore();}
+<semic>[^;()\{\}\[\]]*;	{
+					int linecount = 0;
+                    int colcount = my_col;
+					char *pt = yytext;
+					while (*pt) {
+                       if ( *pt == '\n' ) {
+                           linecount++;
+                           colcount=0;
+                       }
+                       pt++;
+                       colcount++;
+                    }
+                    yylloc->first_line = my_lineno; 
+					yylloc->last_line = my_lineno+linecount; 
+					yylloc->last_column=colcount; 
+					yylloc->first_column=my_col;
+                    yylval->str = strdup(yytext);
+                    if(yyleng > 1)
+                      *(yylval->str+yyleng-1)=0;
+                    /* printf("Got semic word %s\n", yylval->str); */
+                    unput(';');
+                    BEGIN(0);
+                    my_col=colcount;
+                    my_lineno += linecount;
+                    return word;
+                }
+
+\#include[ \t]+\"[^\"]+\" {
+                     FILE *in1;
+					 char fnamebuf[1024],*p1,*p2;
+                     if ( include_stack_index >= MAX_INCLUDE_DEPTH ) {
+						ast_log(LOG_ERROR,"File=%s, line=%d, column=%d: Includes nested too deeply! Wow!!! How did you do that?\n", my_file, my_lineno, my_col);
+                     } else {
+                         p1 = strchr(yytext,'"');
+                         p2 = strrchr(yytext,'"');
+                         if ( (int)(p2-p1) > 1023 ) {
+							ast_log(LOG_ERROR,"File=%s, line=%d, column=%d: Filename is incredibly way too long (%d chars!). Inclusion ignored!\n", my_file, my_lineno, my_col, yyleng - 10);
+        	             } else {
+								int i;
+								int found = 0;
+								strncpy(fnamebuf,p1,p2-p1);
+								fnamebuf[p2-p1] = 0;
+								for (i=0; i<include_stack_index; i++) {
+									if ( !strcmp(fnamebuf,include_stack[i].fname )) {
+										ast_log(LOG_ERROR,"File=%s, line=%d, column=%d: Nice Try!!! But %s has already been included (perhaps by another file), and would cause an infinite loop of file inclusions!!! Include directive ignored\n", 
+												my_file, my_lineno, my_col, fnamebuf);
+										found=1;
+										break;
+									}
+								}
+								if( !found )
+								{
+                                	*p2 = 0;
+                                    /* relative vs. absolute */
+                                    if ( *(p1+1) != '/' )
+                                    {
+                                        strcpy(fnamebuf,ast_config_AST_CONFIG_DIR);
+										strcat(fnamebuf,"/");
+										strcat(fnamebuf,p1+1);
+                                    }
+                                    else
+                                	    strcpy(fnamebuf,p1+1);
+		                        	in1 = fopen( fnamebuf, "r" );
+                                	if ( ! in1 ) {
+						ast_log(LOG_ERROR,"File=%s, line=%d, column=%d: Couldn't find the include file: %s; ignoring the Include directive!\n", my_file, my_lineno, my_col, fnamebuf);
+                                	} else {
+						char *buffer;
+	                             	 	struct stat stats;
+	                            		stat(fnamebuf, &stats);
+	                             		buffer = (char*)malloc(stats.st_size+1);
+	                             		fread(buffer, 1, stats.st_size, in1);
+						buffer[stats.st_size] = 0;
+						ast_log(LOG_NOTICE,"  --Read in included file %s, %d chars\n",fnamebuf, (int)stats.st_size);
+	                                	fclose(in1);
+
+						include_stack[include_stack_index].fname = my_file;
+						my_file = strdup(fnamebuf);
+						include_stack[include_stack_index].lineno = my_lineno;
+						include_stack[include_stack_index].colno = my_col+yyleng;
+						include_stack[include_stack_index++].bufstate = YY_CURRENT_BUFFER;
+
+	                                	yy_switch_to_buffer(ael_yy_scan_string (buffer ,yyscanner),yyscanner);
+                                    		free(buffer);
+                                  	  	my_lineno = 1;
+                                    		my_col = 1;
+                                    		BEGIN(INITIAL);
+                                	}
+                                }
+                         }
+                     }
+                 }
+
+<<EOF>>  {
+                 if ( --include_stack_index < 0 ) {
+                 	    yyterminate();
+                     } else {
+						 free(my_file);
+                         yy_delete_buffer( YY_CURRENT_BUFFER, yyscanner );
+                         yy_switch_to_buffer(include_stack[include_stack_index].bufstate, yyscanner );
+                         my_lineno = include_stack[include_stack_index].lineno;
+                         my_col    = include_stack[include_stack_index].colno;
+                         my_file   = include_stack[include_stack_index].fname;
+                     }
+          }
+
+
+%%
+
+static void pbcpush(char x)
+{
+	pbcstack[pbcpos++] = x;
+}
+
+static int pbcpop(char x)
+{
+	if (   ( x == ')' && pbcstack[pbcpos-1] == '(' )
+		|| ( x == ']' && pbcstack[pbcpos-1] == '[' )
+		|| ( x == '}' && pbcstack[pbcpos-1] == '{' )) {
+		pbcpos--;
+		return 0;
+	}
+	else
+		return 1; /* error */
+}
+
+static int c_prevword(void)
+{
+    char *c = prev_word;
+	int ret = 0;
+	while ( c && *c ) {
+        switch (*c) {
+            case '{': pbcpush('{');break;
+            case '}': ret = pbcpop('}');break;
+            case '[':pbcpush('[');break;
+            case ']':ret = pbcpop(']');break;
+            case '(':pbcpush('(');break;
+            case ')':ret = pbcpop(')'); break;
+        }
+        if( ret )
+            return 1;
+		c++;
+	}
+	return 0;
+}
+
+static void pbcwhere(char *text, int *line, int *col )
+{
+	int loc_line = 0;
+    int loc_col = 0;
+	while ( *text ) {
+       if ( *text == '\n' ) {
+             loc_line++;
+             loc_col = 1;
+       } else {
+             loc_col++;
+       }
+       text++;
+    }
+	*line = loc_line;
+    *col = loc_col;
+}
+
+void reset_parencount(yyscan_t yyscanner )
+{
+	struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+	parencount = 0;
+	pbcpos = 0;
+	pbcpush('(');
+	c_prevword();
+	BEGIN(paren);
+}
+
+void reset_semicount(yyscan_t yyscanner )
+{
+	struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+	pbcpos = 0;
+	BEGIN(semic);
+}
+
+void reset_argcount(yyscan_t yyscanner )
+{
+	struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+	parencount = 0;
+	pbcpos = 0;
+	commaout = 0;
+	pbcpush('(');
+	c_prevword();
+	BEGIN(argg);
+}
+
+
+struct pval *ael2_parse(char *filename, int *errors)
+{
+	struct pval *pval;
+	struct parse_io *io;
+	char *buffer;
+	struct stat stats;
+	FILE *fin;
+
+	/* extern int ael_yydebug; */
+
+	io = calloc(sizeof(struct parse_io),1);
+	/* reset the global counters */
+	prev_word = 0;
+	my_lineno = 1;
+	include_stack_index=0;
+	my_col = 0;
+	/* ael_yydebug = 1; */
+	ael_yylex_init(&io->scanner);
+	fin = fopen(filename,"r");
+	if ( !fin ) {
+		ast_log(LOG_ERROR,"File %s could not be opened\n", filename);
+		*errors = 1;
+		return 0;
+	}
+	my_file = strdup(filename);
+	stat(filename, &stats);
+	buffer = (char*)malloc(stats.st_size+2);
+	fread(buffer, 1, stats.st_size, fin);
+	buffer[stats.st_size]=0;
+	fclose(fin);
+	
+	ael_yy_scan_string (buffer ,io->scanner);
+	ael_yyset_lineno(1 , io->scanner);
+
+	/* ael_yyset_in (fin , io->scanner);	OLD WAY */
+
+	ael_yyparse(io);
+
+
+	pval = io->pval;
+	*errors = io->syntax_error_count;
+
+	ael_yylex_destroy(io->scanner);
+	free(buffer);
+	free(io);
+
+	return pval;
+}
diff --git a/pbx/ael/ael.tab.c b/pbx/ael/ael.tab.c
new file mode 100644
index 0000000000..4f00b05a61
--- /dev/null
+++ b/pbx/ael/ael.tab.c
@@ -0,0 +1,3192 @@
+/* A Bison parser, made by GNU Bison 2.1.  */
+
+/* Skeleton parser for Yacc-like parsing with Bison,
+   Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street, Fifth Floor,
+   Boston, MA 02110-1301, USA.  */
+
+/* As a special exception, when this file is copied by Bison into a
+   Bison output file, you may use that output file without restriction.
+   This special exception was added by the Free Software Foundation
+   in version 1.24 of Bison.  */
+
+/* Written by Richard Stallman by simplifying the original so called
+   ``semantic'' parser.  */
+
+/* All symbols defined below should begin with yy or YY, to avoid
+   infringing on user name space.  This should be done even for local
+   variables, as they might otherwise be expanded by user macros.
+   There are some unavoidable exceptions within include files to
+   define necessary library symbols; they are noted "INFRINGES ON
+   USER NAME SPACE" below.  */
+
+/* Identify Bison output.  */
+#define YYBISON 1
+
+/* Bison version.  */
+#define YYBISON_VERSION "2.1"
+
+/* Skeleton name.  */
+#define YYSKELETON_NAME "yacc.c"
+
+/* Pure parsers.  */
+#define YYPURE 1
+
+/* Using locations.  */
+#define YYLSP_NEEDED 1
+
+/* Substitute the variable and function names.  */
+#define yyparse ael_yyparse
+#define yylex   ael_yylex
+#define yyerror ael_yyerror
+#define yylval  ael_yylval
+#define yychar  ael_yychar
+#define yydebug ael_yydebug
+#define yynerrs ael_yynerrs
+#define yylloc ael_yylloc
+
+/* Tokens.  */
+#ifndef YYTOKENTYPE
+# define YYTOKENTYPE
+   /* Put the tokens into the symbol table, so that GDB and other debuggers
+      know about them.  */
+   enum yytokentype {
+     KW_CONTEXT = 258,
+     LC = 259,
+     RC = 260,
+     LP = 261,
+     RP = 262,
+     SEMI = 263,
+     EQ = 264,
+     COMMA = 265,
+     COLON = 266,
+     AMPER = 267,
+     BAR = 268,
+     AT = 269,
+     KW_MACRO = 270,
+     KW_GLOBALS = 271,
+     KW_IGNOREPAT = 272,
+     KW_SWITCH = 273,
+     KW_IF = 274,
+     KW_IFTIME = 275,
+     KW_ELSE = 276,
+     KW_RANDOM = 277,
+     KW_ABSTRACT = 278,
+     EXTENMARK = 279,
+     KW_GOTO = 280,
+     KW_JUMP = 281,
+     KW_RETURN = 282,
+     KW_BREAK = 283,
+     KW_CONTINUE = 284,
+     KW_REGEXTEN = 285,
+     KW_HINT = 286,
+     KW_FOR = 287,
+     KW_WHILE = 288,
+     KW_CASE = 289,
+     KW_PATTERN = 290,
+     KW_DEFAULT = 291,
+     KW_CATCH = 292,
+     KW_SWITCHES = 293,
+     KW_ESWITCHES = 294,
+     KW_INCLUDES = 295,
+     word = 296
+   };
+#endif
+/* Tokens.  */
+#define KW_CONTEXT 258
+#define LC 259
+#define RC 260
+#define LP 261
+#define RP 262
+#define SEMI 263
+#define EQ 264
+#define COMMA 265
+#define COLON 266
+#define AMPER 267
+#define BAR 268
+#define AT 269
+#define KW_MACRO 270
+#define KW_GLOBALS 271
+#define KW_IGNOREPAT 272
+#define KW_SWITCH 273
+#define KW_IF 274
+#define KW_IFTIME 275
+#define KW_ELSE 276
+#define KW_RANDOM 277
+#define KW_ABSTRACT 278
+#define EXTENMARK 279
+#define KW_GOTO 280
+#define KW_JUMP 281
+#define KW_RETURN 282
+#define KW_BREAK 283
+#define KW_CONTINUE 284
+#define KW_REGEXTEN 285
+#define KW_HINT 286
+#define KW_FOR 287
+#define KW_WHILE 288
+#define KW_CASE 289
+#define KW_PATTERN 290
+#define KW_DEFAULT 291
+#define KW_CATCH 292
+#define KW_SWITCHES 293
+#define KW_ESWITCHES 294
+#define KW_INCLUDES 295
+#define word 296
+
+
+
+
+/* Copy the first part of user declarations.  */
+#line 1 "ael.y"
+
+/*
+ * Asterisk -- An open source telephony toolkit. 
+ *
+ * Copyright (C) 2006, Digium, Inc.
+ *
+ * Steve Murphy <murf@parsetree.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+/*! \file
+ *
+ * \brief Bison Grammar description of AEL2.
+ * 
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "asterisk/logger.h"
+#include "asterisk/ael_structs.h"
+
+extern void reset_parencount(yyscan_t yyscanner);
+extern void reset_semicount(yyscan_t yyscanner);
+extern void reset_argcount(yyscan_t yyscanner );
+
+#define YYLEX_PARAM ((struct parse_io *)parseio)->scanner
+#define YYERROR_VERBOSE 1
+
+extern char *my_file;
+#ifdef AAL_ARGCHECK
+int ael_is_funcname(char *name);
+#endif
+ static char *ael_token_subst(char *mess);
+ extern char *prev_word;
+ 
+
+
+/* Enabling traces.  */
+#ifndef YYDEBUG
+# define YYDEBUG 0
+#endif
+
+/* Enabling verbose error messages.  */
+#ifdef YYERROR_VERBOSE
+# undef YYERROR_VERBOSE
+# define YYERROR_VERBOSE 1
+#else
+# define YYERROR_VERBOSE 1
+#endif
+
+/* Enabling the token table.  */
+#ifndef YYTOKEN_TABLE
+# define YYTOKEN_TABLE 0
+#endif
+
+#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED)
+#line 47 "ael.y"
+typedef union YYSTYPE {
+	char *str;
+	struct pval *pval;
+} YYSTYPE;
+/* Line 196 of yacc.c.  */
+#line 225 "ael.tab.c"
+# define yystype YYSTYPE /* obsolescent; will be withdrawn */
+# define YYSTYPE_IS_DECLARED 1
+# define YYSTYPE_IS_TRIVIAL 1
+#endif
+
+#if ! defined (YYLTYPE) && ! defined (YYLTYPE_IS_DECLARED)
+typedef struct YYLTYPE
+{
+  int first_line;
+  int first_column;
+  int last_line;
+  int last_column;
+} YYLTYPE;
+# define yyltype YYLTYPE /* obsolescent; will be withdrawn */
+# define YYLTYPE_IS_DECLARED 1
+# define YYLTYPE_IS_TRIVIAL 1
+#endif
+
+
+/* Copy the second part of user declarations.  */
+#line 52 "ael.y"
+
+	/* declaring these AFTER the union makes things a lot simpler! */
+void yyerror(YYLTYPE *locp, struct parse_io *parseio, char const *s);
+int ael_yylex (YYSTYPE * yylval_param, YYLTYPE * yylloc_param , void * yyscanner);
+	
+
+
+/* Line 219 of yacc.c.  */
+#line 255 "ael.tab.c"
+
+#if ! defined (YYSIZE_T) && defined (__SIZE_TYPE__)
+# define YYSIZE_T __SIZE_TYPE__
+#endif
+#if ! defined (YYSIZE_T) && defined (size_t)
+# define YYSIZE_T size_t
+#endif
+#if ! defined (YYSIZE_T) && (defined (__STDC__) || defined (__cplusplus))
+# include <stddef.h> /* INFRINGES ON USER NAME SPACE */
+# define YYSIZE_T size_t
+#endif
+#if ! defined (YYSIZE_T)
+# define YYSIZE_T unsigned int
+#endif
+
+#ifndef YY_
+# if YYENABLE_NLS
+#  if ENABLE_NLS
+#   include <libintl.h> /* INFRINGES ON USER NAME SPACE */
+#   define YY_(msgid) dgettext ("bison-runtime", msgid)
+#  endif
+# endif
+# ifndef YY_
+#  define YY_(msgid) msgid
+# endif
+#endif
+
+#if ! defined (yyoverflow) || YYERROR_VERBOSE
+
+/* The parser invokes alloca or malloc; define the necessary symbols.  */
+
+# ifdef YYSTACK_USE_ALLOCA
+#  if YYSTACK_USE_ALLOCA
+#   ifdef __GNUC__
+#    define YYSTACK_ALLOC __builtin_alloca
+#   else
+#    define YYSTACK_ALLOC alloca
+#    if defined (__STDC__) || defined (__cplusplus)
+#     include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
+#     define YYINCLUDED_STDLIB_H
+#    endif
+#   endif
+#  endif
+# endif
+
+# ifdef YYSTACK_ALLOC
+   /* Pacify GCC's `empty if-body' warning. */
+#  define YYSTACK_FREE(Ptr) do { /* empty */; } while (0)
+#  ifndef YYSTACK_ALLOC_MAXIMUM
+    /* The OS might guarantee only one guard page at the bottom of the stack,
+       and a page size can be as small as 4096 bytes.  So we cannot safely
+       invoke alloca (N) if N exceeds 4096.  Use a slightly smaller number
+       to allow for a few compiler-allocated temporary stack slots.  */
+#   define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2005 */
+#  endif
+# else
+#  define YYSTACK_ALLOC YYMALLOC
+#  define YYSTACK_FREE YYFREE
+#  ifndef YYSTACK_ALLOC_MAXIMUM
+#   define YYSTACK_ALLOC_MAXIMUM ((YYSIZE_T) -1)
+#  endif
+#  ifdef __cplusplus
+extern "C" {
+#  endif
+#  ifndef YYMALLOC
+#   define YYMALLOC malloc
+#   if (! defined (malloc) && ! defined (YYINCLUDED_STDLIB_H) \
+	&& (defined (__STDC__) || defined (__cplusplus)))
+void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */
+#   endif
+#  endif
+#  ifndef YYFREE
+#   define YYFREE free
+#   if (! defined (free) && ! defined (YYINCLUDED_STDLIB_H) \
+	&& (defined (__STDC__) || defined (__cplusplus)))
+void free (void *); /* INFRINGES ON USER NAME SPACE */
+#   endif
+#  endif
+#  ifdef __cplusplus
+}
+#  endif
+# endif
+#endif /* ! defined (yyoverflow) || YYERROR_VERBOSE */
+
+
+#if (! defined (yyoverflow) \
+     && (! defined (__cplusplus) \
+	 || (defined (YYLTYPE_IS_TRIVIAL) && YYLTYPE_IS_TRIVIAL \
+             && defined (YYSTYPE_IS_TRIVIAL) && YYSTYPE_IS_TRIVIAL)))
+
+/* A type that is properly aligned for any stack member.  */
+union yyalloc
+{
+  short int yyss;
+  YYSTYPE yyvs;
+    YYLTYPE yyls;
+};
+
+/* The size of the maximum gap between one aligned stack and the next.  */
+# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1)
+
+/* The size of an array large to enough to hold all stacks, each with
+   N elements.  */
+# define YYSTACK_BYTES(N) \
+     ((N) * (sizeof (short int) + sizeof (YYSTYPE) + sizeof (YYLTYPE))	\
+      + 2 * YYSTACK_GAP_MAXIMUM)
+
+/* Copy COUNT objects from FROM to TO.  The source and destination do
+   not overlap.  */
+# ifndef YYCOPY
+#  if defined (__GNUC__) && 1 < __GNUC__
+#   define YYCOPY(To, From, Count) \
+      __builtin_memcpy (To, From, (Count) * sizeof (*(From)))
+#  else
+#   define YYCOPY(To, From, Count)		\
+      do					\
+	{					\
+	  YYSIZE_T yyi;				\
+	  for (yyi = 0; yyi < (Count); yyi++)	\
+	    (To)[yyi] = (From)[yyi];		\
+	}					\
+      while (0)
+#  endif
+# endif
+
+/* Relocate STACK from its old location to the new one.  The
+   local variables YYSIZE and YYSTACKSIZE give the old and new number of
+   elements in the stack, and YYPTR gives the new location of the
+   stack.  Advance YYPTR to a properly aligned location for the next
+   stack.  */
+# define YYSTACK_RELOCATE(Stack)					\
+    do									\
+      {									\
+	YYSIZE_T yynewbytes;						\
+	YYCOPY (&yyptr->Stack, Stack, yysize);				\
+	Stack = &yyptr->Stack;						\
+	yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
+	yyptr += yynewbytes / sizeof (*yyptr);				\
+      }									\
+    while (0)
+
+#endif
+
+#if defined (__STDC__) || defined (__cplusplus)
+   typedef signed char yysigned_char;
+#else
+   typedef short int yysigned_char;
+#endif
+
+/* YYFINAL -- State number of the termination state. */
+#define YYFINAL  17
+/* YYLAST -- Last index in YYTABLE.  */
+#define YYLAST   584
+
+/* YYNTOKENS -- Number of terminals. */
+#define YYNTOKENS  42
+/* YYNNTS -- Number of nonterminals. */
+#define YYNNTS  52
+/* YYNRULES -- Number of rules. */
+#define YYNRULES  151
+/* YYNRULES -- Number of states. */
+#define YYNSTATES  354
+
+/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX.  */
+#define YYUNDEFTOK  2
+#define YYMAXUTOK   296
+
+#define YYTRANSLATE(YYX)						\
+  ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
+
+/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX.  */
+static const unsigned char yytranslate[] =
+{
+       0,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     1,     2,     3,     4,
+       5,     6,     7,     8,     9,    10,    11,    12,    13,    14,
+      15,    16,    17,    18,    19,    20,    21,    22,    23,    24,
+      25,    26,    27,    28,    29,    30,    31,    32,    33,    34,
+      35,    36,    37,    38,    39,    40,    41
+};
+
+#if YYDEBUG
+/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
+   YYRHS.  */
+static const unsigned short int yyprhs[] =
+{
+       0,     0,     3,     5,     7,    10,    13,    15,    17,    19,
+      21,    27,    32,    38,    43,    50,    56,    63,    69,    78,
+      86,    94,   101,   106,   110,   112,   115,   118,   119,   125,
+     127,   131,   134,   136,   138,   141,   144,   146,   148,   150,
+     152,   154,   155,   161,   164,   166,   171,   175,   180,   188,
+     197,   199,   202,   205,   206,   212,   213,   219,   234,   245,
+     247,   250,   252,   255,   259,   261,   264,   268,   269,   276,
+     280,   281,   287,   291,   295,   298,   299,   300,   301,   314,
+     315,   322,   325,   329,   333,   336,   339,   340,   346,   349,
+     352,   355,   358,   363,   366,   371,   374,   379,   381,   383,
+     387,   391,   397,   403,   409,   415,   417,   421,   427,   431,
+     437,   441,   442,   448,   452,   453,   457,   461,   464,   466,
+     467,   471,   474,   476,   479,   484,   488,   493,   497,   500,
+     504,   506,   509,   511,   517,   522,   526,   531,   535,   538,
+     542,   545,   548,   563,   574,   578,   594,   606,   609,   611,
+     613,   618
+};
+
+/* YYRHS -- A `-1'-separated list of the rules' RHS. */
+static const yysigned_char yyrhs[] =
+{
+      43,     0,    -1,    44,    -1,    45,    -1,    44,    45,    -1,
+      44,     1,    -1,    46,    -1,    47,    -1,    48,    -1,     8,
+      -1,     3,    41,     4,    53,     5,    -1,     3,    41,     4,
+       5,    -1,     3,    36,     4,    53,     5,    -1,     3,    36,
+       4,     5,    -1,    23,     3,    41,     4,    53,     5,    -1,
+      23,     3,    41,     4,     5,    -1,    23,     3,    36,     4,
+      53,     5,    -1,    23,     3,    36,     4,     5,    -1,    15,
+      41,     6,    52,     7,     4,    86,     5,    -1,    15,    41,
+       6,    52,     7,     4,     5,    -1,    15,    41,     6,     7,
+       4,    86,     5,    -1,    15,    41,     6,     7,     4,     5,
+      -1,    16,     4,    49,     5,    -1,    16,     4,     5,    -1,
+      50,    -1,    49,    50,    -1,    49,     1,    -1,    -1,    41,
+       9,    51,    41,     8,    -1,    41,    -1,    52,    10,    41,
+      -1,    52,     1,    -1,    54,    -1,     1,    -1,    53,    54,
+      -1,    53,     1,    -1,    57,    -1,    93,    -1,    88,    -1,
+      89,    -1,    56,    -1,    -1,    41,     9,    55,    41,     8,
+      -1,    41,     1,    -1,     8,    -1,    17,    24,    41,     8,
+      -1,    41,    24,    69,    -1,    30,    41,    24,    69,    -1,
+      31,     6,    65,     7,    41,    24,    69,    -1,    30,    31,
+       6,    65,     7,    41,    24,    69,    -1,    69,    -1,    58,
+      69,    -1,    58,     1,    -1,    -1,    19,     6,    60,    64,
+       7,    -1,    -1,    22,     6,    62,    64,     7,    -1,    20,
+       6,    65,    11,    65,    11,    65,    13,    65,    13,    65,
+      13,    65,     7,    -1,    20,     6,    41,    13,    65,    13,
+      65,    13,    65,     7,    -1,    41,    -1,    41,    41,    -1,
+      41,    -1,    41,    41,    -1,    41,    41,    41,    -1,    41,
+      -1,    41,    41,    -1,    41,    11,    41,    -1,    -1,    18,
+       6,    68,    41,     7,     4,    -1,     4,    58,     5,    -1,
+      -1,    41,     9,    70,    41,     8,    -1,    25,    76,     8,
+      -1,    26,    77,     8,    -1,    41,    11,    -1,    -1,    -1,
+      -1,    32,     6,    71,    41,     8,    72,    41,     8,    73,
+      41,     7,    69,    -1,    -1,    33,     6,    74,    41,     7,
+      69,    -1,    67,     5,    -1,    67,    84,     5,    -1,    12,
+      78,     8,    -1,    82,     8,    -1,    41,     8,    -1,    -1,
+      82,     9,    75,    41,     8,    -1,    28,     8,    -1,    27,
+       8,    -1,    29,     8,    -1,    61,    69,    -1,    61,    69,
+      21,    69,    -1,    59,    69,    -1,    59,    69,    21,    69,
+      -1,    63,    69,    -1,    63,    69,    21,    69,    -1,     8,
+      -1,    66,    -1,    66,    13,    66,    -1,    66,    10,    66,
+      -1,    66,    13,    66,    13,    66,    -1,    66,    10,    66,
+      10,    66,    -1,    36,    13,    66,    13,    66,    -1,    36,
+      10,    66,    10,    66,    -1,    66,    -1,    66,    10,    66,
+      -1,    66,    10,    41,    14,    41,    -1,    66,    14,    66,
+      -1,    66,    10,    41,    14,    36,    -1,    66,    14,    36,
+      -1,    -1,    41,     6,    79,    83,     7,    -1,    41,     6,
+       7,    -1,    -1,    41,    81,     6,    -1,    80,    83,     7,
+      -1,    80,     7,    -1,    64,    -1,    -1,    83,    10,    41,
+      -1,    83,    10,    -1,    85,    -1,    84,    85,    -1,    34,
+      41,    11,    58,    -1,    36,    11,    58,    -1,    35,    41,
+      11,    58,    -1,    34,    41,    11,    -1,    36,    11,    -1,
+      35,    41,    11,    -1,    87,    -1,    86,    87,    -1,    69,
+      -1,    37,    41,     4,    58,     5,    -1,    38,     4,    90,
+       5,    -1,    38,     4,     5,    -1,    39,     4,    90,     5,
+      -1,    39,     4,     5,    -1,    41,     8,    -1,    90,    41,
+       8,    -1,    90,     1,    -1,    92,     8,    -1,    92,    13,
+      65,    11,    65,    11,    65,    13,    65,    13,    65,    13,
+      65,     8,    -1,    92,    13,    41,    13,    65,    13,    65,
+      13,    65,     8,    -1,    91,    92,     8,    -1,    91,    92,
+      13,    65,    11,    65,    11,    65,    13,    65,    13,    65,
+      13,    65,     8,    -1,    91,    92,    13,    41,    13,    65,
+      13,    65,    13,    65,     8,    -1,    91,     1,    -1,    41,
+      -1,    36,    -1,    40,     4,    91,     5,    -1,    40,     4,
+       5,    -1
+};
+
+/* YYRLINE[YYN] -- source line where rule number YYN was defined.  */
+static const unsigned short int yyrline[] =
+{
+       0,   126,   126,   129,   130,   133,   136,   137,   138,   139,
+     142,   143,   144,   145,   146,   147,   148,   149,   152,   154,
+     155,   156,   159,   160,   163,   164,   165,   168,   168,   171,
+     172,   173,   176,   177,   178,   181,   184,   185,   186,   187,
+     188,   189,   189,   190,   191,   194,   197,   198,   199,   200,
+     204,   205,   208,   211,   211,   214,   214,   217,   236,   255,
+     256,   258,   259,   260,   263,   264,   265,   268,   268,   273,
+     274,   274,   277,   278,   279,   280,   281,   282,   280,   285,
+     285,   288,   289,   290,   291,   292,   294,   294,   327,   328,
+     329,   330,   331,   332,   333,   334,   335,   336,   339,   340,
+     343,   346,   351,   356,   361,   368,   371,   374,   379,   384,
+     389,   396,   396,   399,   402,   402,   411,   417,   420,   421,
+     422,   423,   426,   427,   432,   433,   434,   435,   436,   437,
+     440,   441,   446,   447,   450,   451,   454,   455,   458,   459,
+     460,   463,   464,   485,   498,   499,   519,   532,   535,   536,
+     539,   540
+};
+#endif
+
+#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE
+/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
+   First, the terminals, then, starting at YYNTOKENS, nonterminals. */
+static const char *const yytname[] =
+{
+  "$end", "error", "$undefined", "KW_CONTEXT", "LC", "RC", "LP", "RP",
+  "SEMI", "EQ", "COMMA", "COLON", "AMPER", "BAR", "AT", "KW_MACRO",
+  "KW_GLOBALS", "KW_IGNOREPAT", "KW_SWITCH", "KW_IF", "KW_IFTIME",
+  "KW_ELSE", "KW_RANDOM", "KW_ABSTRACT", "EXTENMARK", "KW_GOTO", "KW_JUMP",
+  "KW_RETURN", "KW_BREAK", "KW_CONTINUE", "KW_REGEXTEN", "KW_HINT",
+  "KW_FOR", "KW_WHILE", "KW_CASE", "KW_PATTERN", "KW_DEFAULT", "KW_CATCH",
+  "KW_SWITCHES", "KW_ESWITCHES", "KW_INCLUDES", "word", "$accept", "file",
+  "objects", "object", "context", "macro", "globals", "global_statements",
+  "global_statement", "@1", "arglist", "elements", "element", "@2",
+  "ignorepat", "extension", "statements", "if_head", "@3", "random_head",
+  "@4", "iftime_head", "word_list", "word3_list", "goto_word",
+  "switch_head", "@5", "statement", "@6", "@7", "@8", "@9", "@10", "@11",
+  "target", "jumptarget", "macro_call", "@12", "application_call_head",
+  "@13", "application_call", "eval_arglist", "case_statements",
+  "case_statement", "macro_statements", "macro_statement", "switches",
+  "eswitches", "switchlist", "includeslist", "includedname", "includes", 0
+};
+#endif
+
+# ifdef YYPRINT
+/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to
+   token YYLEX-NUM.  */
+static const unsigned short int yytoknum[] =
+{
+       0,   256,   257,   258,   259,   260,   261,   262,   263,   264,
+     265,   266,   267,   268,   269,   270,   271,   272,   273,   274,
+     275,   276,   277,   278,   279,   280,   281,   282,   283,   284,
+     285,   286,   287,   288,   289,   290,   291,   292,   293,   294,
+     295,   296
+};
+# endif
+
+/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives.  */
+static const unsigned char yyr1[] =
+{
+       0,    42,    43,    44,    44,    44,    45,    45,    45,    45,
+      46,    46,    46,    46,    46,    46,    46,    46,    47,    47,
+      47,    47,    48,    48,    49,    49,    49,    51,    50,    52,
+      52,    52,    53,    53,    53,    53,    54,    54,    54,    54,
+      54,    55,    54,    54,    54,    56,    57,    57,    57,    57,
+      58,    58,    58,    60,    59,    62,    61,    63,    63,    64,
+      64,    65,    65,    65,    66,    66,    66,    68,    67,    69,
+      70,    69,    69,    69,    69,    71,    72,    73,    69,    74,
+      69,    69,    69,    69,    69,    69,    75,    69,    69,    69,
+      69,    69,    69,    69,    69,    69,    69,    69,    76,    76,
+      76,    76,    76,    76,    76,    77,    77,    77,    77,    77,
+      77,    79,    78,    78,    81,    80,    82,    82,    83,    83,
+      83,    83,    84,    84,    85,    85,    85,    85,    85,    85,
+      86,    86,    87,    87,    88,    88,    89,    89,    90,    90,
+      90,    91,    91,    91,    91,    91,    91,    91,    92,    92,
+      93,    93
+};
+
+/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN.  */
+static const unsigned char yyr2[] =
+{
+       0,     2,     1,     1,     2,     2,     1,     1,     1,     1,
+       5,     4,     5,     4,     6,     5,     6,     5,     8,     7,
+       7,     6,     4,     3,     1,     2,     2,     0,     5,     1,
+       3,     2,     1,     1,     2,     2,     1,     1,     1,     1,
+       1,     0,     5,     2,     1,     4,     3,     4,     7,     8,
+       1,     2,     2,     0,     5,     0,     5,    14,    10,     1,
+       2,     1,     2,     3,     1,     2,     3,     0,     6,     3,
+       0,     5,     3,     3,     2,     0,     0,     0,    12,     0,
+       6,     2,     3,     3,     2,     2,     0,     5,     2,     2,
+       2,     2,     4,     2,     4,     2,     4,     1,     1,     3,
+       3,     5,     5,     5,     5,     1,     3,     5,     3,     5,
+       3,     0,     5,     3,     0,     3,     3,     2,     1,     0,
+       3,     2,     1,     2,     4,     3,     4,     3,     2,     3,
+       1,     2,     1,     5,     4,     3,     4,     3,     2,     3,
+       2,     2,    14,    10,     3,    15,    11,     2,     1,     1,
+       4,     3
+};
+
+/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
+   STATE-NUM when YYTABLE doesn't specify something else to do.  Zero
+   means the default is an error.  */
+static const unsigned char yydefact[] =
+{
+       0,     0,     9,     0,     0,     0,     0,     0,     3,     6,
+       7,     8,     0,     0,     0,     0,     0,     1,     5,     4,
+       0,     0,     0,    23,     0,     0,    24,     0,     0,    33,
+      13,    44,     0,     0,     0,     0,     0,     0,     0,     0,
+      32,    40,    36,    38,    39,    37,    11,     0,     0,    29,
+       0,    27,    26,    22,    25,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,    43,    41,     0,    35,    12,    34,
+      10,     0,    31,     0,     0,     0,    17,     0,    15,     0,
+       0,     0,     0,    61,     0,   135,     0,     0,   137,     0,
+     151,   149,   148,     0,     0,     0,     0,    97,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+     114,     0,     0,     0,     0,    46,   119,     0,    21,     0,
+     132,     0,   130,     0,    30,     0,    16,    14,    45,     0,
+      47,    62,     0,   138,   140,   134,     0,   136,   147,   150,
+       0,   141,     0,     0,     0,    50,     0,     0,    67,    53,
+       0,    55,     0,    64,    98,     0,   105,     0,    89,    88,
+      90,    75,    79,    85,    70,    74,     0,    93,    91,    95,
+      81,     0,     0,     0,     0,   122,   117,    59,   118,     0,
+      84,    86,     0,    20,   131,    19,     0,    28,     0,    63,
+       0,   139,   144,     0,    61,     0,    42,    52,    69,    51,
+     111,    83,     0,     0,    61,     0,     0,     0,     0,     0,
+      65,     0,     0,    72,     0,     0,    73,     0,     0,     0,
+     115,     0,     0,     0,     0,     0,   128,    82,   123,    60,
+     116,   121,     0,     0,    18,     0,     0,    61,     0,     0,
+       0,   113,   119,     0,     0,     0,     0,     0,     0,     0,
+      66,   100,    99,    64,   106,   110,   108,     0,     0,     0,
+      94,    92,    96,   127,   129,     0,   120,     0,     0,     0,
+      48,     0,     0,     0,     0,     0,     0,    54,     0,     0,
+      56,     0,     0,     0,     0,     0,    76,     0,    71,     0,
+       0,    87,   133,    49,     0,     0,     0,     0,   112,    68,
+       0,     0,   104,   103,   102,   101,   109,   107,     0,    80,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,    77,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,   143,     0,    58,     0,     0,   146,     0,
+       0,     0,     0,     0,     0,     0,    78,     0,     0,     0,
+       0,   142,    57,   145
+};
+
+/* YYDEFGOTO[NTERM-NUM]. */
+static const short int yydefgoto[] =
+{
+      -1,     6,     7,     8,     9,    10,    11,    25,    26,    75,
+      50,    39,    40,    95,    41,    42,   144,   111,   203,   112,
+     206,   113,   178,    84,   154,   114,   202,   145,   219,   217,
+     308,   330,   218,   232,   155,   157,   147,   242,   116,   166,
+     117,   179,   174,   175,   121,   122,    43,    44,    87,    93,
+      94,    45
+};
+
+/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
+   STATE-NUM.  */
+#define YYPACT_NINF -215
+static const short int yypact[] =
+{
+     212,   127,  -215,   -35,    55,    23,    85,   561,  -215,  -215,
+    -215,  -215,    64,   118,   112,    13,   128,  -215,  -215,  -215,
+     157,   208,     2,  -215,   123,    19,  -215,   130,   137,  -215,
+    -215,  -215,   143,    43,   169,   181,   182,   189,   126,   284,
+    -215,  -215,  -215,  -215,  -215,  -215,  -215,   337,   196,  -215,
+     141,  -215,  -215,  -215,  -215,   342,   357,   135,   188,   177,
+     170,    22,    36,    29,  -215,  -215,   527,  -215,  -215,  -215,
+    -215,   423,  -215,   206,   191,   195,  -215,   384,  -215,   399,
+     210,   170,   527,   200,   215,  -215,   242,    51,  -215,    57,
+    -215,  -215,  -215,    12,   158,   220,   527,  -215,   223,   245,
+     250,   259,   262,   148,   229,   263,   265,   266,   269,   275,
+     251,   527,   527,   527,   156,  -215,    26,   145,  -215,   243,
+    -215,   449,  -215,   475,  -215,   279,  -215,  -215,  -215,   281,
+    -215,   252,   253,  -215,  -215,  -215,   283,  -215,  -215,  -215,
+     204,  -215,   254,   291,   278,  -215,   296,   300,  -215,  -215,
+     276,  -215,    69,    40,    95,   310,   114,   313,  -215,  -215,
+    -215,  -215,  -215,  -215,  -215,  -215,   323,   311,   318,   325,
+    -215,   290,   303,   340,   172,  -215,  -215,   307,  -215,   230,
+    -215,  -215,   348,  -215,  -215,  -215,   501,  -215,   312,  -215,
+     331,  -215,  -215,   315,    58,   346,  -215,  -215,  -215,  -215,
+     353,  -215,   320,   322,    76,   355,   322,   229,   229,   328,
+    -215,   229,   229,  -215,   329,   178,  -215,   330,   338,   343,
+    -215,   527,   527,   527,   375,   379,   527,  -215,  -215,  -215,
+    -215,   350,   352,   527,  -215,   370,   527,   108,   388,   170,
+     170,  -215,   322,   395,   396,   170,   170,   398,   354,   393,
+    -215,   400,   404,    50,  -215,  -215,  -215,   401,   405,   403,
+    -215,  -215,  -215,   527,   527,     3,  -215,   410,   308,   527,
+    -215,   170,   170,   406,   397,   235,   409,  -215,   407,   415,
+    -215,   229,   229,   229,   229,   190,  -215,   527,  -215,    68,
+     111,  -215,  -215,  -215,   408,   421,   170,   170,  -215,  -215,
+     170,   170,  -215,  -215,  -215,  -215,  -215,  -215,   392,  -215,
+     170,   170,   431,   433,   434,   445,   426,   446,   450,   170,
+     170,   170,   170,  -215,   170,   170,   428,   452,   455,   453,
+     429,   464,   460,  -215,   170,  -215,   170,   477,  -215,   170,
+     472,   476,   527,   478,   170,   170,  -215,   170,   480,   485,
+     488,  -215,  -215,  -215
+};
+
+/* YYPGOTO[NTERM-NUM].  */
+static const short int yypgoto[] =
+{
+    -215,  -215,  -215,   491,  -215,  -215,  -215,  -215,   474,  -215,
+    -215,   104,   -37,  -215,  -215,  -215,  -214,  -215,  -215,  -215,
+    -215,  -215,    60,   -67,  -101,  -215,  -215,   -66,  -215,  -215,
+    -215,  -215,  -215,  -215,  -215,  -215,  -215,  -215,  -215,  -215,
+    -215,   268,  -215,   341,   391,  -120,  -215,  -215,   456,  -215,
+     418,  -215
+};
+
+/* YYTABLE[YYPACT[STATE-NUM]].  What to do in state STATE-NUM.  If
+   positive, shift that token.  If negative, reduce the rule which
+   number is the opposite.  If zero, do what YYDEFACT says.
+   If YYTABLE_NINF, syntax error.  */
+#define YYTABLE_NINF -127
+static const short int yytable[] =
+{
+     115,   184,    69,   156,   197,   120,    14,    96,  -125,    48,
+      69,    97,   265,   138,   129,    98,   130,   139,    23,   268,
+      52,    99,   100,   101,    53,   102,    16,    85,   103,   104,
+     105,   106,   107,   176,    90,   108,   109,  -125,  -125,  -125,
+      69,    88,    69,    49,   110,   167,   168,   169,    91,   289,
+     290,   209,   134,    92,    24,   120,   135,   120,   134,    15,
+      24,   209,   137,    86,   285,    91,   184,   177,    20,   197,
+      92,   239,    96,  -124,    58,   195,    97,    86,   199,   207,
+      98,   210,   208,   205,    59,    17,    99,   100,   101,   245,
+     102,   210,   136,   103,   104,   105,   106,   107,   136,   131,
+     108,   109,  -124,  -124,  -124,   211,   248,   249,   212,   110,
+     251,   252,   197,   254,   256,    96,  -126,   131,    22,    97,
+     120,   271,    21,    98,   214,    47,   238,    64,   215,    99,
+     100,   101,    51,   102,    55,    65,   103,   104,   105,   106,
+     107,    56,    72,   108,   109,  -126,  -126,  -126,    73,   131,
+      66,    74,   110,   180,   181,   260,   261,   262,    29,    77,
+      79,   170,    30,    12,    27,    31,   141,    57,    13,    28,
+     270,   142,   273,   274,    32,    60,    80,   227,   278,   279,
+     302,   303,   304,   305,   152,    61,    62,    33,    34,   153,
+     171,   172,   173,    63,    81,    35,    36,    37,    38,   199,
+      71,    82,   199,   293,   294,   295,   171,   172,   173,    29,
+     123,    83,   192,    46,   255,     1,    31,   193,   128,   153,
+       2,   309,   132,   199,   199,    32,   306,     3,     4,   312,
+     313,   307,   124,   314,   315,     5,   125,   230,    33,    34,
+     231,   131,   298,   317,   318,   231,    35,    36,    37,    38,
+     133,   148,   326,   327,   328,   329,   149,   331,   332,   163,
+     164,   143,   165,   244,   146,   150,   247,   340,   151,   341,
+     153,   158,   343,   159,   160,   161,   346,   348,   349,   197,
+     350,   162,    96,   198,   182,    67,    97,   187,   188,    68,
+      98,   191,    31,   189,   190,   194,    99,   100,   101,   196,
+     102,    32,   200,   103,   104,   105,   106,   107,   201,   197,
+     108,   109,    96,   292,    33,    34,    97,   204,   213,   110,
+      98,   216,    35,    36,    37,    38,    99,   100,   101,   220,
+     102,   224,   221,   103,   104,   105,   106,   107,    67,   222,
+     108,   109,    70,    29,   225,    31,   223,    76,   229,   110,
+      31,   226,   233,   235,    32,   236,   237,   240,    29,    32,
+     241,   243,    78,   177,   281,    31,   246,    33,    34,   250,
+     253,   257,    33,    34,    32,    35,    36,    37,    38,   258,
+      35,    36,    37,    38,   259,    67,   263,    33,    34,   126,
+     264,   266,    31,   267,   269,    35,    36,    37,    38,   272,
+      67,    32,   276,   277,   127,   280,   282,    31,   297,   286,
+     283,   288,   287,   299,    33,    34,    32,   284,   291,   296,
+     300,   310,    35,    36,    37,    38,   301,    96,   118,    33,
+      34,    97,   311,   316,   323,    98,   333,    35,    36,    37,
+      38,    99,   100,   101,   319,   102,   320,   321,   103,   104,
+     105,   106,   107,    96,   183,   108,   109,    97,   322,   324,
+     119,    98,   335,   325,   110,   334,   336,    99,   100,   101,
+     337,   102,   338,   339,   103,   104,   105,   106,   107,    96,
+     185,   108,   109,    97,   342,   344,   119,    98,   351,   345,
+     110,   347,   352,    99,   100,   101,   353,   102,    19,    54,
+     103,   104,   105,   106,   107,    96,   234,   108,   109,    97,
+     275,   140,   119,    98,   186,   228,   110,     0,    89,    99,
+     100,   101,     0,   102,     0,     0,   103,   104,   105,   106,
+     107,    96,     0,   108,   109,    97,     0,     0,   119,    98,
+       0,     0,   110,     0,     0,    99,   100,   101,     0,   102,
+       0,     0,   103,   104,   105,   106,   107,     0,     0,   108,
+     109,    -2,    18,     0,     1,     0,     0,     0,   110,     2,
+       0,     0,     0,     0,     0,     0,     3,     4,     0,     0,
+       0,     0,     0,     0,     5
+};
+
+static const short int yycheck[] =
+{
+      66,   121,    39,   104,     1,    71,    41,     4,     5,     7,
+      47,     8,   226,     1,    81,    12,    82,     5,     5,   233,
+       1,    18,    19,    20,     5,    22,     3,     5,    25,    26,
+      27,    28,    29,     7,     5,    32,    33,    34,    35,    36,
+      77,     5,    79,    41,    41,   111,   112,   113,    36,   263,
+     264,    11,     1,    41,    41,   121,     5,   123,     1,     4,
+      41,    11,     5,    41,    14,    36,   186,    41,     4,     1,
+      41,    13,     4,     5,    31,   142,     8,    41,   144,    10,
+      12,    41,    13,   150,    41,     0,    18,    19,    20,    13,
+      22,    41,    41,    25,    26,    27,    28,    29,    41,    41,
+      32,    33,    34,    35,    36,    10,   207,   208,    13,    41,
+     211,   212,     1,   214,   215,     4,     5,    41,     6,     8,
+     186,    13,     4,    12,    10,    21,   193,     1,    14,    18,
+      19,    20,     9,    22,     4,     9,    25,    26,    27,    28,
+      29,     4,     1,    32,    33,    34,    35,    36,     7,    41,
+      24,    10,    41,     8,     9,   221,   222,   223,     1,    55,
+      56,     5,     5,    36,    36,     8,     8,    24,    41,    41,
+     236,    13,   239,   240,    17,     6,    41,     5,   245,   246,
+     281,   282,   283,   284,    36,     4,     4,    30,    31,    41,
+      34,    35,    36,     4,     6,    38,    39,    40,    41,   265,
+       4,    24,   268,   269,   271,   272,    34,    35,    36,     1,
+       4,    41,     8,     5,    36,     3,     8,    13,     8,    41,
+       8,   287,     7,   289,   290,    17,    36,    15,    16,   296,
+     297,    41,    41,   300,   301,    23,    41,     7,    30,    31,
+      10,    41,     7,   310,   311,    10,    38,    39,    40,    41,
+       8,     6,   319,   320,   321,   322,     6,   324,   325,     8,
+       9,    41,    11,   203,    41,     6,   206,   334,     6,   336,
+      41,     8,   339,     8,     8,     6,   342,   344,   345,     1,
+     347,     6,     4,     5,    41,     1,     8,     8,     7,     5,
+      12,     8,     8,    41,    41,    41,    18,    19,    20,     8,
+      22,    17,     6,    25,    26,    27,    28,    29,     8,     1,
+      32,    33,     4,     5,    30,    31,     8,    41,     8,    41,
+      12,     8,    38,    39,    40,    41,    18,    19,    20,     6,
+      22,    41,    21,    25,    26,    27,    28,    29,     1,    21,
+      32,    33,     5,     1,    41,     8,    21,     5,    41,    41,
+       8,    11,     4,    41,    17,    24,    41,    11,     1,    17,
+       7,    41,     5,    41,    10,     8,    11,    30,    31,    41,
+      41,    41,    30,    31,    17,    38,    39,    40,    41,    41,
+      38,    39,    40,    41,    41,     1,    11,    30,    31,     5,
+      11,    41,     8,    41,    24,    38,    39,    40,    41,    11,
+       1,    17,     7,     7,     5,     7,    13,     8,    11,     8,
+      10,     8,     7,     4,    30,    31,    17,    13,     8,    13,
+      13,    13,    38,    39,    40,    41,    11,     4,     5,    30,
+      31,     8,    11,    41,     8,    12,     8,    38,    39,    40,
+      41,    18,    19,    20,    13,    22,    13,    13,    25,    26,
+      27,    28,    29,     4,     5,    32,    33,     8,    13,    13,
+      37,    12,     7,    13,    41,    13,    13,    18,    19,    20,
+      41,    22,     8,    13,    25,    26,    27,    28,    29,     4,
+       5,    32,    33,     8,     7,    13,    37,    12,     8,    13,
+      41,    13,     7,    18,    19,    20,     8,    22,     7,    25,
+      25,    26,    27,    28,    29,     4,     5,    32,    33,     8,
+     242,    93,    37,    12,   123,   174,    41,    -1,    62,    18,
+      19,    20,    -1,    22,    -1,    -1,    25,    26,    27,    28,
+      29,     4,    -1,    32,    33,     8,    -1,    -1,    37,    12,
+      -1,    -1,    41,    -1,    -1,    18,    19,    20,    -1,    22,
+      -1,    -1,    25,    26,    27,    28,    29,    -1,    -1,    32,
+      33,     0,     1,    -1,     3,    -1,    -1,    -1,    41,     8,
+      -1,    -1,    -1,    -1,    -1,    -1,    15,    16,    -1,    -1,
+      -1,    -1,    -1,    -1,    23
+};
+
+/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
+   symbol of state STATE-NUM.  */
+static const unsigned char yystos[] =
+{
+       0,     3,     8,    15,    16,    23,    43,    44,    45,    46,
+      47,    48,    36,    41,    41,     4,     3,     0,     1,    45,
+       4,     4,     6,     5,    41,    49,    50,    36,    41,     1,
+       5,     8,    17,    30,    31,    38,    39,    40,    41,    53,
+      54,    56,    57,    88,    89,    93,     5,    53,     7,    41,
+      52,     9,     1,     5,    50,     4,     4,    24,    31,    41,
+       6,     4,     4,     4,     1,     9,    24,     1,     5,    54,
+       5,     4,     1,     7,    10,    51,     5,    53,     5,    53,
+      41,     6,    24,    41,    65,     5,    41,    90,     5,    90,
+       5,    36,    41,    91,    92,    55,     4,     8,    12,    18,
+      19,    20,    22,    25,    26,    27,    28,    29,    32,    33,
+      41,    59,    61,    63,    67,    69,    80,    82,     5,    37,
+      69,    86,    87,     4,    41,    41,     5,     5,     8,    65,
+      69,    41,     7,     8,     1,     5,    41,     5,     1,     5,
+      92,     8,    13,    41,    58,    69,    41,    78,     6,     6,
+       6,     6,    36,    41,    66,    76,    66,    77,     8,     8,
+       8,     6,     6,     8,     9,    11,    81,    69,    69,    69,
+       5,    34,    35,    36,    84,    85,     7,    41,    64,    83,
+       8,     9,    41,     5,    87,     5,    86,     8,     7,    41,
+      41,     8,     8,    13,    41,    65,     8,     1,     5,    69,
+       6,     8,    68,    60,    41,    65,    62,    10,    13,    11,
+      41,    10,    13,     8,    10,    14,     8,    71,    74,    70,
+       6,    21,    21,    21,    41,    41,    11,     5,    85,    41,
+       7,    10,    75,     4,     5,    41,    24,    41,    65,    13,
+      11,     7,    79,    41,    64,    13,    11,    64,    66,    66,
+      41,    66,    66,    41,    66,    36,    66,    41,    41,    41,
+      69,    69,    69,    11,    11,    58,    41,    41,    58,    24,
+      69,    13,    11,    65,    65,    83,     7,     7,    65,    65,
+       7,    10,    13,    10,    13,    14,     8,     7,     8,    58,
+      58,     8,     5,    69,    65,    65,    13,    11,     7,     4,
+      13,    11,    66,    66,    66,    66,    36,    41,    72,    69,
+      13,    11,    65,    65,    65,    65,    41,    65,    65,    13,
+      13,    13,    13,     8,    13,    13,    65,    65,    65,    65,
+      73,    65,    65,     8,    13,     7,    13,    41,     8,    13,
+      65,    65,     7,    65,    13,    13,    69,    13,    65,    65,
+      65,     8,     7,     8
+};
+
+#define yyerrok		(yyerrstatus = 0)
+#define yyclearin	(yychar = YYEMPTY)
+#define YYEMPTY		(-2)
+#define YYEOF		0
+
+#define YYACCEPT	goto yyacceptlab
+#define YYABORT		goto yyabortlab
+#define YYERROR		goto yyerrorlab
+
+
+/* Like YYERROR except do call yyerror.  This remains here temporarily
+   to ease the transition to the new meaning of YYERROR, for GCC.
+   Once GCC version 2 has supplanted version 1, this can go.  */
+
+#define YYFAIL		goto yyerrlab
+
+#define YYRECOVERING()  (!!yyerrstatus)
+
+#define YYBACKUP(Token, Value)					\
+do								\
+  if (yychar == YYEMPTY && yylen == 1)				\
+    {								\
+      yychar = (Token);						\
+      yylval = (Value);						\
+      yytoken = YYTRANSLATE (yychar);				\
+      YYPOPSTACK;						\
+      goto yybackup;						\
+    }								\
+  else								\
+    {								\
+      yyerror (&yylloc, parseio, YY_("syntax error: cannot back up")); \
+      YYERROR;							\
+    }								\
+while (0)
+
+
+#define YYTERROR	1
+#define YYERRCODE	256
+
+
+/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N].
+   If N is 0, then set CURRENT to the empty location which ends
+   the previous symbol: RHS[0] (always defined).  */
+
+#define YYRHSLOC(Rhs, K) ((Rhs)[K])
+#ifndef YYLLOC_DEFAULT
+# define YYLLOC_DEFAULT(Current, Rhs, N)				\
+    do									\
+      if (N)								\
+	{								\
+	  (Current).first_line   = YYRHSLOC (Rhs, 1).first_line;	\
+	  (Current).first_column = YYRHSLOC (Rhs, 1).first_column;	\
+	  (Current).last_line    = YYRHSLOC (Rhs, N).last_line;		\
+	  (Current).last_column  = YYRHSLOC (Rhs, N).last_column;	\
+	}								\
+      else								\
+	{								\
+	  (Current).first_line   = (Current).last_line   =		\
+	    YYRHSLOC (Rhs, 0).last_line;				\
+	  (Current).first_column = (Current).last_column =		\
+	    YYRHSLOC (Rhs, 0).last_column;				\
+	}								\
+    while (0)
+#endif
+
+
+/* YY_LOCATION_PRINT -- Print the location on the stream.
+   This macro was not mandated originally: define only if we know
+   we won't break user code: when these are the locations we know.  */
+
+#ifndef YY_LOCATION_PRINT
+# if YYLTYPE_IS_TRIVIAL
+#  define YY_LOCATION_PRINT(File, Loc)			\
+     fprintf (File, "%d.%d-%d.%d",			\
+              (Loc).first_line, (Loc).first_column,	\
+              (Loc).last_line,  (Loc).last_column)
+# else
+#  define YY_LOCATION_PRINT(File, Loc) ((void) 0)
+# endif
+#endif
+
+
+/* YYLEX -- calling `yylex' with the right arguments.  */
+
+#ifdef YYLEX_PARAM
+# define YYLEX yylex (&yylval, &yylloc, YYLEX_PARAM)
+#else
+# define YYLEX yylex (&yylval, &yylloc)
+#endif
+
+/* Enable debugging if requested.  */
+#if YYDEBUG
+
+# ifndef YYFPRINTF
+#  include <stdio.h> /* INFRINGES ON USER NAME SPACE */
+#  define YYFPRINTF fprintf
+# endif
+
+# define YYDPRINTF(Args)			\
+do {						\
+  if (yydebug)					\
+    YYFPRINTF Args;				\
+} while (0)
+
+# define YY_SYMBOL_PRINT(Title, Type, Value, Location)		\
+do {								\
+  if (yydebug)							\
+    {								\
+      YYFPRINTF (stderr, "%s ", Title);				\
+      yysymprint (stderr,					\
+                  Type, Value, Location);	\
+      YYFPRINTF (stderr, "\n");					\
+    }								\
+} while (0)
+
+/*------------------------------------------------------------------.
+| yy_stack_print -- Print the state stack from its BOTTOM up to its |
+| TOP (included).                                                   |
+`------------------------------------------------------------------*/
+
+#if defined (__STDC__) || defined (__cplusplus)
+static void
+yy_stack_print (short int *bottom, short int *top)
+#else
+static void
+yy_stack_print (bottom, top)
+    short int *bottom;
+    short int *top;
+#endif
+{
+  YYFPRINTF (stderr, "Stack now");
+  for (/* Nothing. */; bottom <= top; ++bottom)
+    YYFPRINTF (stderr, " %d", *bottom);
+  YYFPRINTF (stderr, "\n");
+}
+
+# define YY_STACK_PRINT(Bottom, Top)				\
+do {								\
+  if (yydebug)							\
+    yy_stack_print ((Bottom), (Top));				\
+} while (0)
+
+
+/*------------------------------------------------.
+| Report that the YYRULE is going to be reduced.  |
+`------------------------------------------------*/
+
+#if defined (__STDC__) || defined (__cplusplus)
+static void
+yy_reduce_print (int yyrule)
+#else
+static void
+yy_reduce_print (yyrule)
+    int yyrule;
+#endif
+{
+  int yyi;
+  unsigned long int yylno = yyrline[yyrule];
+  YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu), ",
+             yyrule - 1, yylno);
+  /* Print the symbols being reduced, and their result.  */
+  for (yyi = yyprhs[yyrule]; 0 <= yyrhs[yyi]; yyi++)
+    YYFPRINTF (stderr, "%s ", yytname[yyrhs[yyi]]);
+  YYFPRINTF (stderr, "-> %s\n", yytname[yyr1[yyrule]]);
+}
+
+# define YY_REDUCE_PRINT(Rule)		\
+do {					\
+  if (yydebug)				\
+    yy_reduce_print (Rule);		\
+} while (0)
+
+/* Nonzero means print parse trace.  It is left uninitialized so that
+   multiple parsers can coexist.  */
+int yydebug;
+#else /* !YYDEBUG */
+# define YYDPRINTF(Args)
+# define YY_SYMBOL_PRINT(Title, Type, Value, Location)
+# define YY_STACK_PRINT(Bottom, Top)
+# define YY_REDUCE_PRINT(Rule)
+#endif /* !YYDEBUG */
+
+
+/* YYINITDEPTH -- initial size of the parser's stacks.  */
+#ifndef	YYINITDEPTH
+# define YYINITDEPTH 200
+#endif
+
+/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only
+   if the built-in stack extension method is used).
+
+   Do not make this value too large; the results are undefined if
+   YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH)
+   evaluated with infinite-precision integer arithmetic.  */
+
+#ifndef YYMAXDEPTH
+# define YYMAXDEPTH 10000
+#endif
+
+
+
+#if YYERROR_VERBOSE
+
+# ifndef yystrlen
+#  if defined (__GLIBC__) && defined (_STRING_H)
+#   define yystrlen strlen
+#  else
+/* Return the length of YYSTR.  */
+static YYSIZE_T
+#   if defined (__STDC__) || defined (__cplusplus)
+yystrlen (const char *yystr)
+#   else
+yystrlen (yystr)
+     const char *yystr;
+#   endif
+{
+  const char *yys = yystr;
+
+  while (*yys++ != '\0')
+    continue;
+
+  return yys - yystr - 1;
+}
+#  endif
+# endif
+
+# ifndef yystpcpy
+#  if defined (__GLIBC__) && defined (_STRING_H) && defined (_GNU_SOURCE)
+#   define yystpcpy stpcpy
+#  else
+/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in
+   YYDEST.  */
+static char *
+#   if defined (__STDC__) || defined (__cplusplus)
+yystpcpy (char *yydest, const char *yysrc)
+#   else
+yystpcpy (yydest, yysrc)
+     char *yydest;
+     const char *yysrc;
+#   endif
+{
+  char *yyd = yydest;
+  const char *yys = yysrc;
+
+  while ((*yyd++ = *yys++) != '\0')
+    continue;
+
+  return yyd - 1;
+}
+#  endif
+# endif
+
+# ifndef yytnamerr
+/* Copy to YYRES the contents of YYSTR after stripping away unnecessary
+   quotes and backslashes, so that it's suitable for yyerror.  The
+   heuristic is that double-quoting is unnecessary unless the string
+   contains an apostrophe, a comma, or backslash (other than
+   backslash-backslash).  YYSTR is taken from yytname.  If YYRES is
+   null, do not copy; instead, return the length of what the result
+   would have been.  */
+static YYSIZE_T
+yytnamerr (char *yyres, const char *yystr)
+{
+  if (*yystr == '"')
+    {
+      size_t yyn = 0;
+      char const *yyp = yystr;
+
+      for (;;)
+	switch (*++yyp)
+	  {
+	  case '\'':
+	  case ',':
+	    goto do_not_strip_quotes;
+
+	  case '\\':
+	    if (*++yyp != '\\')
+	      goto do_not_strip_quotes;
+	    /* Fall through.  */
+	  default:
+	    if (yyres)
+	      yyres[yyn] = *yyp;
+	    yyn++;
+	    break;
+
+	  case '"':
+	    if (yyres)
+	      yyres[yyn] = '\0';
+	    return yyn;
+	  }
+    do_not_strip_quotes: ;
+    }
+
+  if (! yyres)
+    return yystrlen (yystr);
+
+  return yystpcpy (yyres, yystr) - yyres;
+}
+# endif
+
+#endif /* YYERROR_VERBOSE */
+
+
+
+#if YYDEBUG
+/*--------------------------------.
+| Print this symbol on YYOUTPUT.  |
+`--------------------------------*/
+
+#if defined (__STDC__) || defined (__cplusplus)
+static void
+yysymprint (FILE *yyoutput, int yytype, YYSTYPE *yyvaluep, YYLTYPE *yylocationp)
+#else
+static void
+yysymprint (yyoutput, yytype, yyvaluep, yylocationp)
+    FILE *yyoutput;
+    int yytype;
+    YYSTYPE *yyvaluep;
+    YYLTYPE *yylocationp;
+#endif
+{
+  /* Pacify ``unused variable'' warnings.  */
+  (void) yyvaluep;
+  (void) yylocationp;
+
+  if (yytype < YYNTOKENS)
+    YYFPRINTF (yyoutput, "token %s (", yytname[yytype]);
+  else
+    YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]);
+
+  YY_LOCATION_PRINT (yyoutput, *yylocationp);
+  YYFPRINTF (yyoutput, ": ");
+
+# ifdef YYPRINT
+  if (yytype < YYNTOKENS)
+    YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
+# endif
+  switch (yytype)
+    {
+      default:
+        break;
+    }
+  YYFPRINTF (yyoutput, ")");
+}
+
+#endif /* ! YYDEBUG */
+/*-----------------------------------------------.
+| Release the memory associated to this symbol.  |
+`-----------------------------------------------*/
+
+#if defined (__STDC__) || defined (__cplusplus)
+static void
+yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep, YYLTYPE *yylocationp)
+#else
+static void
+yydestruct (yymsg, yytype, yyvaluep, yylocationp)
+    const char *yymsg;
+    int yytype;
+    YYSTYPE *yyvaluep;
+    YYLTYPE *yylocationp;
+#endif
+{
+  /* Pacify ``unused variable'' warnings.  */
+  (void) yyvaluep;
+  (void) yylocationp;
+
+  if (!yymsg)
+    yymsg = "Deleting";
+  YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp);
+
+  switch (yytype)
+    {
+      case 41: /* "word" */
+#line 121 "ael.y"
+        { free((yyvaluep->str));};
+#line 1309 "ael.tab.c"
+        break;
+      case 44: /* "objects" */
+#line 118 "ael.y"
+        { if (yymsg[0] != 'C') {destroy_pval((yyvaluep->pval)); prev_word=0;} else {printf("Cleanup destructor called for pvals\n");} };
+#line 1314 "ael.tab.c"
+        break;
+      case 45: /* "object" */
+#line 118 "ael.y"
+        { if (yymsg[0] != 'C') {destroy_pval((yyvaluep->pval)); prev_word=0;} else {printf("Cleanup destructor called for pvals\n");} };
+#line 1319 "ael.tab.c"
+        break;
+      case 46: /* "context" */
+#line 118 "ael.y"
+        { if (yymsg[0] != 'C') {destroy_pval((yyvaluep->pval)); prev_word=0;} else {printf("Cleanup destructor called for pvals\n");} };
+#line 1324 "ael.tab.c"
+        break;
+      case 47: /* "macro" */
+#line 118 "ael.y"
+        { if (yymsg[0] != 'C') {destroy_pval((yyvaluep->pval)); prev_word=0;} else {printf("Cleanup destructor called for pvals\n");} };
+#line 1329 "ael.tab.c"
+        break;
+      case 48: /* "globals" */
+#line 118 "ael.y"
+        { if (yymsg[0] != 'C') {destroy_pval((yyvaluep->pval)); prev_word=0;} else {printf("Cleanup destructor called for pvals\n");} };
+#line 1334 "ael.tab.c"
+        break;
+      case 49: /* "global_statements" */
+#line 118 "ael.y"
+        { if (yymsg[0] != 'C') {destroy_pval((yyvaluep->pval)); prev_word=0;} else {printf("Cleanup destructor called for pvals\n");} };
+#line 1339 "ael.tab.c"
+        break;
+      case 50: /* "global_statement" */
+#line 118 "ael.y"
+        { if (yymsg[0] != 'C') {destroy_pval((yyvaluep->pval)); prev_word=0;} else {printf("Cleanup destructor called for pvals\n");} };
+#line 1344 "ael.tab.c"
+        break;
+      case 52: /* "arglist" */
+#line 118 "ael.y"
+        { if (yymsg[0] != 'C') {destroy_pval((yyvaluep->pval)); prev_word=0;} else {printf("Cleanup destructor called for pvals\n");} };
+#line 1349 "ael.tab.c"
+        break;
+      case 53: /* "elements" */
+#line 118 "ael.y"
+        { if (yymsg[0] != 'C') {destroy_pval((yyvaluep->pval)); prev_word=0;} else {printf("Cleanup destructor called for pvals\n");} };
+#line 1354 "ael.tab.c"
+        break;
+      case 54: /* "element" */
+#line 118 "ael.y"
+        { if (yymsg[0] != 'C') {destroy_pval((yyvaluep->pval)); prev_word=0;} else {printf("Cleanup destructor called for pvals\n");} };
+#line 1359 "ael.tab.c"
+        break;
+      case 56: /* "ignorepat" */
+#line 118 "ael.y"
+        { if (yymsg[0] != 'C') {destroy_pval((yyvaluep->pval)); prev_word=0;} else {printf("Cleanup destructor called for pvals\n");} };
+#line 1364 "ael.tab.c"
+        break;
+      case 57: /* "extension" */
+#line 118 "ael.y"
+        { if (yymsg[0] != 'C') {destroy_pval((yyvaluep->pval)); prev_word=0;} else {printf("Cleanup destructor called for pvals\n");} };
+#line 1369 "ael.tab.c"
+        break;
+      case 58: /* "statements" */
+#line 118 "ael.y"
+        { if (yymsg[0] != 'C') {destroy_pval((yyvaluep->pval)); prev_word=0;} else {printf("Cleanup destructor called for pvals\n");} };
+#line 1374 "ael.tab.c"
+        break;
+      case 59: /* "if_head" */
+#line 118 "ael.y"
+        { if (yymsg[0] != 'C') {destroy_pval((yyvaluep->pval)); prev_word=0;} else {printf("Cleanup destructor called for pvals\n");} };
+#line 1379 "ael.tab.c"
+        break;
+      case 61: /* "random_head" */
+#line 118 "ael.y"
+        { if (yymsg[0] != 'C') {destroy_pval((yyvaluep->pval)); prev_word=0;} else {printf("Cleanup destructor called for pvals\n");} };
+#line 1384 "ael.tab.c"
+        break;
+      case 63: /* "iftime_head" */
+#line 118 "ael.y"
+        { if (yymsg[0] != 'C') {destroy_pval((yyvaluep->pval)); prev_word=0;} else {printf("Cleanup destructor called for pvals\n");} };
+#line 1389 "ael.tab.c"
+        break;
+      case 64: /* "word_list" */
+#line 121 "ael.y"
+        { free((yyvaluep->str));};
+#line 1394 "ael.tab.c"
+        break;
+      case 65: /* "word3_list" */
+#line 121 "ael.y"
+        { free((yyvaluep->str));};
+#line 1399 "ael.tab.c"
+        break;
+      case 66: /* "goto_word" */
+#line 121 "ael.y"
+        { free((yyvaluep->str));};
+#line 1404 "ael.tab.c"
+        break;
+      case 67: /* "switch_head" */
+#line 118 "ael.y"
+        { if (yymsg[0] != 'C') {destroy_pval((yyvaluep->pval)); prev_word=0;} else {printf("Cleanup destructor called for pvals\n");} };
+#line 1409 "ael.tab.c"
+        break;
+      case 69: /* "statement" */
+#line 118 "ael.y"
+        { if (yymsg[0] != 'C') {destroy_pval((yyvaluep->pval)); prev_word=0;} else {printf("Cleanup destructor called for pvals\n");} };
+#line 1414 "ael.tab.c"
+        break;
+      case 76: /* "target" */
+#line 118 "ael.y"
+        { if (yymsg[0] != 'C') {destroy_pval((yyvaluep->pval)); prev_word=0;} else {printf("Cleanup destructor called for pvals\n");} };
+#line 1419 "ael.tab.c"
+        break;
+      case 77: /* "jumptarget" */
+#line 118 "ael.y"
+        { if (yymsg[0] != 'C') {destroy_pval((yyvaluep->pval)); prev_word=0;} else {printf("Cleanup destructor called for pvals\n");} };
+#line 1424 "ael.tab.c"
+        break;
+      case 78: /* "macro_call" */
+#line 118 "ael.y"
+        { if (yymsg[0] != 'C') {destroy_pval((yyvaluep->pval)); prev_word=0;} else {printf("Cleanup destructor called for pvals\n");} };
+#line 1429 "ael.tab.c"
+        break;
+      case 80: /* "application_call_head" */
+#line 118 "ael.y"
+        { if (yymsg[0] != 'C') {destroy_pval((yyvaluep->pval)); prev_word=0;} else {printf("Cleanup destructor called for pvals\n");} };
+#line 1434 "ael.tab.c"
+        break;
+      case 82: /* "application_call" */
+#line 118 "ael.y"
+        { if (yymsg[0] != 'C') {destroy_pval((yyvaluep->pval)); prev_word=0;} else {printf("Cleanup destructor called for pvals\n");} };
+#line 1439 "ael.tab.c"
+        break;
+      case 83: /* "eval_arglist" */
+#line 118 "ael.y"
+        { if (yymsg[0] != 'C') {destroy_pval((yyvaluep->pval)); prev_word=0;} else {printf("Cleanup destructor called for pvals\n");} };
+#line 1444 "ael.tab.c"
+        break;
+      case 84: /* "case_statements" */
+#line 118 "ael.y"
+        { if (yymsg[0] != 'C') {destroy_pval((yyvaluep->pval)); prev_word=0;} else {printf("Cleanup destructor called for pvals\n");} };
+#line 1449 "ael.tab.c"
+        break;
+      case 85: /* "case_statement" */
+#line 118 "ael.y"
+        { if (yymsg[0] != 'C') {destroy_pval((yyvaluep->pval)); prev_word=0;} else {printf("Cleanup destructor called for pvals\n");} };
+#line 1454 "ael.tab.c"
+        break;
+      case 86: /* "macro_statements" */
+#line 118 "ael.y"
+        { if (yymsg[0] != 'C') {destroy_pval((yyvaluep->pval)); prev_word=0;} else {printf("Cleanup destructor called for pvals\n");} };
+#line 1459 "ael.tab.c"
+        break;
+      case 87: /* "macro_statement" */
+#line 118 "ael.y"
+        { if (yymsg[0] != 'C') {destroy_pval((yyvaluep->pval)); prev_word=0;} else {printf("Cleanup destructor called for pvals\n");} };
+#line 1464 "ael.tab.c"
+        break;
+      case 88: /* "switches" */
+#line 118 "ael.y"
+        { if (yymsg[0] != 'C') {destroy_pval((yyvaluep->pval)); prev_word=0;} else {printf("Cleanup destructor called for pvals\n");} };
+#line 1469 "ael.tab.c"
+        break;
+      case 89: /* "eswitches" */
+#line 118 "ael.y"
+        { if (yymsg[0] != 'C') {destroy_pval((yyvaluep->pval)); prev_word=0;} else {printf("Cleanup destructor called for pvals\n");} };
+#line 1474 "ael.tab.c"
+        break;
+      case 90: /* "switchlist" */
+#line 118 "ael.y"
+        { if (yymsg[0] != 'C') {destroy_pval((yyvaluep->pval)); prev_word=0;} else {printf("Cleanup destructor called for pvals\n");} };
+#line 1479 "ael.tab.c"
+        break;
+      case 91: /* "includeslist" */
+#line 118 "ael.y"
+        { if (yymsg[0] != 'C') {destroy_pval((yyvaluep->pval)); prev_word=0;} else {printf("Cleanup destructor called for pvals\n");} };
+#line 1484 "ael.tab.c"
+        break;
+      case 92: /* "includedname" */
+#line 121 "ael.y"
+        { free((yyvaluep->str));};
+#line 1489 "ael.tab.c"
+        break;
+      case 93: /* "includes" */
+#line 118 "ael.y"
+        { if (yymsg[0] != 'C') {destroy_pval((yyvaluep->pval)); prev_word=0;} else {printf("Cleanup destructor called for pvals\n");} };
+#line 1494 "ael.tab.c"
+        break;
+
+      default:
+        break;
+    }
+}
+
+
+/* Prevent warnings from -Wmissing-prototypes.  */
+
+#ifdef YYPARSE_PARAM
+# if defined (__STDC__) || defined (__cplusplus)
+int yyparse (void *YYPARSE_PARAM);
+# else
+int yyparse ();
+# endif
+#else /* ! YYPARSE_PARAM */
+#if defined (__STDC__) || defined (__cplusplus)
+int yyparse (struct parse_io *parseio);
+#else
+int yyparse ();
+#endif
+#endif /* ! YYPARSE_PARAM */
+
+
+
+
+
+
+/*----------.
+| yyparse.  |
+`----------*/
+
+#ifdef YYPARSE_PARAM
+# if defined (__STDC__) || defined (__cplusplus)
+int yyparse (void *YYPARSE_PARAM)
+# else
+int yyparse (YYPARSE_PARAM)
+  void *YYPARSE_PARAM;
+# endif
+#else /* ! YYPARSE_PARAM */
+#if defined (__STDC__) || defined (__cplusplus)
+int
+yyparse (struct parse_io *parseio)
+#else
+int
+yyparse (parseio)
+    struct parse_io *parseio;
+#endif
+#endif
+{
+  /* The look-ahead symbol.  */
+int yychar;
+
+/* The semantic value of the look-ahead symbol.  */
+YYSTYPE yylval;
+
+/* Number of syntax errors so far.  */
+int yynerrs;
+/* Location data for the look-ahead symbol.  */
+YYLTYPE yylloc;
+
+  int yystate;
+  int yyn;
+  int yyresult;
+  /* Number of tokens to shift before error messages enabled.  */
+  int yyerrstatus;
+  /* Look-ahead token as an internal (translated) token number.  */
+  int yytoken = 0;
+
+  /* Three stacks and their tools:
+     `yyss': related to states,
+     `yyvs': related to semantic values,
+     `yyls': related to locations.
+
+     Refer to the stacks thru separate pointers, to allow yyoverflow
+     to reallocate them elsewhere.  */
+
+  /* The state stack.  */
+  short int yyssa[YYINITDEPTH];
+  short int *yyss = yyssa;
+  short int *yyssp;
+
+  /* The semantic value stack.  */
+  YYSTYPE yyvsa[YYINITDEPTH];
+  YYSTYPE *yyvs = yyvsa;
+  YYSTYPE *yyvsp;
+
+  /* The location stack.  */
+  YYLTYPE yylsa[YYINITDEPTH];
+  YYLTYPE *yyls = yylsa;
+  YYLTYPE *yylsp;
+  /* The locations where the error started and ended. */
+  YYLTYPE yyerror_range[2];
+
+#define YYPOPSTACK   (yyvsp--, yyssp--, yylsp--)
+
+  YYSIZE_T yystacksize = YYINITDEPTH;
+
+  /* The variables used to return semantic value and location from the
+     action routines.  */
+  YYSTYPE yyval;
+  YYLTYPE yyloc;
+
+  /* When reducing, the number of symbols on the RHS of the reduced
+     rule.  */
+  int yylen;
+
+  YYDPRINTF ((stderr, "Starting parse\n"));
+
+  yystate = 0;
+  yyerrstatus = 0;
+  yynerrs = 0;
+  yychar = YYEMPTY;		/* Cause a token to be read.  */
+
+  /* Initialize stack pointers.
+     Waste one element of value and location stack
+     so that they stay on the same level as the state stack.
+     The wasted elements are never initialized.  */
+
+  yyssp = yyss;
+  yyvsp = yyvs;
+  yylsp = yyls;
+#if YYLTYPE_IS_TRIVIAL
+  /* Initialize the default location before parsing starts.  */
+  yylloc.first_line   = yylloc.last_line   = 1;
+  yylloc.first_column = yylloc.last_column = 0;
+#endif
+
+  goto yysetstate;
+
+/*------------------------------------------------------------.
+| yynewstate -- Push a new state, which is found in yystate.  |
+`------------------------------------------------------------*/
+ yynewstate:
+  /* In all cases, when you get here, the value and location stacks
+     have just been pushed. so pushing a state here evens the stacks.
+     */
+  yyssp++;
+
+ yysetstate:
+  *yyssp = yystate;
+
+  if (yyss + yystacksize - 1 <= yyssp)
+    {
+      /* Get the current used size of the three stacks, in elements.  */
+      YYSIZE_T yysize = yyssp - yyss + 1;
+
+#ifdef yyoverflow
+      {
+	/* Give user a chance to reallocate the stack. Use copies of
+	   these so that the &'s don't force the real ones into
+	   memory.  */
+	YYSTYPE *yyvs1 = yyvs;
+	short int *yyss1 = yyss;
+	YYLTYPE *yyls1 = yyls;
+
+	/* Each stack pointer address is followed by the size of the
+	   data in use in that stack, in bytes.  This used to be a
+	   conditional around just the two extra args, but that might
+	   be undefined if yyoverflow is a macro.  */
+	yyoverflow (YY_("memory exhausted"),
+		    &yyss1, yysize * sizeof (*yyssp),
+		    &yyvs1, yysize * sizeof (*yyvsp),
+		    &yyls1, yysize * sizeof (*yylsp),
+		    &yystacksize);
+	yyls = yyls1;
+	yyss = yyss1;
+	yyvs = yyvs1;
+      }
+#else /* no yyoverflow */
+# ifndef YYSTACK_RELOCATE
+      goto yyexhaustedlab;
+# else
+      /* Extend the stack our own way.  */
+      if (YYMAXDEPTH <= yystacksize)
+	goto yyexhaustedlab;
+      yystacksize *= 2;
+      if (YYMAXDEPTH < yystacksize)
+	yystacksize = YYMAXDEPTH;
+
+      {
+	short int *yyss1 = yyss;
+	union yyalloc *yyptr =
+	  (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
+	if (! yyptr)
+	  goto yyexhaustedlab;
+	YYSTACK_RELOCATE (yyss);
+	YYSTACK_RELOCATE (yyvs);
+	YYSTACK_RELOCATE (yyls);
+#  undef YYSTACK_RELOCATE
+	if (yyss1 != yyssa)
+	  YYSTACK_FREE (yyss1);
+      }
+# endif
+#endif /* no yyoverflow */
+
+      yyssp = yyss + yysize - 1;
+      yyvsp = yyvs + yysize - 1;
+      yylsp = yyls + yysize - 1;
+
+      YYDPRINTF ((stderr, "Stack size increased to %lu\n",
+		  (unsigned long int) yystacksize));
+
+      if (yyss + yystacksize - 1 <= yyssp)
+	YYABORT;
+    }
+
+  YYDPRINTF ((stderr, "Entering state %d\n", yystate));
+
+  goto yybackup;
+
+/*-----------.
+| yybackup.  |
+`-----------*/
+yybackup:
+
+/* Do appropriate processing given the current state.  */
+/* Read a look-ahead token if we need one and don't already have one.  */
+/* yyresume: */
+
+  /* First try to decide what to do without reference to look-ahead token.  */
+
+  yyn = yypact[yystate];
+  if (yyn == YYPACT_NINF)
+    goto yydefault;
+
+  /* Not known => get a look-ahead token if don't already have one.  */
+
+  /* YYCHAR is either YYEMPTY or YYEOF or a valid look-ahead symbol.  */
+  if (yychar == YYEMPTY)
+    {
+      YYDPRINTF ((stderr, "Reading a token: "));
+      yychar = YYLEX;
+    }
+
+  if (yychar <= YYEOF)
+    {
+      yychar = yytoken = YYEOF;
+      YYDPRINTF ((stderr, "Now at end of input.\n"));
+    }
+  else
+    {
+      yytoken = YYTRANSLATE (yychar);
+      YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc);
+    }
+
+  /* If the proper action on seeing token YYTOKEN is to reduce or to
+     detect an error, take that action.  */
+  yyn += yytoken;
+  if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken)
+    goto yydefault;
+  yyn = yytable[yyn];
+  if (yyn <= 0)
+    {
+      if (yyn == 0 || yyn == YYTABLE_NINF)
+	goto yyerrlab;
+      yyn = -yyn;
+      goto yyreduce;
+    }
+
+  if (yyn == YYFINAL)
+    YYACCEPT;
+
+  /* Shift the look-ahead token.  */
+  YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc);
+
+  /* Discard the token being shifted unless it is eof.  */
+  if (yychar != YYEOF)
+    yychar = YYEMPTY;
+
+  *++yyvsp = yylval;
+  *++yylsp = yylloc;
+
+  /* Count tokens shifted since error; after three, turn off error
+     status.  */
+  if (yyerrstatus)
+    yyerrstatus--;
+
+  yystate = yyn;
+  goto yynewstate;
+
+
+/*-----------------------------------------------------------.
+| yydefault -- do the default action for the current state.  |
+`-----------------------------------------------------------*/
+yydefault:
+  yyn = yydefact[yystate];
+  if (yyn == 0)
+    goto yyerrlab;
+  goto yyreduce;
+
+
+/*-----------------------------.
+| yyreduce -- Do a reduction.  |
+`-----------------------------*/
+yyreduce:
+  /* yyn is the number of a rule to reduce with.  */
+  yylen = yyr2[yyn];
+
+  /* If YYLEN is nonzero, implement the default value of the action:
+     `$$ = $1'.
+
+     Otherwise, the following line sets YYVAL to garbage.
+     This behavior is undocumented and Bison
+     users should not rely upon it.  Assigning to YYVAL
+     unconditionally makes the parser a bit smaller, and it avoids a
+     GCC warning that YYVAL may be used uninitialized.  */
+  yyval = yyvsp[1-yylen];
+
+  /* Default location. */
+  YYLLOC_DEFAULT (yyloc, yylsp - yylen, yylen);
+  YY_REDUCE_PRINT (yyn);
+  switch (yyn)
+    {
+        case 2:
+#line 126 "ael.y"
+    { (yyval.pval) = parseio->pval = (yyvsp[0].pval); ;}
+    break;
+
+  case 3:
+#line 129 "ael.y"
+    {(yyval.pval)=(yyvsp[0].pval);;}
+    break;
+
+  case 4:
+#line 130 "ael.y"
+    {if ( (yyvsp[-1].pval) && (yyvsp[0].pval) ) {(yyval.pval)=(yyvsp[-1].pval); linku1((yyval.pval),(yyvsp[0].pval));} 
+						 else if ( (yyvsp[-1].pval) ) {(yyval.pval)=(yyvsp[-1].pval);}
+						 else if ( (yyvsp[0].pval) ) {(yyval.pval)=(yyvsp[0].pval);} ;}
+    break;
+
+  case 5:
+#line 133 "ael.y"
+    {(yyval.pval)=(yyvsp[-1].pval);;}
+    break;
+
+  case 6:
+#line 136 "ael.y"
+    {(yyval.pval)=(yyvsp[0].pval);;}
+    break;
+
+  case 7:
+#line 137 "ael.y"
+    {(yyval.pval)=(yyvsp[0].pval);;}
+    break;
+
+  case 8:
+#line 138 "ael.y"
+    {(yyval.pval)=(yyvsp[0].pval);;}
+    break;
+
+  case 9:
+#line 139 "ael.y"
+    {(yyval.pval)=0;/* allow older docs to be read */;}
+    break;
+
+  case 10:
+#line 142 "ael.y"
+    {(yyval.pval)=npval(PV_CONTEXT,(yylsp[-4]).first_line,(yylsp[0]).last_line, (yylsp[-4]).first_column, (yylsp[0]).last_column); (yyval.pval)->u1.str = (yyvsp[-3].str); (yyval.pval)->u2.statements = (yyvsp[-1].pval); ;}
+    break;
+
+  case 11:
+#line 143 "ael.y"
+    {(yyval.pval)=npval(PV_CONTEXT,(yylsp[-3]).first_line,(yylsp[0]).last_line, (yylsp[-3]).first_column, (yylsp[0]).last_column); (yyval.pval)->u1.str = (yyvsp[-2].str); ;}
+    break;
+
+  case 12:
+#line 144 "ael.y"
+    {(yyval.pval)=npval(PV_CONTEXT,(yylsp[-4]).first_line,(yylsp[0]).last_line, (yylsp[-4]).first_column, (yylsp[0]).last_column); (yyval.pval)->u1.str = strdup("default"); (yyval.pval)->u2.statements = (yyvsp[-1].pval); ;}
+    break;
+
+  case 13:
+#line 145 "ael.y"
+    {(yyval.pval)=npval(PV_CONTEXT,(yylsp[-3]).first_line,(yylsp[0]).last_line, (yylsp[-3]).first_column, (yylsp[0]).last_column); (yyval.pval)->u1.str = strdup("default"); ;}
+    break;
+
+  case 14:
+#line 146 "ael.y"
+    {(yyval.pval)=npval(PV_CONTEXT,(yylsp[-5]).first_line,(yylsp[0]).last_line, (yylsp[-5]).first_column, (yylsp[0]).last_column); (yyval.pval)->u1.str = (yyvsp[-3].str); (yyval.pval)->u2.statements = (yyvsp[-1].pval);  (yyval.pval)->u3.abstract = 1;;}
+    break;
+
+  case 15:
+#line 147 "ael.y"
+    {(yyval.pval)=npval(PV_CONTEXT,(yylsp[-4]).first_line,(yylsp[0]).last_line, (yylsp[-4]).first_column, (yylsp[0]).last_column); (yyval.pval)->u1.str = (yyvsp[-2].str); (yyval.pval)->u3.abstract = 1; ;}
+    break;
+
+  case 16:
+#line 148 "ael.y"
+    {(yyval.pval)=npval(PV_CONTEXT,(yylsp[-5]).first_line,(yylsp[0]).last_line, (yylsp[-5]).first_column, (yylsp[0]).last_column); (yyval.pval)->u1.str = strdup("default"); (yyval.pval)->u2.statements = (yyvsp[-1].pval); (yyval.pval)->u3.abstract = 1; ;}
+    break;
+
+  case 17:
+#line 149 "ael.y"
+    {(yyval.pval)=npval(PV_CONTEXT,(yylsp[-4]).first_line,(yylsp[0]).last_line, (yylsp[-4]).first_column, (yylsp[0]).last_column); (yyval.pval)->u1.str = strdup("default"); (yyval.pval)->u3.abstract = 1; ;}
+    break;
+
+  case 18:
+#line 152 "ael.y"
+    {(yyval.pval)=npval(PV_MACRO,(yylsp[-7]).first_line,(yylsp[0]).last_line, (yylsp[-7]).first_column, (yylsp[0]).last_column); 
+																	 (yyval.pval)->u1.str = (yyvsp[-6].str); (yyval.pval)->u2.arglist = (yyvsp[-4].pval); (yyval.pval)->u3.macro_statements = (yyvsp[-1].pval); ;}
+    break;
+
+  case 19:
+#line 154 "ael.y"
+    {(yyval.pval)=npval(PV_MACRO,(yylsp[-6]).first_line,(yylsp[0]).last_line, (yylsp[-6]).first_column, (yylsp[0]).last_column); (yyval.pval)->u1.str = (yyvsp[-5].str); (yyval.pval)->u2.arglist = (yyvsp[-3].pval); ;}
+    break;
+
+  case 20:
+#line 155 "ael.y"
+    {(yyval.pval)=npval(PV_MACRO,(yylsp[-6]).first_line,(yylsp[0]).last_line, (yylsp[-6]).first_column, (yylsp[0]).last_column); (yyval.pval)->u1.str = (yyvsp[-5].str); (yyval.pval)->u3.macro_statements = (yyvsp[-1].pval); ;}
+    break;
+
+  case 21:
+#line 156 "ael.y"
+    {(yyval.pval)=npval(PV_MACRO,(yylsp[-5]).first_line,(yylsp[0]).last_line, (yylsp[-5]).first_column, (yylsp[0]).last_column); (yyval.pval)->u1.str = (yyvsp[-4].str); /* pretty empty! */ ;}
+    break;
+
+  case 22:
+#line 159 "ael.y"
+    {(yyval.pval)=npval(PV_GLOBALS,(yylsp[-3]).first_line,(yylsp[0]).last_line, (yylsp[-3]).first_column, (yylsp[0]).last_column); (yyval.pval)->u1.statements = (yyvsp[-1].pval);;}
+    break;
+
+  case 23:
+#line 160 "ael.y"
+    {(yyval.pval)=npval(PV_GLOBALS,(yylsp[-2]).first_line,(yylsp[0]).last_line, (yylsp[-2]).first_column, (yylsp[0]).last_column); /* and that's all */ ;}
+    break;
+
+  case 24:
+#line 163 "ael.y"
+    {(yyval.pval)=(yyvsp[0].pval);;}
+    break;
+
+  case 25:
+#line 164 "ael.y"
+    {(yyval.pval)=(yyvsp[-1].pval); linku1((yyval.pval),(yyvsp[0].pval));;}
+    break;
+
+  case 26:
+#line 165 "ael.y"
+    {(yyval.pval)=(yyvsp[-1].pval);;}
+    break;
+
+  case 27:
+#line 168 "ael.y"
+    { reset_semicount(parseio->scanner); ;}
+    break;
+
+  case 28:
+#line 168 "ael.y"
+    {(yyval.pval)=npval(PV_VARDEC,(yylsp[-4]).first_line,(yylsp[0]).last_line, (yylsp[-4]).first_column, (yylsp[0]).last_column); (yyval.pval)->u1.str = (yyvsp[-4].str);(yyval.pval)->u2.val = (yyvsp[-1].str); ;}
+    break;
+
+  case 29:
+#line 171 "ael.y"
+    {(yyval.pval)= npval(PV_WORD,(yylsp[0]).first_line,(yylsp[0]).last_line, (yylsp[0]).first_column, (yylsp[0]).last_column); (yyval.pval)->u1.str = (yyvsp[0].str); ;}
+    break;
+
+  case 30:
+#line 172 "ael.y"
+    {pval *z = npval(PV_WORD,(yylsp[-2]).first_line,(yylsp[0]).last_line, (yylsp[-2]).first_column, (yylsp[0]).last_column); z->u1.str = (yyvsp[0].str); (yyval.pval)=(yyvsp[-2].pval); linku1((yyval.pval),z); ;}
+    break;
+
+  case 31:
+#line 173 "ael.y"
+    {(yyval.pval)=(yyvsp[-1].pval);;}
+    break;
+
+  case 32:
+#line 176 "ael.y"
+    { (yyval.pval)=(yyvsp[0].pval);;}
+    break;
+
+  case 33:
+#line 177 "ael.y"
+    {(yyval.pval)=0;;}
+    break;
+
+  case 34:
+#line 178 "ael.y"
+    { if ( (yyvsp[-1].pval) && (yyvsp[0].pval) ) {(yyval.pval)=(yyvsp[-1].pval); linku1((yyval.pval),(yyvsp[0].pval));} 
+						 else if ( (yyvsp[-1].pval) ) {(yyval.pval)=(yyvsp[-1].pval);}
+						 else if ( (yyvsp[0].pval) ) {(yyval.pval)=(yyvsp[0].pval);} ;}
+    break;
+
+  case 35:
+#line 181 "ael.y"
+    { (yyval.pval)=(yyvsp[-1].pval);;}
+    break;
+
+  case 36:
+#line 184 "ael.y"
+    {(yyval.pval)=(yyvsp[0].pval);;}
+    break;
+
+  case 37:
+#line 185 "ael.y"
+    {(yyval.pval)=(yyvsp[0].pval);;}
+    break;
+
+  case 38:
+#line 186 "ael.y"
+    {(yyval.pval)=(yyvsp[0].pval);;}
+    break;
+
+  case 39:
+#line 187 "ael.y"
+    {(yyval.pval)=(yyvsp[0].pval);;}
+    break;
+
+  case 40:
+#line 188 "ael.y"
+    {(yyval.pval)=(yyvsp[0].pval);;}
+    break;
+
+  case 41:
+#line 189 "ael.y"
+    { reset_semicount(parseio->scanner); ;}
+    break;
+
+  case 42:
+#line 189 "ael.y"
+    {(yyval.pval)=npval(PV_VARDEC,(yylsp[-4]).first_line,(yylsp[0]).last_line, (yylsp[-4]).first_column, (yylsp[0]).last_column); (yyval.pval)->u1.str = (yyvsp[-4].str);(yyval.pval)->u2.val = (yyvsp[-1].str); ;}
+    break;
+
+  case 43:
+#line 190 "ael.y"
+    {free((yyvsp[-1].str)); (yyval.pval)=0;;}
+    break;
+
+  case 44:
+#line 191 "ael.y"
+    {(yyval.pval)=0;/* allow older docs to be read */;}
+    break;
+
+  case 45:
+#line 194 "ael.y"
+    { (yyval.pval)=npval(PV_IGNOREPAT,(yylsp[-3]).first_line,(yylsp[0]).last_line, (yylsp[-3]).first_column, (yylsp[0]).last_column); (yyval.pval)->u1.str = (yyvsp[-1].str);;}
+    break;
+
+  case 46:
+#line 197 "ael.y"
+    {(yyval.pval) = npval(PV_EXTENSION,(yylsp[-2]).first_line,(yylsp[0]).last_line, (yylsp[-2]).first_column, (yylsp[0]).last_column); (yyval.pval)->u1.str = (yyvsp[-2].str); (yyval.pval)->u2.statements = (yyvsp[0].pval); ;}
+    break;
+
+  case 47:
+#line 198 "ael.y"
+    {(yyval.pval) = npval(PV_EXTENSION,(yylsp[-3]).first_line,(yylsp[-1]).last_line, (yylsp[-3]).first_column, (yylsp[0]).last_column); (yyval.pval)->u1.str = (yyvsp[-2].str); (yyval.pval)->u2.statements = (yyvsp[0].pval); (yyval.pval)->u4.regexten=1;;}
+    break;
+
+  case 48:
+#line 199 "ael.y"
+    {(yyval.pval) = npval(PV_EXTENSION,(yylsp[-6]).first_line,(yylsp[0]).last_line, (yylsp[-6]).first_column, (yylsp[0]).last_column); (yyval.pval)->u1.str = (yyvsp[-2].str); (yyval.pval)->u2.statements = (yyvsp[0].pval); (yyval.pval)->u3.hints = (yyvsp[-4].str);;}
+    break;
+
+  case 49:
+#line 200 "ael.y"
+    {(yyval.pval) = npval(PV_EXTENSION,(yylsp[-7]).first_line,(yylsp[-4]).last_line, (yylsp[-7]).first_column, (yylsp[0]).last_column); (yyval.pval)->u1.str = (yyvsp[-2].str); (yyval.pval)->u2.statements = (yyvsp[0].pval); (yyval.pval)->u4.regexten=1;(yyval.pval)->u3.hints = (yyvsp[-4].str);;}
+    break;
+
+  case 50:
+#line 204 "ael.y"
+    {(yyval.pval)=(yyvsp[0].pval);;}
+    break;
+
+  case 51:
+#line 205 "ael.y"
+    {if ( (yyvsp[-1].pval) && (yyvsp[0].pval) ) {(yyval.pval)=(yyvsp[-1].pval); linku1((yyval.pval),(yyvsp[0].pval));} 
+						 else if ( (yyvsp[-1].pval) ) {(yyval.pval)=(yyvsp[-1].pval);}
+						 else if ( (yyvsp[0].pval) ) {(yyval.pval)=(yyvsp[0].pval);} ;}
+    break;
+
+  case 52:
+#line 208 "ael.y"
+    {(yyval.pval)=(yyvsp[-1].pval);;}
+    break;
+
+  case 53:
+#line 211 "ael.y"
+    { reset_parencount(parseio->scanner); ;}
+    break;
+
+  case 54:
+#line 211 "ael.y"
+    { (yyval.pval)= npval(PV_IF,(yylsp[-4]).first_line,(yylsp[0]).last_line, (yylsp[-4]).first_column, (yylsp[0]).last_column); (yyval.pval)->u1.str = (yyvsp[-1].str); ;}
+    break;
+
+  case 55:
+#line 214 "ael.y"
+    { reset_parencount(parseio->scanner); ;}
+    break;
+
+  case 56:
+#line 214 "ael.y"
+    { (yyval.pval)= npval(PV_RANDOM,(yylsp[-4]).first_line,(yylsp[0]).last_line, (yylsp[-4]).first_column, (yylsp[0]).last_column); (yyval.pval)->u1.str=(yyvsp[-1].str);;}
+    break;
+
+  case 57:
+#line 217 "ael.y"
+    { (yyval.pval)= npval(PV_IFTIME,(yylsp[-13]).first_line,(yylsp[-9]).last_line, (yylsp[-13]).first_column, (yylsp[-9]).last_column); 
+					(yyval.pval)->u1.list = npval(PV_WORD,(yylsp[-11]).first_line,(yylsp[-11]).last_line, (yylsp[-11]).first_column, (yylsp[-11]).last_column); 
+					(yyval.pval)->u1.list->u1.str = (char*)malloc(strlen((yyvsp[-11].str))+strlen((yyvsp[-9].str))+strlen((yyvsp[-7].str))+4);
+					strcpy((yyval.pval)->u1.list->u1.str,(yyvsp[-11].str));
+					strcat((yyval.pval)->u1.list->u1.str,":");
+					strcat((yyval.pval)->u1.list->u1.str,(yyvsp[-9].str));
+					strcat((yyval.pval)->u1.list->u1.str,":");
+					strcat((yyval.pval)->u1.list->u1.str,(yyvsp[-7].str));
+					free((yyvsp[-11].str));
+					free((yyvsp[-9].str));
+					free((yyvsp[-7].str));
+					(yyval.pval)->u1.list->next = npval(PV_WORD,(yylsp[-5]).first_line,(yylsp[-5]).last_line, (yylsp[-5]).first_column, (yylsp[-5]).last_column); 
+					(yyval.pval)->u1.list->next->u1.str = (yyvsp[-5].str); 
+					(yyval.pval)->u1.list->next->next = npval(PV_WORD,(yylsp[-3]).first_line,(yylsp[-3]).last_line, (yylsp[-3]).first_column, (yylsp[-3]).last_column); 
+					(yyval.pval)->u1.list->next->next->u1.str = (yyvsp[-3].str); 
+					(yyval.pval)->u1.list->next->next->next = npval(PV_WORD,(yylsp[-1]).first_line,(yylsp[-1]).last_line, (yylsp[-1]).first_column, (yylsp[-1]).last_column); 
+					(yyval.pval)->u1.list->next->next->next->u1.str = (yyvsp[-1].str); 
+					prev_word = 0;
+		;}
+    break;
+
+  case 58:
+#line 236 "ael.y"
+    { (yyval.pval)= npval(PV_IFTIME,(yylsp[-9]).first_line,(yylsp[-5]).last_line, (yylsp[-9]).first_column, (yylsp[-5]).last_column); 
+					(yyval.pval)->u1.list = npval(PV_WORD,(yylsp[-7]).first_line,(yylsp[-7]).last_line, (yylsp[-7]).first_column, (yylsp[-7]).last_column); 
+					(yyval.pval)->u1.list->u1.str = (yyvsp[-7].str);
+					(yyval.pval)->u1.list->next = npval(PV_WORD,(yylsp[-5]).first_line,(yylsp[-5]).last_line, (yylsp[-5]).first_column, (yylsp[-5]).last_column); 
+					(yyval.pval)->u1.list->next->u1.str = (yyvsp[-5].str); 
+					(yyval.pval)->u1.list->next->next = npval(PV_WORD,(yylsp[-3]).first_line,(yylsp[-3]).last_line, (yylsp[-3]).first_column, (yylsp[-3]).last_column); 
+					(yyval.pval)->u1.list->next->next->u1.str = (yyvsp[-3].str); 
+					(yyval.pval)->u1.list->next->next->next = npval(PV_WORD,(yylsp[-1]).first_line,(yylsp[-1]).last_line, (yylsp[-1]).first_column, (yylsp[-1]).last_column); 
+					(yyval.pval)->u1.list->next->next->next->u1.str = (yyvsp[-1].str); 
+					prev_word = 0;
+		;}
+    break;
+
+  case 59:
+#line 255 "ael.y"
+    { (yyval.str) = (yyvsp[0].str);;}
+    break;
+
+  case 60:
+#line 256 "ael.y"
+    { (yyval.str) = (char*)malloc(strlen((yyvsp[-1].str))+strlen((yyvsp[0].str))+1); strcpy((yyval.str), (yyvsp[-1].str)); strcat((yyval.str), (yyvsp[0].str));  free((yyvsp[-1].str)); free((yyvsp[0].str));prev_word = (yyval.str);;}
+    break;
+
+  case 61:
+#line 258 "ael.y"
+    { (yyval.str) = (yyvsp[0].str);;}
+    break;
+
+  case 62:
+#line 259 "ael.y"
+    { (yyval.str) = (char*)malloc(strlen((yyvsp[-1].str))+strlen((yyvsp[0].str))+1); strcpy((yyval.str), (yyvsp[-1].str)); strcat((yyval.str), (yyvsp[0].str));  free((yyvsp[-1].str)); free((yyvsp[0].str));prev_word = (yyval.str);;}
+    break;
+
+  case 63:
+#line 260 "ael.y"
+    { (yyval.str) = (char*)malloc(strlen((yyvsp[-2].str))+strlen((yyvsp[-1].str))+strlen((yyvsp[0].str))+1); strcpy((yyval.str), (yyvsp[-2].str)); strcat((yyval.str), (yyvsp[-1].str));  strcat((yyval.str), (yyvsp[0].str));  free((yyvsp[-2].str)); free((yyvsp[-1].str)); free((yyvsp[0].str));prev_word=(yyval.str);;}
+    break;
+
+  case 64:
+#line 263 "ael.y"
+    { (yyval.str) = (yyvsp[0].str);;}
+    break;
+
+  case 65:
+#line 264 "ael.y"
+    { (yyval.str) = (char*)malloc(strlen((yyvsp[-1].str))+strlen((yyvsp[0].str))+1); strcpy((yyval.str), (yyvsp[-1].str)); strcat((yyval.str), (yyvsp[0].str));  free((yyvsp[-1].str)); free((yyvsp[0].str));;}
+    break;
+
+  case 66:
+#line 265 "ael.y"
+    { (yyval.str) = (char*)malloc(strlen((yyvsp[-2].str))+strlen((yyvsp[0].str))+2); strcpy((yyval.str), (yyvsp[-2].str)); strcat((yyval.str),":"); strcat((yyval.str), (yyvsp[0].str));  free((yyvsp[-2].str)); free((yyvsp[0].str));;}
+    break;
+
+  case 67:
+#line 268 "ael.y"
+    { reset_parencount(parseio->scanner); ;}
+    break;
+
+  case 68:
+#line 269 "ael.y"
+    {(yyval.pval)=npval(PV_SWITCH,(yylsp[-5]).first_line,(yylsp[0]).last_line, (yylsp[-5]).first_column, (yylsp[0]).last_column);
+						(yyval.pval)->u1.str = (yyvsp[-2].str); ;}
+    break;
+
+  case 69:
+#line 273 "ael.y"
+    {(yyval.pval)=npval(PV_STATEMENTBLOCK,(yylsp[-2]).first_line,(yylsp[0]).last_line, (yylsp[-2]).first_column, (yylsp[0]).last_column); (yyval.pval)->u1.list = (yyvsp[-1].pval); ;}
+    break;
+
+  case 70:
+#line 274 "ael.y"
+    {reset_semicount(parseio->scanner);;}
+    break;
+
+  case 71:
+#line 275 "ael.y"
+    {(yyval.pval)=npval(PV_VARDEC,(yylsp[-4]).first_line,(yylsp[0]).last_line, (yylsp[-4]).first_column, (yylsp[0]).last_column); 
+				(yyval.pval)->u1.str = (yyvsp[-4].str); (yyval.pval)->u2.val = (yyvsp[-1].str); ;}
+    break;
+
+  case 72:
+#line 277 "ael.y"
+    {(yyval.pval)=npval(PV_GOTO,(yylsp[-2]).first_line,(yylsp[0]).last_line, (yylsp[-2]).first_column, (yylsp[0]).last_column); (yyval.pval)->u1.list = (yyvsp[-1].pval);;}
+    break;
+
+  case 73:
+#line 278 "ael.y"
+    {(yyval.pval)=npval(PV_GOTO,(yylsp[-2]).first_line,(yylsp[0]).last_line, (yylsp[-2]).first_column, (yylsp[0]).last_column); (yyval.pval)->u1.list = (yyvsp[-1].pval);;}
+    break;
+
+  case 74:
+#line 279 "ael.y"
+    {(yyval.pval)=npval(PV_LABEL,(yylsp[-1]).first_line,(yylsp[0]).last_line, (yylsp[-1]).first_column, (yylsp[0]).last_column); (yyval.pval)->u1.str = (yyvsp[-1].str); ;}
+    break;
+
+  case 75:
+#line 280 "ael.y"
+    {reset_semicount(parseio->scanner);;}
+    break;
+
+  case 76:
+#line 281 "ael.y"
+    {reset_semicount(parseio->scanner);;}
+    break;
+
+  case 77:
+#line 282 "ael.y"
+    {reset_parencount(parseio->scanner);;}
+    break;
+
+  case 78:
+#line 283 "ael.y"
+    { (yyval.pval)=npval(PV_FOR,(yylsp[-11]).first_line,(yylsp[0]).last_line, (yylsp[-11]).first_column, (yylsp[0]).last_column); 
+						(yyval.pval)->u1.for_init = (yyvsp[-8].str); (yyval.pval)->u2.for_test=(yyvsp[-5].str); (yyval.pval)->u3.for_inc = (yyvsp[-2].str); (yyval.pval)->u4.for_statements = (yyvsp[0].pval);;}
+    break;
+
+  case 79:
+#line 285 "ael.y"
+    {reset_parencount(parseio->scanner);;}
+    break;
+
+  case 80:
+#line 286 "ael.y"
+    {(yyval.pval)=npval(PV_WHILE,(yylsp[-5]).first_line,(yylsp[0]).last_line, (yylsp[-5]).first_column, (yylsp[0]).last_column); 
+					(yyval.pval)->u1.str = (yyvsp[-2].str); (yyval.pval)->u2.statements = (yyvsp[0].pval); ;}
+    break;
+
+  case 81:
+#line 288 "ael.y"
+    {(yyval.pval)=(yyvsp[-1].pval);(yyval.pval)->endline = (yylsp[0]).last_line; (yyval.pval)->endcol = (yylsp[0]).last_column;;}
+    break;
+
+  case 82:
+#line 289 "ael.y"
+    {(yyval.pval)=(yyvsp[-2].pval); (yyval.pval)->u2.statements = (yyvsp[-1].pval);(yyval.pval)->endline = (yylsp[0]).last_line; (yyval.pval)->endcol = (yylsp[0]).last_column;;}
+    break;
+
+  case 83:
+#line 290 "ael.y"
+    {(yyval.pval) = (yyvsp[-1].pval);(yyval.pval)->endline = (yylsp[-1]).last_line; (yyval.pval)->endcol = (yylsp[-1]).last_column;;}
+    break;
+
+  case 84:
+#line 291 "ael.y"
+    { (yyval.pval) = (yyvsp[-1].pval);(yyval.pval)->endline = (yylsp[0]).last_line; (yyval.pval)->endcol = (yylsp[0]).last_column;;}
+    break;
+
+  case 85:
+#line 292 "ael.y"
+    { (yyval.pval)= npval(PV_APPLICATION_CALL,(yylsp[-1]).first_line,(yylsp[0]).last_line, (yylsp[-1]).first_column, (yylsp[0]).last_column); 
+																						(yyval.pval)->u1.str = (yyvsp[-1].str);;}
+    break;
+
+  case 86:
+#line 294 "ael.y"
+    {reset_semicount(parseio->scanner);;}
+    break;
+
+  case 87:
+#line 294 "ael.y"
+    {
+                          char *bufx;
+						  int tot=0;
+						  pval *pptr;
+						  
+                          (yyval.pval) = npval(PV_VARDEC,(yylsp[-4]).first_line,(yylsp[0]).last_line, (yylsp[-4]).first_column, (yylsp[0]).last_column);
+						  (yyval.pval)->u2.val=(yyvsp[-1].str);
+						  /* rebuild the original string-- this is not an app call, it's an unwrapped vardec, with a func call on the LHS */
+                          /* string to big to fit in the buffer? */
+						  tot+=strlen((yyvsp[-4].pval)->u1.str);
+						  for(pptr=(yyvsp[-4].pval)->u2.arglist;pptr;pptr=pptr->next) {
+							  tot+=strlen(pptr->u1.str);
+							  tot++; /* for a sep like a comma */
+						  }
+						  tot+=4; /* for safety */
+						  bufx = (char *)malloc(tot);
+						  strcpy(bufx,(yyvsp[-4].pval)->u1.str);
+						  strcat(bufx,"(");
+						  for (pptr=(yyvsp[-4].pval)->u2.arglist;pptr;pptr=pptr->next) {
+							  if ( pptr != (yyvsp[-4].pval)->u2.arglist )
+								  strcat(bufx,",");
+							  strcat(bufx,pptr->u1.str);
+						  }
+						  strcat(bufx,")");
+#ifdef AAL_ARGCHECK
+						  if ( !ael_is_funcname((yyvsp[-4].pval)->u1.str) )
+                              ast_log(LOG_WARNING, "==== File: %s, Line %d, Cols: %d-%d: Function call? The name %s is not in my internal list of function names\n", 
+									  my_file, (yylsp[-4]).first_line, (yylsp[-4]).first_column, (yylsp[-4]).last_column, (yyvsp[-4].pval)->u1.str);
+#endif
+						  (yyval.pval)->u1.str = bufx;
+						  destroy_pval((yyvsp[-4].pval)); /* the app call it is not, get rid of that chain */
+						  prev_word = 0;
+                       ;}
+    break;
+
+  case 88:
+#line 327 "ael.y"
+    { (yyval.pval) = npval(PV_BREAK,(yylsp[-1]).first_line,(yylsp[0]).last_line, (yylsp[-1]).first_column, (yylsp[0]).last_column);;}
+    break;
+
+  case 89:
+#line 328 "ael.y"
+    {(yyval.pval) = npval(PV_RETURN,(yylsp[-1]).first_line,(yylsp[0]).last_line, (yylsp[-1]).first_column, (yylsp[0]).last_column);;}
+    break;
+
+  case 90:
+#line 329 "ael.y"
+    {(yyval.pval) = npval(PV_CONTINUE,(yylsp[-1]).first_line,(yylsp[0]).last_line, (yylsp[-1]).first_column, (yylsp[0]).last_column);;}
+    break;
+
+  case 91:
+#line 330 "ael.y"
+    {(yyval.pval)=(yyvsp[-1].pval); (yyval.pval)->u2.statements = (yyvsp[0].pval);(yyval.pval)->endline = (yylsp[0]).last_line; (yyval.pval)->endcol = (yylsp[0]).last_column;;}
+    break;
+
+  case 92:
+#line 331 "ael.y"
+    {(yyval.pval)=(yyvsp[-3].pval); (yyval.pval)->u2.statements = (yyvsp[-2].pval);(yyval.pval)->endline = (yylsp[-2]).last_line; (yyval.pval)->endcol = (yylsp[-2]).last_column; (yyval.pval)->u3.else_statements = (yyvsp[0].pval);;}
+    break;
+
+  case 93:
+#line 332 "ael.y"
+    {(yyval.pval)=(yyvsp[-1].pval); (yyval.pval)->u2.statements = (yyvsp[0].pval);(yyval.pval)->endline = (yylsp[0]).last_line; (yyval.pval)->endcol = (yylsp[0]).last_column;;}
+    break;
+
+  case 94:
+#line 333 "ael.y"
+    {(yyval.pval)=(yyvsp[-3].pval); (yyval.pval)->u2.statements = (yyvsp[-2].pval);(yyval.pval)->endline = (yylsp[-2]).last_line; (yyval.pval)->endcol = (yylsp[-2]).last_column; (yyval.pval)->u3.else_statements = (yyvsp[0].pval);;}
+    break;
+
+  case 95:
+#line 334 "ael.y"
+    {(yyval.pval)=(yyvsp[-1].pval); (yyval.pval)->u2.statements = (yyvsp[0].pval);(yyval.pval)->endline = (yylsp[0]).last_line; (yyval.pval)->endcol = (yylsp[0]).last_column;;}
+    break;
+
+  case 96:
+#line 335 "ael.y"
+    {(yyval.pval)=(yyvsp[-3].pval); (yyval.pval)->u2.statements = (yyvsp[-2].pval);(yyval.pval)->endline = (yylsp[-2]).last_line; (yyval.pval)->endcol = (yylsp[-2]).last_column; (yyval.pval)->u3.else_statements = (yyvsp[0].pval);;}
+    break;
+
+  case 97:
+#line 336 "ael.y"
+    { (yyval.pval)=0; ;}
+    break;
+
+  case 98:
+#line 339 "ael.y"
+    { (yyval.pval) = npval(PV_WORD,(yylsp[0]).first_line,(yylsp[0]).last_line, (yylsp[0]).first_column, (yylsp[0]).last_column); (yyval.pval)->u1.str = (yyvsp[0].str);;}
+    break;
+
+  case 99:
+#line 340 "ael.y"
+    {(yyval.pval)=npval(PV_WORD,(yylsp[-2]).first_line,(yylsp[-2]).last_line, (yylsp[-2]).first_column, (yylsp[-2]).last_column); 
+					(yyval.pval)->u1.str = (yyvsp[-2].str); (yyval.pval)->next = npval(PV_WORD,(yylsp[0]).first_line,(yylsp[0]).last_line, (yylsp[0]).first_column, (yylsp[0]).last_column); 
+					(yyval.pval)->next->u1.str = (yyvsp[0].str);;}
+    break;
+
+  case 100:
+#line 343 "ael.y"
+    {(yyval.pval)=npval(PV_WORD,(yylsp[-2]).first_line,(yylsp[-2]).last_line, (yylsp[-2]).first_column, (yylsp[-2]).last_column); 
+					(yyval.pval)->u1.str = (yyvsp[-2].str); (yyval.pval)->next = npval(PV_WORD,(yylsp[0]).first_line,(yylsp[0]).last_line, (yylsp[0]).first_column, (yylsp[0]).last_column); 
+					(yyval.pval)->next->u1.str = (yyvsp[0].str);;}
+    break;
+
+  case 101:
+#line 346 "ael.y"
+    {(yyval.pval)=npval(PV_WORD,(yylsp[-4]).first_line,(yylsp[-4]).last_line, (yylsp[-4]).first_column, (yylsp[-4]).last_column); 
+					(yyval.pval)->u1.str = (yyvsp[-4].str); (yyval.pval)->next = npval(PV_WORD,(yylsp[-2]).first_line,(yylsp[-2]).last_line, (yylsp[-2]).first_column, (yylsp[-2]).last_column); 
+					(yyval.pval)->next->u1.str = (yyvsp[-2].str); 
+					(yyval.pval)->next->next = npval(PV_WORD,(yylsp[0]).first_line,(yylsp[0]).last_line, (yylsp[0]).first_column, (yylsp[0]).last_column); 
+					(yyval.pval)->next->next->u1.str = (yyvsp[0].str); ;}
+    break;
+
+  case 102:
+#line 351 "ael.y"
+    {(yyval.pval)=npval(PV_WORD,(yylsp[-4]).first_line,(yylsp[-4]).last_line, (yylsp[-4]).first_column, (yylsp[-4]).last_column); 
+					(yyval.pval)->u1.str = (yyvsp[-4].str); (yyval.pval)->next = npval(PV_WORD,(yylsp[-2]).first_line,(yylsp[-2]).last_line, (yylsp[-2]).first_column, (yylsp[-2]).last_column); 
+					(yyval.pval)->next->u1.str = (yyvsp[-2].str); 
+					(yyval.pval)->next->next = npval(PV_WORD,(yylsp[0]).first_line,(yylsp[0]).last_line, (yylsp[0]).first_column, (yylsp[0]).last_column); 
+					(yyval.pval)->next->next->u1.str = (yyvsp[0].str); ;}
+    break;
+
+  case 103:
+#line 356 "ael.y"
+    {(yyval.pval)=npval(PV_WORD,(yylsp[-4]).first_line,(yylsp[-4]).last_line, (yylsp[-4]).first_column, (yylsp[-4]).last_column); 
+					(yyval.pval)->u1.str = strdup("default"); (yyval.pval)->next = npval(PV_WORD,(yylsp[-2]).first_line,(yylsp[-2]).last_line, (yylsp[-2]).first_column, (yylsp[-2]).last_column); 
+					(yyval.pval)->next->u1.str = (yyvsp[-2].str); 
+					(yyval.pval)->next->next = npval(PV_WORD,(yylsp[0]).first_line,(yylsp[0]).last_line, (yylsp[0]).first_column, (yylsp[0]).last_column); 
+					(yyval.pval)->next->next->u1.str = (yyvsp[0].str); ;}
+    break;
+
+  case 104:
+#line 361 "ael.y"
+    {(yyval.pval)=npval(PV_WORD,(yylsp[-4]).first_line,(yylsp[-4]).last_line, (yylsp[-4]).first_column, (yylsp[-4]).last_column); 
+					(yyval.pval)->u1.str = strdup("default"); (yyval.pval)->next = npval(PV_WORD,(yylsp[-2]).first_line,(yylsp[-2]).last_line, (yylsp[-2]).first_column, (yylsp[-2]).last_column); 
+					(yyval.pval)->next->u1.str = (yyvsp[-2].str); 
+					(yyval.pval)->next->next = npval(PV_WORD,(yylsp[0]).first_line,(yylsp[0]).last_line, (yylsp[0]).first_column, (yylsp[0]).last_column); 
+					(yyval.pval)->next->next->u1.str = (yyvsp[0].str); ;}
+    break;
+
+  case 105:
+#line 368 "ael.y"
+    {(yyval.pval)=npval(PV_WORD,(yylsp[0]).first_line,(yylsp[0]).last_line, (yylsp[0]).first_column, (yylsp[0]).last_column); 
+					(yyval.pval)->u1.str = (yyvsp[0].str); (yyval.pval)->next = npval(PV_WORD,(yylsp[0]).first_line,(yylsp[0]).last_line, (yylsp[0]).first_column, (yylsp[0]).last_column); 
+					(yyval.pval)->next->u1.str = strdup("1");;}
+    break;
+
+  case 106:
+#line 371 "ael.y"
+    {(yyval.pval)=npval(PV_WORD,(yylsp[-2]).first_line,(yylsp[-2]).last_line, (yylsp[-2]).first_column, (yylsp[-2]).last_column); 
+					(yyval.pval)->u1.str = (yyvsp[-2].str); (yyval.pval)->next = npval(PV_WORD,(yylsp[0]).first_line,(yylsp[0]).last_line, (yylsp[0]).first_column, (yylsp[0]).last_column); 
+					(yyval.pval)->next->u1.str = (yyvsp[0].str);;}
+    break;
+
+  case 107:
+#line 374 "ael.y"
+    {(yyval.pval)=npval(PV_WORD,(yylsp[-4]).first_line,(yylsp[-4]).last_line, (yylsp[-4]).first_column, (yylsp[-4]).last_column); 
+					(yyval.pval)->u1.str = (yyvsp[0].str); (yyval.pval)->next = npval(PV_WORD,(yylsp[-2]).first_line,(yylsp[-2]).last_line, (yylsp[-2]).first_column, (yylsp[-2]).last_column); 
+					(yyval.pval)->next->u1.str = (yyvsp[-4].str); 
+					(yyval.pval)->next->next = npval(PV_WORD,(yylsp[0]).first_line,(yylsp[0]).last_line, (yylsp[0]).first_column, (yylsp[0]).last_column); 
+					(yyval.pval)->next->next->u1.str = (yyvsp[-2].str); ;}
+    break;
+
+  case 108:
+#line 379 "ael.y"
+    {(yyval.pval)=npval(PV_WORD,(yylsp[-2]).first_line,(yylsp[-2]).last_line, (yylsp[-2]).first_column, (yylsp[-2]).last_column); 
+					(yyval.pval)->u1.str = (yyvsp[0].str); (yyval.pval)->next = npval(PV_WORD,(yylsp[0]).first_line,(yylsp[0]).last_line, (yylsp[0]).first_column, (yylsp[0]).last_column); 
+					(yyval.pval)->next->u1.str = (yyvsp[-2].str); 
+					(yyval.pval)->next->next = npval(PV_WORD,(yylsp[0]).first_line,(yylsp[0]).last_line, (yylsp[0]).first_column, (yylsp[0]).last_column); 
+					(yyval.pval)->next->next->u1.str = strdup("1"); ;}
+    break;
+
+  case 109:
+#line 384 "ael.y"
+    {(yyval.pval)=npval(PV_WORD,(yylsp[-4]).first_line,(yylsp[-4]).last_line, (yylsp[-4]).first_column, (yylsp[-4]).last_column); 
+					(yyval.pval)->u1.str = strdup("default"); (yyval.pval)->next = npval(PV_WORD,(yylsp[-2]).first_line,(yylsp[-2]).last_line, (yylsp[-2]).first_column, (yylsp[-2]).last_column); 
+					(yyval.pval)->next->u1.str = (yyvsp[-4].str); 
+					(yyval.pval)->next->next = npval(PV_WORD,(yylsp[0]).first_line,(yylsp[0]).last_line, (yylsp[0]).first_column, (yylsp[0]).last_column); 
+					(yyval.pval)->next->next->u1.str = (yyvsp[-2].str); ;}
+    break;
+
+  case 110:
+#line 389 "ael.y"
+    {(yyval.pval)=npval(PV_WORD,(yylsp[-2]).first_line,(yylsp[-2]).last_line, (yylsp[-2]).first_column, (yylsp[-2]).last_column); 
+					(yyval.pval)->u1.str = strdup("default"); (yyval.pval)->next = npval(PV_WORD,(yylsp[0]).first_line,(yylsp[0]).last_line, (yylsp[0]).first_column, (yylsp[0]).last_column); 
+					(yyval.pval)->next->u1.str = (yyvsp[-2].str); 
+					(yyval.pval)->next->next = npval(PV_WORD,(yylsp[0]).first_line,(yylsp[0]).last_line, (yylsp[0]).first_column, (yylsp[0]).last_column); 
+					(yyval.pval)->next->next->u1.str = strdup("1"); ;}
+    break;
+
+  case 111:
+#line 396 "ael.y"
+    {reset_argcount(parseio->scanner);;}
+    break;
+
+  case 112:
+#line 397 "ael.y"
+    {(yyval.pval)= npval(PV_MACRO_CALL,(yylsp[-4]).first_line,(yylsp[-3]).last_line, (yylsp[-4]).first_column, (yylsp[-3]).last_column); 
+			(yyval.pval)->u1.str = (yyvsp[-4].str); (yyval.pval)->u2.arglist = (yyvsp[-1].pval);;}
+    break;
+
+  case 113:
+#line 399 "ael.y"
+    {(yyval.pval)= npval(PV_MACRO_CALL,(yylsp[-2]).first_line,(yylsp[0]).last_line, (yylsp[-2]).first_column, (yylsp[0]).last_column); (yyval.pval)->u1.str = (yyvsp[-2].str); ;}
+    break;
+
+  case 114:
+#line 402 "ael.y"
+    {reset_argcount(parseio->scanner);;}
+    break;
+
+  case 115:
+#line 402 "ael.y"
+    {if (strcasecmp((yyvsp[-2].str),"goto") == 0) {
+																							(yyval.pval)= npval(PV_GOTO,(yylsp[-2]).first_line,(yylsp[0]).last_line, (yylsp[-2]).first_column, (yylsp[0]).last_column);
+																							free((yyvsp[-2].str)); /* won't be using this */
+																							ast_log(LOG_WARNING, "==== File: %s, Line %d, Cols: %d-%d: Suggestion: Use the goto statement instead of the Goto() application call in AEL.\n", my_file, (yylsp[-2]).first_line, (yylsp[-2]).first_column, (yylsp[-2]).last_column );
+																						} else
+																							(yyval.pval)= npval(PV_APPLICATION_CALL,(yylsp[-2]).first_line,(yylsp[0]).last_line, (yylsp[-2]).first_column, (yylsp[0]).last_column); 
+																						(yyval.pval)->u1.str = (yyvsp[-2].str); ;}
+    break;
+
+  case 116:
+#line 411 "ael.y"
+    {(yyval.pval) = (yyvsp[-2].pval);
+ 		if( (yyval.pval)->type == PV_GOTO )
+			(yyval.pval)->u1.list = (yyvsp[-1].pval);
+	 	else
+			(yyval.pval)->u2.arglist = (yyvsp[-1].pval);
+ 		(yyval.pval)->endline = (yylsp[0]).last_line; (yyval.pval)->endcol = (yylsp[0]).last_column;;}
+    break;
+
+  case 117:
+#line 417 "ael.y"
+    {(yyval.pval)=(yyvsp[-1].pval);(yyval.pval)->endline = (yylsp[0]).last_line; (yyval.pval)->endcol = (yylsp[0]).last_column;;}
+    break;
+
+  case 118:
+#line 420 "ael.y"
+    { (yyval.pval)= npval(PV_WORD,(yylsp[0]).first_line,(yylsp[0]).last_line, (yylsp[0]).first_column, (yylsp[0]).last_column); (yyval.pval)->u1.str = (yyvsp[0].str);;}
+    break;
+
+  case 119:
+#line 421 "ael.y"
+    { (yyval.pval)= npval(PV_WORD,0/*@1.first_line*/,0/*@1.last_line*/,0/* @1.first_column*/, 0/*@1.last_column*/); (yyval.pval)->u1.str = strdup(""); ;}
+    break;
+
+  case 120:
+#line 422 "ael.y"
+    { pval *z = npval(PV_WORD,(yylsp[0]).first_line,(yylsp[0]).last_line, (yylsp[0]).first_column, (yylsp[0]).last_column); (yyval.pval) = (yyvsp[-2].pval); linku1((yyvsp[-2].pval),z); z->u1.str = (yyvsp[0].str);;}
+    break;
+
+  case 121:
+#line 423 "ael.y"
+    { pval *z = npval(PV_WORD,(yylsp[0]).first_line,(yylsp[0]).last_line, (yylsp[0]).first_column, (yylsp[0]).last_column); (yyval.pval) = (yyvsp[-1].pval); linku1((yyvsp[-1].pval),z); z->u1.str = strdup("");;}
+    break;
+
+  case 122:
+#line 426 "ael.y"
+    {(yyval.pval)=(yyvsp[0].pval);;}
+    break;
+
+  case 123:
+#line 427 "ael.y"
+    { if ( (yyvsp[-1].pval) && (yyvsp[0].pval) ) {(yyval.pval)=(yyvsp[-1].pval); linku1((yyval.pval),(yyvsp[0].pval));} 
+						 else if ( (yyvsp[-1].pval) ) {(yyval.pval)=(yyvsp[-1].pval);}
+						 else if ( (yyvsp[0].pval) ) {(yyval.pval)=(yyvsp[0].pval);} ;}
+    break;
+
+  case 124:
+#line 432 "ael.y"
+    {(yyval.pval) = npval(PV_CASE,(yylsp[-3]).first_line,(yylsp[-1]).last_line, (yylsp[-3]).first_column, (yylsp[-1]).last_column); (yyval.pval)->u1.str = (yyvsp[-2].str); (yyval.pval)->u2.statements = (yyvsp[0].pval);;}
+    break;
+
+  case 125:
+#line 433 "ael.y"
+    {(yyval.pval) = npval(PV_DEFAULT,(yylsp[-2]).first_line,(yylsp[0]).last_line, (yylsp[-2]).first_column, (yylsp[0]).last_column); (yyval.pval)->u1.str = 0; (yyval.pval)->u2.statements = (yyvsp[0].pval);;}
+    break;
+
+  case 126:
+#line 434 "ael.y"
+    {(yyval.pval) = npval(PV_PATTERN,(yylsp[-3]).first_line,(yylsp[-1]).last_line, (yylsp[-3]).first_column, (yylsp[-1]).last_column); (yyval.pval)->u1.str = (yyvsp[-2].str); (yyval.pval)->u2.statements = (yyvsp[0].pval);;}
+    break;
+
+  case 127:
+#line 435 "ael.y"
+    {(yyval.pval) = npval(PV_CASE,(yylsp[-2]).first_line,(yylsp[0]).last_line, (yylsp[-2]).first_column, (yylsp[0]).last_column); (yyval.pval)->u1.str = (yyvsp[-1].str);;}
+    break;
+
+  case 128:
+#line 436 "ael.y"
+    {(yyval.pval) = npval(PV_DEFAULT,(yylsp[-1]).first_line,(yylsp[0]).last_line, (yylsp[-1]).first_column, (yylsp[0]).last_column); (yyval.pval)->u1.str = 0;;}
+    break;
+
+  case 129:
+#line 437 "ael.y"
+    {(yyval.pval) = npval(PV_PATTERN,(yylsp[-2]).first_line,(yylsp[0]).last_line, (yylsp[-2]).first_column, (yylsp[0]).last_column); (yyval.pval)->u1.str = (yyvsp[-1].str);;}
+    break;
+
+  case 130:
+#line 440 "ael.y"
+    {(yyval.pval) = (yyvsp[0].pval);;}
+    break;
+
+  case 131:
+#line 441 "ael.y"
+    { if ( (yyvsp[-1].pval) && (yyvsp[0].pval) ) {(yyval.pval)=(yyvsp[-1].pval); linku1((yyval.pval),(yyvsp[0].pval));} 
+						 else if ( (yyvsp[-1].pval) ) {(yyval.pval)=(yyvsp[-1].pval);}
+						 else if ( (yyvsp[0].pval) ) {(yyval.pval)=(yyvsp[0].pval);} ;}
+    break;
+
+  case 132:
+#line 446 "ael.y"
+    {(yyval.pval)=(yyvsp[0].pval);;}
+    break;
+
+  case 133:
+#line 447 "ael.y"
+    {(yyval.pval)=npval(PV_CATCH,(yylsp[-4]).first_line,(yylsp[0]).last_line, (yylsp[-4]).first_column, (yylsp[0]).last_column); (yyval.pval)->u1.str = (yyvsp[-3].str); (yyval.pval)->u2.statements = (yyvsp[-1].pval);;}
+    break;
+
+  case 134:
+#line 450 "ael.y"
+    {(yyval.pval)= npval(PV_SWITCHES,(yylsp[-3]).first_line,(yylsp[0]).last_line, (yylsp[-3]).first_column, (yylsp[0]).last_column); (yyval.pval)->u1.list = (yyvsp[-1].pval); ;}
+    break;
+
+  case 135:
+#line 451 "ael.y"
+    {(yyval.pval)= npval(PV_SWITCHES,(yylsp[-2]).first_line,(yylsp[0]).last_line, (yylsp[-2]).first_column, (yylsp[0]).last_column);;}
+    break;
+
+  case 136:
+#line 454 "ael.y"
+    {(yyval.pval)= npval(PV_ESWITCHES,(yylsp[-3]).first_line,(yylsp[0]).last_line, (yylsp[-3]).first_column, (yylsp[0]).last_column); (yyval.pval)->u1.list = (yyvsp[-1].pval); ;}
+    break;
+
+  case 137:
+#line 455 "ael.y"
+    {(yyval.pval)= npval(PV_ESWITCHES,(yylsp[-2]).first_line,(yylsp[0]).last_line, (yylsp[-2]).first_column, (yylsp[0]).last_column); ;}
+    break;
+
+  case 138:
+#line 458 "ael.y"
+    {(yyval.pval)=npval(PV_WORD,(yylsp[-1]).first_line,(yylsp[0]).last_line, (yylsp[-1]).first_column, (yylsp[0]).last_column); (yyval.pval)->u1.str = (yyvsp[-1].str);;}
+    break;
+
+  case 139:
+#line 459 "ael.y"
+    {pval *z = npval(PV_WORD,(yylsp[-1]).first_line,(yylsp[0]).last_line, (yylsp[-1]).first_column, (yylsp[0]).last_column); (yyval.pval)=(yyvsp[-2].pval); z->u1.str = (yyvsp[-1].str); linku1((yyval.pval),z); ;}
+    break;
+
+  case 140:
+#line 460 "ael.y"
+    {(yyval.pval)=(yyvsp[-1].pval);;}
+    break;
+
+  case 141:
+#line 463 "ael.y"
+    {(yyval.pval)=npval(PV_WORD,(yylsp[-1]).first_line,(yylsp[0]).last_line, (yylsp[-1]).first_column, (yylsp[0]).last_column); (yyval.pval)->u1.str = (yyvsp[-1].str);;}
+    break;
+
+  case 142:
+#line 464 "ael.y"
+    {
+                    (yyval.pval)=npval(PV_WORD,(yylsp[-13]).first_line,(yylsp[-12]).last_line, (yylsp[-13]).first_column, (yylsp[-12]).last_column); 
+                    (yyval.pval)->u1.str = (yyvsp[-13].str);
+					(yyval.pval)->u2.arglist = npval(PV_WORD,(yylsp[-11]).first_line,(yylsp[-7]).last_line, (yylsp[-11]).first_column, (yylsp[-7]).last_column); 
+					(yyval.pval)->u2.arglist->u1.str = (char*)malloc(strlen((yyvsp[-11].str))+strlen((yyvsp[-9].str))+strlen((yyvsp[-7].str))+4);
+					strcpy((yyval.pval)->u2.arglist->u1.str,(yyvsp[-11].str));
+					strcat((yyval.pval)->u2.arglist->u1.str,":");
+					strcat((yyval.pval)->u2.arglist->u1.str,(yyvsp[-9].str));
+					strcat((yyval.pval)->u2.arglist->u1.str,":");
+					strcat((yyval.pval)->u2.arglist->u1.str,(yyvsp[-7].str));
+					free((yyvsp[-11].str));
+					free((yyvsp[-9].str));
+					free((yyvsp[-7].str));
+					(yyval.pval)->u2.arglist->next = npval(PV_WORD,(yylsp[-5]).first_line,(yylsp[-5]).last_line, (yylsp[-5]).first_column, (yylsp[-5]).last_column); 
+					(yyval.pval)->u2.arglist->next->u1.str = (yyvsp[-5].str); 
+					(yyval.pval)->u2.arglist->next->next = npval(PV_WORD,(yylsp[-3]).first_line,(yylsp[-3]).last_line, (yylsp[-3]).first_column, (yylsp[-3]).last_column); 
+					(yyval.pval)->u2.arglist->next->next->u1.str = (yyvsp[-3].str); 
+					(yyval.pval)->u2.arglist->next->next->next = npval(PV_WORD,(yylsp[-1]).first_line,(yylsp[-1]).last_line, (yylsp[-1]).first_column, (yylsp[-1]).last_column); 
+					(yyval.pval)->u2.arglist->next->next->next->u1.str = (yyvsp[-1].str); 
+					prev_word=0;
+			;}
+    break;
+
+  case 143:
+#line 485 "ael.y"
+    {
+                    (yyval.pval)=npval(PV_WORD,(yylsp[-9]).first_line,(yylsp[-8]).last_line, (yylsp[-9]).first_column, (yylsp[-8]).last_column); 
+                    (yyval.pval)->u1.str = (yyvsp[-9].str);
+					(yyval.pval)->u2.arglist = npval(PV_WORD,(yylsp[-7]).first_line,(yylsp[-7]).last_line, (yylsp[-7]).first_column, (yylsp[-7]).last_column); 
+					(yyval.pval)->u2.arglist->u1.str = (yyvsp[-7].str);
+					(yyval.pval)->u2.arglist->next = npval(PV_WORD,(yylsp[-5]).first_line,(yylsp[-5]).last_line, (yylsp[-5]).first_column, (yylsp[-5]).last_column); 
+					(yyval.pval)->u2.arglist->next->u1.str = (yyvsp[-5].str); 
+					(yyval.pval)->u2.arglist->next->next = npval(PV_WORD,(yylsp[-3]).first_line,(yylsp[-3]).last_line, (yylsp[-3]).first_column, (yylsp[-3]).last_column); 
+					(yyval.pval)->u2.arglist->next->next->u1.str = (yyvsp[-3].str); 
+					(yyval.pval)->u2.arglist->next->next->next = npval(PV_WORD,(yylsp[-1]).first_line,(yylsp[-1]).last_line, (yylsp[-1]).first_column, (yylsp[-1]).last_column); 
+					(yyval.pval)->u2.arglist->next->next->next->u1.str = (yyvsp[-1].str); 
+					prev_word=0;
+			;}
+    break;
+
+  case 144:
+#line 498 "ael.y"
+    {pval *z = npval(PV_WORD,(yylsp[-1]).first_line,(yylsp[0]).last_line, (yylsp[-1]).first_column, (yylsp[0]).last_column); (yyval.pval)=(yyvsp[-2].pval); z->u1.str = (yyvsp[-1].str); linku1((yyval.pval),z); ;}
+    break;
+
+  case 145:
+#line 499 "ael.y"
+    {pval *z = npval(PV_WORD,(yylsp[-13]).first_line,(yylsp[-12]).last_line, (yylsp[-13]).first_column, (yylsp[-12]).last_column); 
+					(yyval.pval)=(yyvsp[-14].pval); z->u1.str = (yyvsp[-13].str); linku1((yyval.pval),z);
+					z->u2.arglist = npval(PV_WORD,(yylsp[-11]).first_line,(yylsp[-11]).last_line, (yylsp[-11]).first_column, (yylsp[-11]).last_column); 
+					(yyval.pval)->u2.arglist->u1.str = (char*)malloc(strlen((yyvsp[-11].str))+strlen((yyvsp[-9].str))+strlen((yyvsp[-7].str))+4);
+					strcpy((yyval.pval)->u2.arglist->u1.str,(yyvsp[-11].str));
+					strcat((yyval.pval)->u2.arglist->u1.str,":");
+					strcat((yyval.pval)->u2.arglist->u1.str,(yyvsp[-9].str));
+					strcat((yyval.pval)->u2.arglist->u1.str,":");
+					strcat((yyval.pval)->u2.arglist->u1.str,(yyvsp[-7].str));
+					free((yyvsp[-11].str));
+					free((yyvsp[-9].str));
+					free((yyvsp[-7].str));
+					z->u2.arglist->next = npval(PV_WORD,(yylsp[-5]).first_line,(yylsp[-5]).last_line, (yylsp[-5]).first_column, (yylsp[-5]).last_column); 
+					z->u2.arglist->next->u1.str = (yyvsp[-5].str); 
+					z->u2.arglist->next->next = npval(PV_WORD,(yylsp[-3]).first_line,(yylsp[-3]).last_line, (yylsp[-3]).first_column, (yylsp[-3]).last_column); 
+					z->u2.arglist->next->next->u1.str = (yyvsp[-3].str); 
+					z->u2.arglist->next->next->next = npval(PV_WORD,(yylsp[-1]).first_line,(yylsp[-1]).last_line, (yylsp[-1]).first_column, (yylsp[-1]).last_column); 
+					z->u2.arglist->next->next->next->u1.str = (yyvsp[-1].str); 
+					prev_word=0;
+			;}
+    break;
+
+  case 146:
+#line 520 "ael.y"
+    {pval *z = npval(PV_WORD,(yylsp[-9]).first_line,(yylsp[-9]).last_line, (yylsp[-9]).first_column, (yylsp[-8]).last_column);
+					(yyval.pval)=(yyvsp[-10].pval); z->u1.str = (yyvsp[-9].str); linku1((yyval.pval),z);
+					z->u2.arglist = npval(PV_WORD,(yylsp[-7]).first_line,(yylsp[-7]).last_line, (yylsp[-7]).first_column, (yylsp[-7]).last_column);
+					(yyval.pval)->u2.arglist->u1.str = (yyvsp[-7].str);
+					z->u2.arglist->next = npval(PV_WORD,(yylsp[-5]).first_line,(yylsp[-5]).last_line, (yylsp[-5]).first_column, (yylsp[-5]).last_column);
+					z->u2.arglist->next->u1.str = (yyvsp[-5].str);
+					z->u2.arglist->next->next = npval(PV_WORD,(yylsp[-3]).first_line,(yylsp[-3]).last_line, (yylsp[-3]).first_column, (yylsp[-3]).last_column);
+					z->u2.arglist->next->next->u1.str = (yyvsp[-3].str);
+					z->u2.arglist->next->next->next = npval(PV_WORD,(yylsp[-1]).first_line,(yylsp[-1]).last_line, (yylsp[-1]).first_column, (yylsp[-1]).last_column);
+					z->u2.arglist->next->next->next->u1.str = (yyvsp[-1].str);
+					prev_word=0;
+			;}
+    break;
+
+  case 147:
+#line 532 "ael.y"
+    {(yyval.pval)=(yyvsp[-1].pval);;}
+    break;
+
+  case 148:
+#line 535 "ael.y"
+    { (yyval.str) = (yyvsp[0].str);;}
+    break;
+
+  case 149:
+#line 536 "ael.y"
+    {(yyval.str)=strdup("default");;}
+    break;
+
+  case 150:
+#line 539 "ael.y"
+    {(yyval.pval)= npval(PV_INCLUDES,(yylsp[-3]).first_line,(yylsp[0]).last_line, (yylsp[-3]).first_column, (yylsp[0]).last_column); (yyval.pval)->u1.list = (yyvsp[-1].pval);;}
+    break;
+
+  case 151:
+#line 540 "ael.y"
+    {(yyval.pval)= npval(PV_INCLUDES,(yylsp[-2]).first_line,(yylsp[0]).last_line, (yylsp[-2]).first_column, (yylsp[0]).last_column);;}
+    break;
+
+
+      default: break;
+    }
+
+/* Line 1126 of yacc.c.  */
+#line 2755 "ael.tab.c"
+
+  yyvsp -= yylen;
+  yyssp -= yylen;
+  yylsp -= yylen;
+
+  YY_STACK_PRINT (yyss, yyssp);
+
+  *++yyvsp = yyval;
+  *++yylsp = yyloc;
+
+  /* Now `shift' the result of the reduction.  Determine what state
+     that goes to, based on the state we popped back to and the rule
+     number reduced by.  */
+
+  yyn = yyr1[yyn];
+
+  yystate = yypgoto[yyn - YYNTOKENS] + *yyssp;
+  if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp)
+    yystate = yytable[yystate];
+  else
+    yystate = yydefgoto[yyn - YYNTOKENS];
+
+  goto yynewstate;
+
+
+/*------------------------------------.
+| yyerrlab -- here on detecting error |
+`------------------------------------*/
+yyerrlab:
+  /* If not already recovering from an error, report this error.  */
+  if (!yyerrstatus)
+    {
+      ++yynerrs;
+#if YYERROR_VERBOSE
+      yyn = yypact[yystate];
+
+      if (YYPACT_NINF < yyn && yyn < YYLAST)
+	{
+	  int yytype = YYTRANSLATE (yychar);
+	  YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]);
+	  YYSIZE_T yysize = yysize0;
+	  YYSIZE_T yysize1;
+	  int yysize_overflow = 0;
+	  char *yymsg = 0;
+#	  define YYERROR_VERBOSE_ARGS_MAXIMUM 5
+	  char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
+	  int yyx;
+
+#if 0
+	  /* This is so xgettext sees the translatable formats that are
+	     constructed on the fly.  */
+	  YY_("syntax error, unexpected %s");
+	  YY_("syntax error, unexpected %s, expecting %s");
+	  YY_("syntax error, unexpected %s, expecting %s or %s");
+	  YY_("syntax error, unexpected %s, expecting %s or %s or %s");
+	  YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s");
+#endif
+	  char *yyfmt;
+	  char const *yyf;
+	  static char const yyunexpected[] = "syntax error, unexpected %s";
+	  static char const yyexpecting[] = ", expecting %s";
+	  static char const yyor[] = " or %s";
+	  char yyformat[sizeof yyunexpected
+			+ sizeof yyexpecting - 1
+			+ ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2)
+			   * (sizeof yyor - 1))];
+	  char const *yyprefix = yyexpecting;
+
+	  /* Start YYX at -YYN if negative to avoid negative indexes in
+	     YYCHECK.  */
+	  int yyxbegin = yyn < 0 ? -yyn : 0;
+
+	  /* Stay within bounds of both yycheck and yytname.  */
+	  int yychecklim = YYLAST - yyn;
+	  int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
+	  int yycount = 1;
+
+	  yyarg[0] = yytname[yytype];
+	  yyfmt = yystpcpy (yyformat, yyunexpected);
+
+	  for (yyx = yyxbegin; yyx < yyxend; ++yyx)
+	    if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
+	      {
+		if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
+		  {
+		    yycount = 1;
+		    yysize = yysize0;
+		    yyformat[sizeof yyunexpected - 1] = '\0';
+		    break;
+		  }
+		yyarg[yycount++] = yytname[yyx];
+		yysize1 = yysize + yytnamerr (0, yytname[yyx]);
+		yysize_overflow |= yysize1 < yysize;
+		yysize = yysize1;
+		yyfmt = yystpcpy (yyfmt, yyprefix);
+		yyprefix = yyor;
+	      }
+
+	  yyf = YY_(yyformat);
+	  yysize1 = yysize + yystrlen (yyf);
+	  yysize_overflow |= yysize1 < yysize;
+	  yysize = yysize1;
+
+	  if (!yysize_overflow && yysize <= YYSTACK_ALLOC_MAXIMUM)
+	    yymsg = (char *) YYSTACK_ALLOC (yysize);
+	  if (yymsg)
+	    {
+	      /* Avoid sprintf, as that infringes on the user's name space.
+		 Don't have undefined behavior even if the translation
+		 produced a string with the wrong number of "%s"s.  */
+	      char *yyp = yymsg;
+	      int yyi = 0;
+	      while ((*yyp = *yyf))
+		{
+		  if (*yyp == '%' && yyf[1] == 's' && yyi < yycount)
+		    {
+		      yyp += yytnamerr (yyp, yyarg[yyi++]);
+		      yyf += 2;
+		    }
+		  else
+		    {
+		      yyp++;
+		      yyf++;
+		    }
+		}
+	      yyerror (&yylloc, parseio, yymsg);
+	      YYSTACK_FREE (yymsg);
+	    }
+	  else
+	    {
+	      yyerror (&yylloc, parseio, YY_("syntax error"));
+	      goto yyexhaustedlab;
+	    }
+	}
+      else
+#endif /* YYERROR_VERBOSE */
+	yyerror (&yylloc, parseio, YY_("syntax error"));
+    }
+
+  yyerror_range[0] = yylloc;
+
+  if (yyerrstatus == 3)
+    {
+      /* If just tried and failed to reuse look-ahead token after an
+	 error, discard it.  */
+
+      if (yychar <= YYEOF)
+        {
+	  /* Return failure if at end of input.  */
+	  if (yychar == YYEOF)
+	    YYABORT;
+        }
+      else
+	{
+	  yydestruct ("Error: discarding", yytoken, &yylval, &yylloc);
+	  yychar = YYEMPTY;
+	}
+    }
+
+  /* Else will try to reuse look-ahead token after shifting the error
+     token.  */
+  goto yyerrlab1;
+
+
+/*---------------------------------------------------.
+| yyerrorlab -- error raised explicitly by YYERROR.  |
+`---------------------------------------------------*/
+yyerrorlab:
+
+  /* Pacify compilers like GCC when the user code never invokes
+     YYERROR and the label yyerrorlab therefore never appears in user
+     code.  */
+  if (0)
+     goto yyerrorlab;
+
+  yyerror_range[0] = yylsp[1-yylen];
+  yylsp -= yylen;
+  yyvsp -= yylen;
+  yyssp -= yylen;
+  yystate = *yyssp;
+  goto yyerrlab1;
+
+
+/*-------------------------------------------------------------.
+| yyerrlab1 -- common code for both syntax error and YYERROR.  |
+`-------------------------------------------------------------*/
+yyerrlab1:
+  yyerrstatus = 3;	/* Each real token shifted decrements this.  */
+
+  for (;;)
+    {
+      yyn = yypact[yystate];
+      if (yyn != YYPACT_NINF)
+	{
+	  yyn += YYTERROR;
+	  if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
+	    {
+	      yyn = yytable[yyn];
+	      if (0 < yyn)
+		break;
+	    }
+	}
+
+      /* Pop the current state because it cannot handle the error token.  */
+      if (yyssp == yyss)
+	YYABORT;
+
+      yyerror_range[0] = *yylsp;
+      yydestruct ("Error: popping", yystos[yystate], yyvsp, yylsp);
+      YYPOPSTACK;
+      yystate = *yyssp;
+      YY_STACK_PRINT (yyss, yyssp);
+    }
+
+  if (yyn == YYFINAL)
+    YYACCEPT;
+
+  *++yyvsp = yylval;
+
+  yyerror_range[1] = yylloc;
+  /* Using YYLLOC is tempting, but would change the location of
+     the look-ahead.  YYLOC is available though. */
+  YYLLOC_DEFAULT (yyloc, yyerror_range - 1, 2);
+  *++yylsp = yyloc;
+
+  /* Shift the error token. */
+  YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp);
+
+  yystate = yyn;
+  goto yynewstate;
+
+
+/*-------------------------------------.
+| yyacceptlab -- YYACCEPT comes here.  |
+`-------------------------------------*/
+yyacceptlab:
+  yyresult = 0;
+  goto yyreturn;
+
+/*-----------------------------------.
+| yyabortlab -- YYABORT comes here.  |
+`-----------------------------------*/
+yyabortlab:
+  yyresult = 1;
+  goto yyreturn;
+
+#ifndef yyoverflow
+/*-------------------------------------------------.
+| yyexhaustedlab -- memory exhaustion comes here.  |
+`-------------------------------------------------*/
+yyexhaustedlab:
+  yyerror (&yylloc, parseio, YY_("memory exhausted"));
+  yyresult = 2;
+  /* Fall through.  */
+#endif
+
+yyreturn:
+  if (yychar != YYEOF && yychar != YYEMPTY)
+     yydestruct ("Cleanup: discarding lookahead",
+		 yytoken, &yylval, &yylloc);
+  while (yyssp != yyss)
+    {
+      yydestruct ("Cleanup: popping",
+		  yystos[*yyssp], yyvsp, yylsp);
+      YYPOPSTACK;
+    }
+#ifndef yyoverflow
+  if (yyss != yyssa)
+    YYSTACK_FREE (yyss);
+#endif
+  return yyresult;
+}
+
+
+#line 544 "ael.y"
+
+
+static char *token_equivs1[] = 
+{
+	"AMPER",
+	"AT",
+	"BAR",
+	"COLON",
+	"COMMA",
+	"EQ",
+	"EXTENMARK",
+	"KW_BREAK", 
+	"KW_CASE", 
+	"KW_CATCH", 
+	"KW_CONTEXT",
+	"KW_CONTINUE", 
+	"KW_DEFAULT", 
+	"KW_ELSE",
+	"KW_ESWITCHES",
+	"KW_FOR", 
+	"KW_GLOBALS",
+	"KW_GOTO",
+	"KW_HINT",
+	"KW_IFTIME",
+	"KW_IF",
+	"KW_IGNOREPAT",
+	"KW_INCLUDES"
+	"KW_JUMP",
+	"KW_MACRO",
+	"KW_PATTERN", 
+	"KW_REGEXTEN", 
+	"KW_RETURN", 
+	"KW_SWITCHES", 
+	"KW_SWITCH",
+	"KW_WHILE", 
+	"LC",
+	"LP",
+	"RC",
+	"RP",
+	"SEMI",
+};
+
+static char *token_equivs2[] = 
+{
+	"&",
+	"@",
+	"|",
+	":",
+	",",
+	"=",
+	"=>",
+	"break", 
+	"case", 
+	"catch", 
+	"context",
+	"continue", 
+	"default", 
+	"else",
+	"eswitches",
+	"for", 
+	"globals",
+	"goto",
+	"hint",
+	"ifTime",
+	"if",
+	"ignorepat",
+	"includes"
+	"jump",
+	"macro",
+	"pattern", 
+	"regexten", 
+	"return", 
+	"switches", 
+	"switch",
+	"while", 
+	"{",
+	"(",
+	"}",
+	")",
+	";",
+};
+
+
+static char *ael_token_subst(char *mess)
+{
+	/* calc a length, malloc, fill, and return; yyerror had better free it! */
+	int len=0,i;
+	char *p;
+	char *res, *s,*t;
+	int token_equivs_entries = sizeof(token_equivs1)/sizeof(char*);
+
+	for (p=mess; *p; p++) {
+		for (i=0; i<token_equivs_entries; i++) {
+			if ( strncmp(p,token_equivs1[i],strlen(token_equivs1[i])) == 0 )
+			{
+				len+=strlen(token_equivs2[i])+2;
+				p += strlen(token_equivs1[i])-1;
+				break;
+			}
+		}
+		len++;
+	}
+	res = (char*)malloc(len+1);
+	res[0] = 0;
+	s = res;
+	for (p=mess; *p;) {
+		int found = 0;
+		for (i=0; i<token_equivs_entries; i++) {
+			if ( strncmp(p,token_equivs1[i],strlen(token_equivs1[i])) == 0 ) {
+				*s++ = '\'';
+				for (t=token_equivs2[i]; *t;) {
+					*s++ = *t++;
+				}
+				*s++ = '\'';
+				p += strlen(token_equivs1[i]);
+				found = 1;
+				break;
+			}
+		}
+		if( !found )
+			*s++ = *p++;
+	}
+	*s++ = 0;
+	return res;
+}
+
+void yyerror(YYLTYPE *locp, struct parse_io *parseio,  char const *s)
+{
+	char *s2 = ael_token_subst((char *)s);
+	if (locp->first_line == locp->last_line) {
+		ast_log(LOG_ERROR, "==== File: %s, Line %d, Cols: %d-%d: Error: %s\n", my_file, locp->first_line, locp->first_column, locp->last_column, s2);
+	} else {
+		ast_log(LOG_ERROR, "==== File: %s, Line %d Col %d  to Line %d Col %d: Error: %s\n", my_file, locp->first_line, locp->first_column, locp->last_line, locp->last_column, s2);
+	}
+	free(s2);
+	parseio->syntax_error_count++;
+}
+
+struct pval *npval(pvaltype type,int first_line, int last_line, int first_column, int last_column)
+{
+	extern char *my_file;
+	pval *z = (pval *)calloc(sizeof(struct pval),1);
+	z->type = type;
+	z->startline = first_line;
+	z->endline = last_line;
+	z->startcol = first_column;
+	z->endcol = last_column;
+	z->filename = strdup(my_file);
+	return z;
+}
+
+void linku1(pval *head, pval *tail)
+{
+	if (!head->next) {
+		head->next = tail;
+		head->u1_last = tail;
+	} else {
+		head->u1_last->next = tail;
+		head->u1_last = tail;
+	}
+}
+
+
diff --git a/pbx/ael/ael.tab.h b/pbx/ael/ael.tab.h
new file mode 100644
index 0000000000..48459ee7ce
--- /dev/null
+++ b/pbx/ael/ael.tab.h
@@ -0,0 +1,147 @@
+/* A Bison parser, made by GNU Bison 2.1.  */
+
+/* Skeleton parser for Yacc-like parsing with Bison,
+   Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street, Fifth Floor,
+   Boston, MA 02110-1301, USA.  */
+
+/* As a special exception, when this file is copied by Bison into a
+   Bison output file, you may use that output file without restriction.
+   This special exception was added by the Free Software Foundation
+   in version 1.24 of Bison.  */
+
+/* Tokens.  */
+#ifndef YYTOKENTYPE
+# define YYTOKENTYPE
+   /* Put the tokens into the symbol table, so that GDB and other debuggers
+      know about them.  */
+   enum yytokentype {
+     KW_CONTEXT = 258,
+     LC = 259,
+     RC = 260,
+     LP = 261,
+     RP = 262,
+     SEMI = 263,
+     EQ = 264,
+     COMMA = 265,
+     COLON = 266,
+     AMPER = 267,
+     BAR = 268,
+     AT = 269,
+     KW_MACRO = 270,
+     KW_GLOBALS = 271,
+     KW_IGNOREPAT = 272,
+     KW_SWITCH = 273,
+     KW_IF = 274,
+     KW_IFTIME = 275,
+     KW_ELSE = 276,
+     KW_RANDOM = 277,
+     KW_ABSTRACT = 278,
+     EXTENMARK = 279,
+     KW_GOTO = 280,
+     KW_JUMP = 281,
+     KW_RETURN = 282,
+     KW_BREAK = 283,
+     KW_CONTINUE = 284,
+     KW_REGEXTEN = 285,
+     KW_HINT = 286,
+     KW_FOR = 287,
+     KW_WHILE = 288,
+     KW_CASE = 289,
+     KW_PATTERN = 290,
+     KW_DEFAULT = 291,
+     KW_CATCH = 292,
+     KW_SWITCHES = 293,
+     KW_ESWITCHES = 294,
+     KW_INCLUDES = 295,
+     word = 296
+   };
+#endif
+/* Tokens.  */
+#define KW_CONTEXT 258
+#define LC 259
+#define RC 260
+#define LP 261
+#define RP 262
+#define SEMI 263
+#define EQ 264
+#define COMMA 265
+#define COLON 266
+#define AMPER 267
+#define BAR 268
+#define AT 269
+#define KW_MACRO 270
+#define KW_GLOBALS 271
+#define KW_IGNOREPAT 272
+#define KW_SWITCH 273
+#define KW_IF 274
+#define KW_IFTIME 275
+#define KW_ELSE 276
+#define KW_RANDOM 277
+#define KW_ABSTRACT 278
+#define EXTENMARK 279
+#define KW_GOTO 280
+#define KW_JUMP 281
+#define KW_RETURN 282
+#define KW_BREAK 283
+#define KW_CONTINUE 284
+#define KW_REGEXTEN 285
+#define KW_HINT 286
+#define KW_FOR 287
+#define KW_WHILE 288
+#define KW_CASE 289
+#define KW_PATTERN 290
+#define KW_DEFAULT 291
+#define KW_CATCH 292
+#define KW_SWITCHES 293
+#define KW_ESWITCHES 294
+#define KW_INCLUDES 295
+#define word 296
+
+
+
+
+#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED)
+#line 47 "ael.y"
+typedef union YYSTYPE {
+	char *str;
+	struct pval *pval;
+} YYSTYPE;
+/* Line 1447 of yacc.c.  */
+#line 125 "ael.tab.h"
+# define yystype YYSTYPE /* obsolescent; will be withdrawn */
+# define YYSTYPE_IS_DECLARED 1
+# define YYSTYPE_IS_TRIVIAL 1
+#endif
+
+
+
+#if ! defined (YYLTYPE) && ! defined (YYLTYPE_IS_DECLARED)
+typedef struct YYLTYPE
+{
+  int first_line;
+  int first_column;
+  int last_line;
+  int last_column;
+} YYLTYPE;
+# define yyltype YYLTYPE /* obsolescent; will be withdrawn */
+# define YYLTYPE_IS_DECLARED 1
+# define YYLTYPE_IS_TRIVIAL 1
+#endif
+
+
+
+
diff --git a/pbx/ael/ael.y b/pbx/ael/ael.y
new file mode 100644
index 0000000000..5a9d9805a0
--- /dev/null
+++ b/pbx/ael/ael.y
@@ -0,0 +1,705 @@
+%{
+/*
+ * Asterisk -- An open source telephony toolkit. 
+ *
+ * Copyright (C) 2006, Digium, Inc.
+ *
+ * Steve Murphy <murf@parsetree.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+/*! \file
+ *
+ * \brief Bison Grammar description of AEL2.
+ * 
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "asterisk/logger.h"
+#include "asterisk/ael_structs.h"
+
+extern void reset_parencount(yyscan_t yyscanner);
+extern void reset_semicount(yyscan_t yyscanner);
+extern void reset_argcount(yyscan_t yyscanner );
+
+#define YYLEX_PARAM ((struct parse_io *)parseio)->scanner
+#define YYERROR_VERBOSE 1
+
+extern char *my_file;
+#ifdef AAL_ARGCHECK
+int ael_is_funcname(char *name);
+#endif
+ static char *ael_token_subst(char *mess);
+ extern char *prev_word;
+ 
+%}
+
+
+%union {
+	char *str;
+	struct pval *pval;
+}
+
+%{
+	/* declaring these AFTER the union makes things a lot simpler! */
+void yyerror(YYLTYPE *locp, struct parse_io *parseio, char const *s);
+int ael_yylex (YYSTYPE * yylval_param, YYLTYPE * yylloc_param , void * yyscanner);
+	
+%}
+
+ 
+%token KW_CONTEXT LC RC LP RP SEMI EQ COMMA COLON AMPER BAR AT
+%token KW_MACRO KW_GLOBALS KW_IGNOREPAT KW_SWITCH KW_IF KW_IFTIME KW_ELSE KW_RANDOM KW_ABSTRACT
+%token EXTENMARK KW_GOTO KW_JUMP KW_RETURN KW_BREAK KW_CONTINUE KW_REGEXTEN KW_HINT
+%token KW_FOR KW_WHILE KW_CASE KW_PATTERN KW_DEFAULT KW_CATCH KW_SWITCHES KW_ESWITCHES
+%token KW_INCLUDES
+
+%token <str> word
+
+%type <pval>includes
+%type <pval>includeslist
+%type <pval>switchlist
+%type <pval>eswitches
+%type <pval>switches
+%type <pval>macro_statement
+%type <pval>macro_statements
+%type <pval>case_statement
+%type <pval>case_statements
+%type <pval>eval_arglist
+%type <pval>application_call
+%type <pval>application_call_head
+%type <pval>macro_call
+%type <pval>target jumptarget
+%type <pval>statement
+%type <pval>switch_head
+%type <str>word_list goto_word
+%type <str>word3_list
+%type <str>includedname
+%type <pval>if_head
+%type <pval>random_head
+%type <pval>iftime_head
+%type <pval>statements
+%type <pval>extension
+%type <pval>ignorepat
+%type <pval>element
+%type <pval>elements
+%type <pval>arglist
+%type <pval>global_statement
+%type <pval>global_statements
+%type <pval>globals
+%type <pval>macro
+%type <pval>context
+%type <pval>object
+%type <pval>objects 
+%type <pval>file 
+
+/* OPTIONS */
+%locations
+%pure-parser
+%name-prefix="ael_yy"
+/* the following option does two things: 
+    it adds the locp arg to the yyerror
+    and it adds the NULL to the yyerrr arg list, and calls yyerror with NULL for that arg.
+    You can't get the locp arg without the NULL arg, don't ask me why. */
+%parse-param {struct parse_io *parseio}
+/* there will be two shift/reduce conflicts, they involve the if statement, where a single statement occurs not wrapped in curlies in the "true" section 
+   the default action to shift will attach the else to the preceeding if. */
+%expect 5
+%error-verbose
+%destructor { if (yymsg[0] != 'C') {destroy_pval($$); prev_word=0;} else {printf("Cleanup destructor called for pvals\n");} } includes includeslist switchlist eswitches switches macro_statement macro_statements case_statement case_statements eval_arglist application_call 
+                                application_call_head macro_call target jumptarget statement switch_head if_head random_head iftime_head statements extension ignorepat element
+                                elements arglist global_statement global_statements globals macro context object objects
+%destructor { free($$);}  word word_list goto_word word3_list includedname
+
+
+%%
+
+file : objects  { $$ = parseio->pval = $1; }
+	;
+
+objects : object {$$=$1;}
+	| objects object {if ( $1 && $2 ) {$$=$1; linku1($$,$2);} 
+						 else if ( $1 ) {$$=$1;}
+						 else if ( $2 ) {$$=$2;} }
+	| objects error {$$=$1;}
+	;
+
+object : context {$$=$1;}
+	| macro {$$=$1;}
+	| globals {$$=$1;}
+	| SEMI  {$$=0;/* allow older docs to be read */}
+	;
+
+context : KW_CONTEXT word LC elements RC {$$=npval(PV_CONTEXT,@1.first_line,@5.last_line, @1.first_column, @5.last_column); $$->u1.str = $2; $$->u2.statements = $4; }
+	| KW_CONTEXT word LC RC /* empty context OK */ {$$=npval(PV_CONTEXT,@1.first_line,@4.last_line, @1.first_column, @4.last_column); $$->u1.str = $2; }
+	| KW_CONTEXT KW_DEFAULT LC elements RC  {$$=npval(PV_CONTEXT,@1.first_line,@5.last_line, @1.first_column, @5.last_column); $$->u1.str = strdup("default"); $$->u2.statements = $4; }
+	| KW_CONTEXT KW_DEFAULT LC RC /* empty context OK */ {$$=npval(PV_CONTEXT,@1.first_line,@4.last_line, @1.first_column, @4.last_column); $$->u1.str = strdup("default"); }
+    | KW_ABSTRACT KW_CONTEXT word LC elements RC {$$=npval(PV_CONTEXT,@1.first_line,@6.last_line, @1.first_column, @6.last_column); $$->u1.str = $3; $$->u2.statements = $5;  $$->u3.abstract = 1;}
+	| KW_ABSTRACT KW_CONTEXT word LC RC /* empty context OK */ {$$=npval(PV_CONTEXT,@1.first_line,@5.last_line, @1.first_column, @5.last_column); $$->u1.str = $3; $$->u3.abstract = 1; }
+	| KW_ABSTRACT KW_CONTEXT KW_DEFAULT LC elements RC  {$$=npval(PV_CONTEXT,@1.first_line,@6.last_line, @1.first_column, @6.last_column); $$->u1.str = strdup("default"); $$->u2.statements = $5; $$->u3.abstract = 1; }
+	| KW_ABSTRACT KW_CONTEXT KW_DEFAULT LC RC /* empty context OK */ {$$=npval(PV_CONTEXT,@1.first_line,@5.last_line, @1.first_column, @5.last_column); $$->u1.str = strdup("default"); $$->u3.abstract = 1; }
+	;
+
+macro : KW_MACRO word LP arglist RP LC macro_statements RC {$$=npval(PV_MACRO,@1.first_line,@8.last_line, @1.first_column, @8.last_column); 
+																	 $$->u1.str = $2; $$->u2.arglist = $4; $$->u3.macro_statements = $7; }
+	| KW_MACRO word LP arglist RP LC  RC {$$=npval(PV_MACRO,@1.first_line,@7.last_line, @1.first_column, @7.last_column); $$->u1.str = $2; $$->u2.arglist = $4; }
+	| KW_MACRO word LP RP LC macro_statements RC {$$=npval(PV_MACRO,@1.first_line,@7.last_line, @1.first_column, @7.last_column); $$->u1.str = $2; $$->u3.macro_statements = $6; }
+	| KW_MACRO word LP RP LC  RC {$$=npval(PV_MACRO,@1.first_line,@6.last_line, @1.first_column, @6.last_column); $$->u1.str = $2; /* pretty empty! */ }
+	;
+
+globals : KW_GLOBALS LC global_statements RC {$$=npval(PV_GLOBALS,@1.first_line,@4.last_line, @1.first_column, @4.last_column); $$->u1.statements = $3;}
+	| KW_GLOBALS LC RC /* empty global is OK */ {$$=npval(PV_GLOBALS,@1.first_line,@3.last_line, @1.first_column, @3.last_column); /* and that's all */ }
+	;
+
+global_statements : global_statement {$$=$1;}
+	| global_statements global_statement {$$=$1; linku1($$,$2);}
+	| global_statements error {$$=$1;}
+	;
+
+global_statement : word EQ { reset_semicount(parseio->scanner); }  word SEMI {$$=npval(PV_VARDEC,@1.first_line,@5.last_line, @1.first_column, @5.last_column); $$->u1.str = $1;$$->u2.val = $4; }
+	;
+
+arglist : word {$$= npval(PV_WORD,@1.first_line,@1.last_line, @1.first_column, @1.last_column); $$->u1.str = $1; }
+	| arglist COMMA word {pval *z = npval(PV_WORD,@1.first_line,@3.last_line, @1.first_column, @3.last_column); z->u1.str = $3; $$=$1; linku1($$,z); }
+	| arglist error {$$=$1;}
+	;
+
+elements : element { $$=$1;}
+    | error {$$=0;}
+	| elements element { if ( $1 && $2 ) {$$=$1; linku1($$,$2);} 
+						 else if ( $1 ) {$$=$1;}
+						 else if ( $2 ) {$$=$2;} }
+	| elements error   { $$=$1;}
+	;
+
+element : extension {$$=$1;}
+	| includes {$$=$1;}
+	| switches {$$=$1;}
+	| eswitches {$$=$1;}
+	| ignorepat {$$=$1;}
+	| word EQ { reset_semicount(parseio->scanner); } word SEMI {$$=npval(PV_VARDEC,@1.first_line,@5.last_line, @1.first_column, @5.last_column); $$->u1.str = $1;$$->u2.val = $4; }
+    | word error {free($1); $$=0;}
+	| SEMI  {$$=0;/* allow older docs to be read */}
+	;
+
+ignorepat : KW_IGNOREPAT EXTENMARK word SEMI { $$=npval(PV_IGNOREPAT,@1.first_line,@4.last_line, @1.first_column, @4.last_column); $$->u1.str = $3;}
+	;
+
+extension : word EXTENMARK statement {$$ = npval(PV_EXTENSION,@1.first_line,@3.last_line, @1.first_column, @3.last_column); $$->u1.str = $1; $$->u2.statements = $3; }
+		  | KW_REGEXTEN word EXTENMARK statement {$$ = npval(PV_EXTENSION,@1.first_line,@3.last_line, @1.first_column, @4.last_column); $$->u1.str = $2; $$->u2.statements = $4; $$->u4.regexten=1;}
+		  | KW_HINT LP word3_list RP word EXTENMARK statement {$$ = npval(PV_EXTENSION,@1.first_line,@7.last_line, @1.first_column, @7.last_column); $$->u1.str = $5; $$->u2.statements = $7; $$->u3.hints = $3;}
+		  | KW_REGEXTEN KW_HINT LP word3_list RP word EXTENMARK statement {$$ = npval(PV_EXTENSION,@1.first_line,@4.last_line, @1.first_column, @8.last_column); $$->u1.str = $6; $$->u2.statements = $8; $$->u4.regexten=1;$$->u3.hints = $4;}
+
+	;
+
+statements : statement {$$=$1;}
+	| statements statement {if ( $1 && $2 ) {$$=$1; linku1($$,$2);} 
+						 else if ( $1 ) {$$=$1;}
+						 else if ( $2 ) {$$=$2;} }
+	| statements error {$$=$1;}
+	;
+
+if_head : KW_IF LP { reset_parencount(parseio->scanner); }  word_list RP { $$= npval(PV_IF,@1.first_line,@5.last_line, @1.first_column, @5.last_column); $$->u1.str = $4; }
+		;
+
+random_head : KW_RANDOM LP { reset_parencount(parseio->scanner); } word_list RP { $$= npval(PV_RANDOM,@1.first_line,@5.last_line, @1.first_column, @5.last_column); $$->u1.str=$4;}
+		;
+
+iftime_head : KW_IFTIME LP word3_list COLON word3_list COLON word3_list BAR word3_list BAR word3_list BAR word3_list RP { $$= npval(PV_IFTIME,@1.first_line,@5.last_line, @1.first_column, @5.last_column); 
+					$$->u1.list = npval(PV_WORD,@3.first_line,@3.last_line, @3.first_column, @3.last_column); 
+					$$->u1.list->u1.str = (char*)malloc(strlen($3)+strlen($5)+strlen($7)+4);
+					strcpy($$->u1.list->u1.str,$3);
+					strcat($$->u1.list->u1.str,":");
+					strcat($$->u1.list->u1.str,$5);
+					strcat($$->u1.list->u1.str,":");
+					strcat($$->u1.list->u1.str,$7);
+					free($3);
+					free($5);
+					free($7);
+					$$->u1.list->next = npval(PV_WORD,@9.first_line,@9.last_line, @9.first_column, @9.last_column); 
+					$$->u1.list->next->u1.str = $9; 
+					$$->u1.list->next->next = npval(PV_WORD,@11.first_line,@11.last_line, @11.first_column, @11.last_column); 
+					$$->u1.list->next->next->u1.str = $11; 
+					$$->u1.list->next->next->next = npval(PV_WORD,@13.first_line,@13.last_line, @13.first_column, @13.last_column); 
+					$$->u1.list->next->next->next->u1.str = $13; 
+					prev_word = 0;
+		}
+		| KW_IFTIME LP word BAR word3_list BAR word3_list BAR word3_list RP { $$= npval(PV_IFTIME,@1.first_line,@5.last_line, @1.first_column, @5.last_column); 
+					$$->u1.list = npval(PV_WORD,@3.first_line,@3.last_line, @3.first_column, @3.last_column); 
+					$$->u1.list->u1.str = $3;
+					$$->u1.list->next = npval(PV_WORD,@5.first_line,@5.last_line, @5.first_column, @5.last_column); 
+					$$->u1.list->next->u1.str = $5; 
+					$$->u1.list->next->next = npval(PV_WORD,@7.first_line,@7.last_line, @7.first_column, @7.last_column); 
+					$$->u1.list->next->next->u1.str = $7; 
+					$$->u1.list->next->next->next = npval(PV_WORD,@9.first_line,@9.last_line, @9.first_column, @9.last_column); 
+					$$->u1.list->next->next->next->u1.str = $9; 
+					prev_word = 0;
+		}
+
+	;
+
+/* word_list is a hack to fix a problem with context switching between bison and flex;
+   by the time you register a new context with flex, you've already got a look-ahead token 
+   from the old context, with no way to put it back and start afresh. So, we kludge this
+   and merge the words back together. */
+
+word_list : word { $$ = $1;}  
+	| word word { $$ = (char*)malloc(strlen($1)+strlen($2)+1); strcpy($$, $1); strcat($$, $2);  free($1); free($2);prev_word = $$;}
+	;
+word3_list : word { $$ = $1;}  
+	| word word { $$ = (char*)malloc(strlen($1)+strlen($2)+1); strcpy($$, $1); strcat($$, $2);  free($1); free($2);prev_word = $$;}
+	| word word word { $$ = (char*)malloc(strlen($1)+strlen($2)+strlen($3)+1); strcpy($$, $1); strcat($$, $2);  strcat($$, $3);  free($1); free($2); free($3);prev_word=$$;}
+	;
+
+goto_word : word { $$ = $1;}
+	| word word { $$ = (char*)malloc(strlen($1)+strlen($2)+1); strcpy($$, $1); strcat($$, $2);  free($1); free($2);}
+	| word COLON word { $$ = (char*)malloc(strlen($1)+strlen($3)+2); strcpy($$, $1); strcat($$,":"); strcat($$, $3);  free($1); free($3);}
+	;
+
+switch_head : KW_SWITCH LP { reset_parencount(parseio->scanner); } word RP  LC 
+					{$$=npval(PV_SWITCH,@1.first_line,@6.last_line, @1.first_column, @6.last_column);
+						$$->u1.str = $4; }
+	;
+
+statement : LC statements RC {$$=npval(PV_STATEMENTBLOCK,@1.first_line,@3.last_line, @1.first_column, @3.last_column); $$->u1.list = $2; }
+	| word EQ {reset_semicount(parseio->scanner);} word SEMI 
+			{$$=npval(PV_VARDEC,@1.first_line,@5.last_line, @1.first_column, @5.last_column); 
+				$$->u1.str = $1; $$->u2.val = $4; }
+	| KW_GOTO target SEMI {$$=npval(PV_GOTO,@1.first_line,@3.last_line, @1.first_column, @3.last_column); $$->u1.list = $2;}
+    | KW_JUMP jumptarget SEMI {$$=npval(PV_GOTO,@1.first_line,@3.last_line, @1.first_column, @3.last_column); $$->u1.list = $2;}
+	| word COLON {$$=npval(PV_LABEL,@1.first_line,@2.last_line, @1.first_column, @2.last_column); $$->u1.str = $1; }
+	| KW_FOR LP {reset_semicount(parseio->scanner);} word SEMI
+			{reset_semicount(parseio->scanner);} word SEMI
+			{reset_parencount(parseio->scanner);} word RP statement 
+				{ $$=npval(PV_FOR,@1.first_line,@12.last_line, @1.first_column, @12.last_column); 
+						$$->u1.for_init = $4; $$->u2.for_test=$7; $$->u3.for_inc = $10; $$->u4.for_statements = $12;}
+	| KW_WHILE LP {reset_parencount(parseio->scanner);} word RP statement 
+			{$$=npval(PV_WHILE,@1.first_line,@6.last_line, @1.first_column, @6.last_column); 
+					$$->u1.str = $4; $$->u2.statements = $6; }
+	| switch_head RC /* empty list OK */ {$$=$1;$$->endline = @2.last_line; $$->endcol = @2.last_column;}
+	| switch_head case_statements RC {$$=$1; $$->u2.statements = $2;$$->endline = @3.last_line; $$->endcol = @3.last_column;}
+	| AMPER macro_call SEMI {$$ = $2;$$->endline = @2.last_line; $$->endcol = @2.last_column;}
+	| application_call SEMI { $$ = $1;$$->endline = @2.last_line; $$->endcol = @2.last_column;}
+    | word SEMI { $$= npval(PV_APPLICATION_CALL,@1.first_line,@2.last_line, @1.first_column, @2.last_column); 
+																						$$->u1.str = $1;}
+	| application_call EQ {reset_semicount(parseio->scanner);} word SEMI {
+                          char *bufx;
+						  int tot=0;
+						  pval *pptr;
+						  
+                          $$ = npval(PV_VARDEC,@1.first_line,@5.last_line, @1.first_column, @5.last_column);
+						  $$->u2.val=$4;
+						  /* rebuild the original string-- this is not an app call, it's an unwrapped vardec, with a func call on the LHS */
+                          /* string to big to fit in the buffer? */
+						  tot+=strlen($1->u1.str);
+						  for(pptr=$1->u2.arglist;pptr;pptr=pptr->next) {
+							  tot+=strlen(pptr->u1.str);
+							  tot++; /* for a sep like a comma */
+						  }
+						  tot+=4; /* for safety */
+						  bufx = (char *)malloc(tot);
+						  strcpy(bufx,$1->u1.str);
+						  strcat(bufx,"(");
+						  for (pptr=$1->u2.arglist;pptr;pptr=pptr->next) {
+							  if ( pptr != $1->u2.arglist )
+								  strcat(bufx,",");
+							  strcat(bufx,pptr->u1.str);
+						  }
+						  strcat(bufx,")");
+#ifdef AAL_ARGCHECK
+						  if ( !ael_is_funcname($1->u1.str) )
+                              ast_log(LOG_WARNING, "==== File: %s, Line %d, Cols: %d-%d: Function call? The name %s is not in my internal list of function names\n", 
+									  my_file, @1.first_line, @1.first_column, @1.last_column, $1->u1.str);
+#endif
+						  $$->u1.str = bufx;
+						  destroy_pval($1); /* the app call it is not, get rid of that chain */
+						  prev_word = 0;
+                       }
+	| KW_BREAK SEMI { $$ = npval(PV_BREAK,@1.first_line,@2.last_line, @1.first_column, @2.last_column);}
+	| KW_RETURN SEMI {$$ = npval(PV_RETURN,@1.first_line,@2.last_line, @1.first_column, @2.last_column);}
+	| KW_CONTINUE SEMI {$$ = npval(PV_CONTINUE,@1.first_line,@2.last_line, @1.first_column, @2.last_column);}
+	| random_head statement {$$=$1; $$->u2.statements = $2;$$->endline = @2.last_line; $$->endcol = @2.last_column;}
+	| random_head statement KW_ELSE statement {$$=$1; $$->u2.statements = $2;$$->endline = @2.last_line; $$->endcol = @2.last_column; $$->u3.else_statements = $4;}
+	| if_head statement {$$=$1; $$->u2.statements = $2;$$->endline = @2.last_line; $$->endcol = @2.last_column;}
+	| if_head statement KW_ELSE statement {$$=$1; $$->u2.statements = $2;$$->endline = @2.last_line; $$->endcol = @2.last_column; $$->u3.else_statements = $4;}
+	| iftime_head statement {$$=$1; $$->u2.statements = $2;$$->endline = @2.last_line; $$->endcol = @2.last_column;}
+	| iftime_head statement KW_ELSE statement {$$=$1; $$->u2.statements = $2;$$->endline = @2.last_line; $$->endcol = @2.last_column; $$->u3.else_statements = $4;}
+	| SEMI { $$=0; }
+	;
+
+target : goto_word { $$ = npval(PV_WORD,@1.first_line,@1.last_line, @1.first_column, @1.last_column); $$->u1.str = $1;}
+	| goto_word BAR goto_word {$$=npval(PV_WORD,@1.first_line,@1.last_line, @1.first_column, @1.last_column); 
+					$$->u1.str = $1; $$->next = npval(PV_WORD,@3.first_line,@3.last_line, @3.first_column, @3.last_column); 
+					$$->next->u1.str = $3;}
+	| goto_word COMMA goto_word {$$=npval(PV_WORD,@1.first_line,@1.last_line, @1.first_column, @1.last_column); 
+					$$->u1.str = $1; $$->next = npval(PV_WORD,@3.first_line,@3.last_line, @3.first_column, @3.last_column); 
+					$$->next->u1.str = $3;}
+	| goto_word BAR goto_word BAR goto_word {$$=npval(PV_WORD,@1.first_line,@1.last_line, @1.first_column, @1.last_column); 
+					$$->u1.str = $1; $$->next = npval(PV_WORD,@3.first_line,@3.last_line, @3.first_column, @3.last_column); 
+					$$->next->u1.str = $3; 
+					$$->next->next = npval(PV_WORD,@5.first_line,@5.last_line, @5.first_column, @5.last_column); 
+					$$->next->next->u1.str = $5; }
+	| goto_word COMMA goto_word COMMA goto_word {$$=npval(PV_WORD,@1.first_line,@1.last_line, @1.first_column, @1.last_column); 
+					$$->u1.str = $1; $$->next = npval(PV_WORD,@3.first_line,@3.last_line, @3.first_column, @3.last_column); 
+					$$->next->u1.str = $3; 
+					$$->next->next = npval(PV_WORD,@5.first_line,@5.last_line, @5.first_column, @5.last_column); 
+					$$->next->next->u1.str = $5; }
+	| KW_DEFAULT BAR goto_word BAR goto_word {$$=npval(PV_WORD,@1.first_line,@1.last_line, @1.first_column, @1.last_column); 
+					$$->u1.str = strdup("default"); $$->next = npval(PV_WORD,@3.first_line,@3.last_line, @3.first_column, @3.last_column); 
+					$$->next->u1.str = $3; 
+					$$->next->next = npval(PV_WORD,@5.first_line,@5.last_line, @5.first_column, @5.last_column); 
+					$$->next->next->u1.str = $5; }
+	| KW_DEFAULT COMMA goto_word COMMA goto_word {$$=npval(PV_WORD,@1.first_line,@1.last_line, @1.first_column, @1.last_column); 
+					$$->u1.str = strdup("default"); $$->next = npval(PV_WORD,@3.first_line,@3.last_line, @3.first_column, @3.last_column); 
+					$$->next->u1.str = $3; 
+					$$->next->next = npval(PV_WORD,@5.first_line,@5.last_line, @5.first_column, @5.last_column); 
+					$$->next->next->u1.str = $5; }
+	;
+
+jumptarget : goto_word {$$=npval(PV_WORD,@1.first_line,@1.last_line, @1.first_column, @1.last_column); 
+					$$->u1.str = $1; $$->next = npval(PV_WORD,@1.first_line,@1.last_line, @1.first_column, @1.last_column); 
+					$$->next->u1.str = strdup("1");}  /*  jump extension[,priority][@context] */
+		| goto_word COMMA goto_word {$$=npval(PV_WORD,@1.first_line,@1.last_line, @1.first_column, @1.last_column); 
+					$$->u1.str = $1; $$->next = npval(PV_WORD,@3.first_line,@3.last_line, @3.first_column, @3.last_column); 
+					$$->next->u1.str = $3;} 
+		| goto_word COMMA word AT word {$$=npval(PV_WORD,@1.first_line,@1.last_line, @1.first_column, @1.last_column); 
+					$$->u1.str = $5; $$->next = npval(PV_WORD,@3.first_line,@3.last_line, @3.first_column, @3.last_column); 
+					$$->next->u1.str = $1; 
+					$$->next->next = npval(PV_WORD,@5.first_line,@5.last_line, @5.first_column, @5.last_column); 
+					$$->next->next->u1.str = $3; } 
+		| goto_word AT goto_word {$$=npval(PV_WORD,@1.first_line,@1.last_line, @1.first_column, @1.last_column); 
+					$$->u1.str = $3; $$->next = npval(PV_WORD,@3.first_line,@3.last_line, @3.first_column, @3.last_column); 
+					$$->next->u1.str = $1; 
+					$$->next->next = npval(PV_WORD,@3.first_line,@3.last_line, @3.first_column, @3.last_column); 
+					$$->next->next->u1.str = strdup("1"); } 
+		| goto_word COMMA word AT KW_DEFAULT {$$=npval(PV_WORD,@1.first_line,@1.last_line, @1.first_column, @1.last_column); 
+					$$->u1.str = strdup("default"); $$->next = npval(PV_WORD,@3.first_line,@3.last_line, @3.first_column, @3.last_column); 
+					$$->next->u1.str = $1; 
+					$$->next->next = npval(PV_WORD,@5.first_line,@5.last_line, @5.first_column, @5.last_column); 
+					$$->next->next->u1.str = $3; } 
+		| goto_word AT KW_DEFAULT {$$=npval(PV_WORD,@1.first_line,@1.last_line, @1.first_column, @1.last_column); 
+					$$->u1.str = strdup("default"); $$->next = npval(PV_WORD,@3.first_line,@3.last_line, @3.first_column, @3.last_column); 
+					$$->next->u1.str = $1; 
+					$$->next->next = npval(PV_WORD,@3.first_line,@3.last_line, @3.first_column, @3.last_column); 
+					$$->next->next->u1.str = strdup("1"); } 
+		;
+
+macro_call : word LP {reset_argcount(parseio->scanner);} eval_arglist RP 
+			{$$= npval(PV_MACRO_CALL,@1.first_line,@2.last_line, @1.first_column, @2.last_column); 
+			$$->u1.str = $1; $$->u2.arglist = $4;}
+	| word LP RP {$$= npval(PV_MACRO_CALL,@1.first_line,@3.last_line, @1.first_column, @3.last_column); $$->u1.str = $1; }
+	;
+
+application_call_head: word {reset_argcount(parseio->scanner);} LP  {if (strcasecmp($1,"goto") == 0) {
+																							$$= npval(PV_GOTO,@1.first_line,@3.last_line, @1.first_column, @3.last_column);
+																							free($1); /* won't be using this */
+																							ast_log(LOG_WARNING, "==== File: %s, Line %d, Cols: %d-%d: Suggestion: Use the goto statement instead of the Goto() application call in AEL.\n", my_file, @1.first_line, @1.first_column, @1.last_column );
+																						} else
+																							$$= npval(PV_APPLICATION_CALL,@1.first_line,@3.last_line, @1.first_column, @3.last_column); 
+																						$$->u1.str = $1; }
+	;
+
+application_call : application_call_head eval_arglist RP {$$ = $1;
+ 		if( $$->type == PV_GOTO )
+			$$->u1.list = $2;
+	 	else
+			$$->u2.arglist = $2;
+ 		$$->endline = @3.last_line; $$->endcol = @3.last_column;}
+	| application_call_head RP {$$=$1;$$->endline = @2.last_line; $$->endcol = @2.last_column;}
+	;
+
+eval_arglist :  word_list { $$= npval(PV_WORD,@1.first_line,@1.last_line, @1.first_column, @1.last_column); $$->u1.str = $1;}
+	| /*nothing! */   { $$= npval(PV_WORD,0/*@1.first_line*/,0/*@1.last_line*/,0/* @1.first_column*/, 0/*@1.last_column*/); $$->u1.str = strdup(""); }
+	| eval_arglist COMMA  word { pval *z = npval(PV_WORD,@3.first_line,@3.last_line, @3.first_column, @3.last_column); $$ = $1; linku1($1,z); z->u1.str = $3;}
+	| eval_arglist COMMA { pval *z = npval(PV_WORD,@2.first_line,@2.last_line, @2.first_column, @2.last_column); $$ = $1; linku1($1,z); z->u1.str = strdup("");}
+	;
+
+case_statements: case_statement {$$=$1;}
+	| case_statements case_statement { if ( $1 && $2 ) {$$=$1; linku1($$,$2);} 
+						 else if ( $1 ) {$$=$1;}
+						 else if ( $2 ) {$$=$2;} }
+	;
+
+case_statement: KW_CASE word COLON statements {$$ = npval(PV_CASE,@1.first_line,@3.last_line, @1.first_column, @3.last_column); $$->u1.str = $2; $$->u2.statements = $4;}
+	| KW_DEFAULT COLON statements {$$ = npval(PV_DEFAULT,@1.first_line,@3.last_line, @1.first_column, @3.last_column); $$->u1.str = 0; $$->u2.statements = $3;}
+	| KW_PATTERN word COLON statements {$$ = npval(PV_PATTERN,@1.first_line,@3.last_line, @1.first_column, @3.last_column); $$->u1.str = $2; $$->u2.statements = $4;}
+    | KW_CASE word COLON {$$ = npval(PV_CASE,@1.first_line,@3.last_line, @1.first_column, @3.last_column); $$->u1.str = $2;}
+	| KW_DEFAULT COLON {$$ = npval(PV_DEFAULT,@1.first_line,@2.last_line, @1.first_column, @2.last_column); $$->u1.str = 0;}
+	| KW_PATTERN word COLON  {$$ = npval(PV_PATTERN,@1.first_line,@3.last_line, @1.first_column, @3.last_column); $$->u1.str = $2;}
+	;
+
+macro_statements: macro_statement {$$ = $1;}
+	| macro_statements macro_statement { if ( $1 && $2 ) {$$=$1; linku1($$,$2);} 
+						 else if ( $1 ) {$$=$1;}
+						 else if ( $2 ) {$$=$2;} }
+	;
+
+macro_statement : statement {$$=$1;}
+	| KW_CATCH word LC statements RC {$$=npval(PV_CATCH,@1.first_line,@5.last_line, @1.first_column, @5.last_column); $$->u1.str = $2; $$->u2.statements = $4;}
+	;
+
+switches : KW_SWITCHES LC switchlist RC {$$= npval(PV_SWITCHES,@1.first_line,@4.last_line, @1.first_column, @4.last_column); $$->u1.list = $3; }
+	| KW_SWITCHES LC RC /* empty switch list OK */ {$$= npval(PV_SWITCHES,@1.first_line,@3.last_line, @1.first_column, @3.last_column);}
+	;
+
+eswitches : KW_ESWITCHES LC switchlist RC {$$= npval(PV_ESWITCHES,@1.first_line,@4.last_line, @1.first_column, @4.last_column); $$->u1.list = $3; }
+	| KW_ESWITCHES LC  RC /* empty switch list OK */ {$$= npval(PV_ESWITCHES,@1.first_line,@3.last_line, @1.first_column, @3.last_column); } /* if there's nothing to declare, why include it? */
+	;
+
+switchlist : word SEMI {$$=npval(PV_WORD,@1.first_line,@2.last_line, @1.first_column, @2.last_column); $$->u1.str = $1;}
+	| switchlist word SEMI {pval *z = npval(PV_WORD,@2.first_line,@3.last_line, @2.first_column, @3.last_column); $$=$1; z->u1.str = $2; linku1($$,z); }
+	| switchlist error {$$=$1;}
+	;
+
+includeslist : includedname SEMI {$$=npval(PV_WORD,@1.first_line,@2.last_line, @1.first_column, @2.last_column); $$->u1.str = $1;}
+	| includedname BAR word3_list COLON word3_list COLON word3_list BAR word3_list BAR word3_list BAR word3_list SEMI {
+                    $$=npval(PV_WORD,@1.first_line,@2.last_line, @1.first_column, @2.last_column); 
+                    $$->u1.str = $1;
+					$$->u2.arglist = npval(PV_WORD,@3.first_line,@7.last_line, @3.first_column, @7.last_column); 
+					$$->u2.arglist->u1.str = (char*)malloc(strlen($3)+strlen($5)+strlen($7)+4);
+					strcpy($$->u2.arglist->u1.str,$3);
+					strcat($$->u2.arglist->u1.str,":");
+					strcat($$->u2.arglist->u1.str,$5);
+					strcat($$->u2.arglist->u1.str,":");
+					strcat($$->u2.arglist->u1.str,$7);
+					free($3);
+					free($5);
+					free($7);
+					$$->u2.arglist->next = npval(PV_WORD,@9.first_line,@9.last_line, @9.first_column, @9.last_column); 
+					$$->u2.arglist->next->u1.str = $9; 
+					$$->u2.arglist->next->next = npval(PV_WORD,@11.first_line,@11.last_line, @11.first_column, @11.last_column); 
+					$$->u2.arglist->next->next->u1.str = $11; 
+					$$->u2.arglist->next->next->next = npval(PV_WORD,@13.first_line,@13.last_line, @13.first_column, @13.last_column); 
+					$$->u2.arglist->next->next->next->u1.str = $13; 
+					prev_word=0;
+			}
+	| includedname BAR word BAR word3_list BAR word3_list BAR word3_list SEMI {
+                    $$=npval(PV_WORD,@1.first_line,@2.last_line, @1.first_column, @2.last_column); 
+                    $$->u1.str = $1;
+					$$->u2.arglist = npval(PV_WORD,@3.first_line,@3.last_line, @3.first_column, @3.last_column); 
+					$$->u2.arglist->u1.str = $3;
+					$$->u2.arglist->next = npval(PV_WORD,@5.first_line,@5.last_line, @5.first_column, @5.last_column); 
+					$$->u2.arglist->next->u1.str = $5; 
+					$$->u2.arglist->next->next = npval(PV_WORD,@7.first_line,@7.last_line, @7.first_column, @7.last_column); 
+					$$->u2.arglist->next->next->u1.str = $7; 
+					$$->u2.arglist->next->next->next = npval(PV_WORD,@9.first_line,@9.last_line, @9.first_column, @9.last_column); 
+					$$->u2.arglist->next->next->next->u1.str = $9; 
+					prev_word=0;
+			}
+	| includeslist includedname SEMI {pval *z = npval(PV_WORD,@2.first_line,@3.last_line, @2.first_column, @3.last_column); $$=$1; z->u1.str = $2; linku1($$,z); }
+	| includeslist includedname BAR word3_list COLON word3_list COLON word3_list BAR word3_list BAR word3_list BAR word3_list SEMI {pval *z = npval(PV_WORD,@2.first_line,@3.last_line, @2.first_column, @3.last_column); 
+					$$=$1; z->u1.str = $2; linku1($$,z);
+					z->u2.arglist = npval(PV_WORD,@4.first_line,@4.last_line, @4.first_column, @4.last_column); 
+					$$->u2.arglist->u1.str = (char*)malloc(strlen($4)+strlen($6)+strlen($8)+4);
+					strcpy($$->u2.arglist->u1.str,$4);
+					strcat($$->u2.arglist->u1.str,":");
+					strcat($$->u2.arglist->u1.str,$6);
+					strcat($$->u2.arglist->u1.str,":");
+					strcat($$->u2.arglist->u1.str,$8);
+					free($4);
+					free($6);
+					free($8);
+					z->u2.arglist->next = npval(PV_WORD,@10.first_line,@10.last_line, @10.first_column, @10.last_column); 
+					z->u2.arglist->next->u1.str = $10; 
+					z->u2.arglist->next->next = npval(PV_WORD,@12.first_line,@12.last_line, @12.first_column, @12.last_column); 
+					z->u2.arglist->next->next->u1.str = $12; 
+					z->u2.arglist->next->next->next = npval(PV_WORD,@14.first_line,@14.last_line, @14.first_column, @14.last_column); 
+					z->u2.arglist->next->next->next->u1.str = $14; 
+					prev_word=0;
+			}
+	| includeslist includedname BAR word BAR word3_list BAR word3_list BAR word3_list SEMI
+                   {pval *z = npval(PV_WORD,@2.first_line,@2.last_line, @2.first_column, @3.last_column);
+					$$=$1; z->u1.str = $2; linku1($$,z);
+					z->u2.arglist = npval(PV_WORD,@4.first_line,@4.last_line, @4.first_column, @4.last_column);
+					$$->u2.arglist->u1.str = $4;
+					z->u2.arglist->next = npval(PV_WORD,@6.first_line,@6.last_line, @6.first_column, @6.last_column);
+					z->u2.arglist->next->u1.str = $6;
+					z->u2.arglist->next->next = npval(PV_WORD,@8.first_line,@8.last_line, @8.first_column, @8.last_column);
+					z->u2.arglist->next->next->u1.str = $8;
+					z->u2.arglist->next->next->next = npval(PV_WORD,@10.first_line,@10.last_line, @10.first_column, @10.last_column);
+					z->u2.arglist->next->next->next->u1.str = $10;
+					prev_word=0;
+			}
+	| includeslist error {$$=$1;}
+	;
+
+includedname : word { $$ = $1;}
+			| KW_DEFAULT {$$=strdup("default");}
+			;
+
+includes : KW_INCLUDES LC includeslist RC {$$= npval(PV_INCLUDES,@1.first_line,@4.last_line, @1.first_column, @4.last_column); $$->u1.list = $3;}
+	| KW_INCLUDES LC RC  {$$= npval(PV_INCLUDES,@1.first_line,@3.last_line, @1.first_column, @3.last_column);}
+	;
+
+
+%%
+
+static char *token_equivs1[] = 
+{
+	"AMPER",
+	"AT",
+	"BAR",
+	"COLON",
+	"COMMA",
+	"EQ",
+	"EXTENMARK",
+	"KW_BREAK", 
+	"KW_CASE", 
+	"KW_CATCH", 
+	"KW_CONTEXT",
+	"KW_CONTINUE", 
+	"KW_DEFAULT", 
+	"KW_ELSE",
+	"KW_ESWITCHES",
+	"KW_FOR", 
+	"KW_GLOBALS",
+	"KW_GOTO",
+	"KW_HINT",
+	"KW_IFTIME",
+	"KW_IF",
+	"KW_IGNOREPAT",
+	"KW_INCLUDES"
+	"KW_JUMP",
+	"KW_MACRO",
+	"KW_PATTERN", 
+	"KW_REGEXTEN", 
+	"KW_RETURN", 
+	"KW_SWITCHES", 
+	"KW_SWITCH",
+	"KW_WHILE", 
+	"LC",
+	"LP",
+	"RC",
+	"RP",
+	"SEMI",
+};
+
+static char *token_equivs2[] = 
+{
+	"&",
+	"@",
+	"|",
+	":",
+	",",
+	"=",
+	"=>",
+	"break", 
+	"case", 
+	"catch", 
+	"context",
+	"continue", 
+	"default", 
+	"else",
+	"eswitches",
+	"for", 
+	"globals",
+	"goto",
+	"hint",
+	"ifTime",
+	"if",
+	"ignorepat",
+	"includes"
+	"jump",
+	"macro",
+	"pattern", 
+	"regexten", 
+	"return", 
+	"switches", 
+	"switch",
+	"while", 
+	"{",
+	"(",
+	"}",
+	")",
+	";",
+};
+
+
+static char *ael_token_subst(char *mess)
+{
+	/* calc a length, malloc, fill, and return; yyerror had better free it! */
+	int len=0,i;
+	char *p;
+	char *res, *s,*t;
+	int token_equivs_entries = sizeof(token_equivs1)/sizeof(char*);
+
+	for (p=mess; *p; p++) {
+		for (i=0; i<token_equivs_entries; i++) {
+			if ( strncmp(p,token_equivs1[i],strlen(token_equivs1[i])) == 0 )
+			{
+				len+=strlen(token_equivs2[i])+2;
+				p += strlen(token_equivs1[i])-1;
+				break;
+			}
+		}
+		len++;
+	}
+	res = (char*)malloc(len+1);
+	res[0] = 0;
+	s = res;
+	for (p=mess; *p;) {
+		int found = 0;
+		for (i=0; i<token_equivs_entries; i++) {
+			if ( strncmp(p,token_equivs1[i],strlen(token_equivs1[i])) == 0 ) {
+				*s++ = '\'';
+				for (t=token_equivs2[i]; *t;) {
+					*s++ = *t++;
+				}
+				*s++ = '\'';
+				p += strlen(token_equivs1[i]);
+				found = 1;
+				break;
+			}
+		}
+		if( !found )
+			*s++ = *p++;
+	}
+	*s++ = 0;
+	return res;
+}
+
+void yyerror(YYLTYPE *locp, struct parse_io *parseio,  char const *s)
+{
+	char *s2 = ael_token_subst((char *)s);
+	if (locp->first_line == locp->last_line) {
+		ast_log(LOG_ERROR, "==== File: %s, Line %d, Cols: %d-%d: Error: %s\n", my_file, locp->first_line, locp->first_column, locp->last_column, s2);
+	} else {
+		ast_log(LOG_ERROR, "==== File: %s, Line %d Col %d  to Line %d Col %d: Error: %s\n", my_file, locp->first_line, locp->first_column, locp->last_line, locp->last_column, s2);
+	}
+	free(s2);
+	parseio->syntax_error_count++;
+}
+
+struct pval *npval(pvaltype type,int first_line, int last_line, int first_column, int last_column)
+{
+	extern char *my_file;
+	pval *z = (pval *)calloc(sizeof(struct pval),1);
+	z->type = type;
+	z->startline = first_line;
+	z->endline = last_line;
+	z->startcol = first_column;
+	z->endcol = last_column;
+	z->filename = strdup(my_file);
+	return z;
+}
+
+void linku1(pval *head, pval *tail)
+{
+	if (!head->next) {
+		head->next = tail;
+		head->u1_last = tail;
+	} else {
+		head->u1_last->next = tail;
+		head->u1_last = tail;
+	}
+}
+
diff --git a/pbx/ael/ael_lex.c b/pbx/ael/ael_lex.c
new file mode 100644
index 0000000000..9e5894de55
--- /dev/null
+++ b/pbx/ael/ael_lex.c
@@ -0,0 +1,2996 @@
+#line 2 "ael_lex.c"
+
+#line 4 "ael_lex.c"
+
+#define  YY_INT_ALIGNED short int
+
+/* A lexical scanner generated by flex */
+
+#define FLEX_SCANNER
+#define YY_FLEX_MAJOR_VERSION 2
+#define YY_FLEX_MINOR_VERSION 5
+#define YY_FLEX_SUBMINOR_VERSION 33
+#if YY_FLEX_SUBMINOR_VERSION > 0
+#define FLEX_BETA
+#endif
+
+/* First, we deal with  platform-specific or compiler-specific issues. */
+
+/* begin standard C headers. */
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <stdlib.h>
+
+/* end standard C headers. */
+
+/* flex integer type definitions */
+
+#ifndef FLEXINT_H
+#define FLEXINT_H
+
+/* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */
+
+#if __STDC_VERSION__ >= 199901L
+
+/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h,
+ * if you want the limit (max/min) macros for int types. 
+ */
+#ifndef __STDC_LIMIT_MACROS
+#define __STDC_LIMIT_MACROS 1
+#endif
+
+#include <inttypes.h>
+typedef int8_t flex_int8_t;
+typedef uint8_t flex_uint8_t;
+typedef int16_t flex_int16_t;
+typedef uint16_t flex_uint16_t;
+typedef int32_t flex_int32_t;
+typedef uint32_t flex_uint32_t;
+#else
+typedef signed char flex_int8_t;
+typedef short int flex_int16_t;
+typedef int flex_int32_t;
+typedef unsigned char flex_uint8_t; 
+typedef unsigned short int flex_uint16_t;
+typedef unsigned int flex_uint32_t;
+#endif /* ! C99 */
+
+/* Limits of integral types. */
+#ifndef INT8_MIN
+#define INT8_MIN               (-128)
+#endif
+#ifndef INT16_MIN
+#define INT16_MIN              (-32767-1)
+#endif
+#ifndef INT32_MIN
+#define INT32_MIN              (-2147483647-1)
+#endif
+#ifndef INT8_MAX
+#define INT8_MAX               (127)
+#endif
+#ifndef INT16_MAX
+#define INT16_MAX              (32767)
+#endif
+#ifndef INT32_MAX
+#define INT32_MAX              (2147483647)
+#endif
+#ifndef UINT8_MAX
+#define UINT8_MAX              (255U)
+#endif
+#ifndef UINT16_MAX
+#define UINT16_MAX             (65535U)
+#endif
+#ifndef UINT32_MAX
+#define UINT32_MAX             (4294967295U)
+#endif
+
+#endif /* ! FLEXINT_H */
+
+#ifdef __cplusplus
+
+/* The "const" storage-class-modifier is valid. */
+#define YY_USE_CONST
+
+#else	/* ! __cplusplus */
+
+#if __STDC__
+
+#define YY_USE_CONST
+
+#endif	/* __STDC__ */
+#endif	/* ! __cplusplus */
+
+#ifdef YY_USE_CONST
+#define yyconst const
+#else
+#define yyconst
+#endif
+
+/* Returned upon end-of-file. */
+#define YY_NULL 0
+
+/* Promotes a possibly negative, possibly signed char to an unsigned
+ * integer for use as an array index.  If the signed char is negative,
+ * we want to instead treat it as an 8-bit unsigned char, hence the
+ * double cast.
+ */
+#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c)
+
+/* An opaque pointer. */
+#ifndef YY_TYPEDEF_YY_SCANNER_T
+#define YY_TYPEDEF_YY_SCANNER_T
+typedef void* yyscan_t;
+#endif
+
+/* For convenience, these vars (plus the bison vars far below)
+   are macros in the reentrant scanner. */
+#define yyin yyg->yyin_r
+#define yyout yyg->yyout_r
+#define yyextra yyg->yyextra_r
+#define yyleng yyg->yyleng_r
+#define yytext yyg->yytext_r
+#define yylineno (YY_CURRENT_BUFFER_LVALUE->yy_bs_lineno)
+#define yycolumn (YY_CURRENT_BUFFER_LVALUE->yy_bs_column)
+#define yy_flex_debug yyg->yy_flex_debug_r
+
+int ael_yylex_init (yyscan_t* scanner);
+
+/* Enter a start condition.  This macro really ought to take a parameter,
+ * but we do it the disgusting crufty way forced on us by the ()-less
+ * definition of BEGIN.
+ */
+#define BEGIN yyg->yy_start = 1 + 2 *
+
+/* Translate the current start state into a value that can be later handed
+ * to BEGIN to return to the state.  The YYSTATE alias is for lex
+ * compatibility.
+ */
+#define YY_START ((yyg->yy_start - 1) / 2)
+#define YYSTATE YY_START
+
+/* Action number for EOF rule of a given start state. */
+#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1)
+
+/* Special action meaning "start processing a new file". */
+#define YY_NEW_FILE ael_yyrestart(yyin ,yyscanner )
+
+#define YY_END_OF_BUFFER_CHAR 0
+
+/* Size of default input buffer. */
+#ifndef YY_BUF_SIZE
+#define YY_BUF_SIZE 16384
+#endif
+
+/* The state buf must be large enough to hold one state per character in the main buffer.
+ */
+#define YY_STATE_BUF_SIZE   ((YY_BUF_SIZE + 2) * sizeof(yy_state_type))
+
+#ifndef YY_TYPEDEF_YY_BUFFER_STATE
+#define YY_TYPEDEF_YY_BUFFER_STATE
+typedef struct yy_buffer_state *YY_BUFFER_STATE;
+#endif
+
+#define EOB_ACT_CONTINUE_SCAN 0
+#define EOB_ACT_END_OF_FILE 1
+#define EOB_ACT_LAST_MATCH 2
+
+    #define YY_LESS_LINENO(n)
+    
+/* Return all but the first "n" matched characters back to the input stream. */
+#define yyless(n) \
+	do \
+		{ \
+		/* Undo effects of setting up yytext. */ \
+        int yyless_macro_arg = (n); \
+        YY_LESS_LINENO(yyless_macro_arg);\
+		*yy_cp = yyg->yy_hold_char; \
+		YY_RESTORE_YY_MORE_OFFSET \
+		yyg->yy_c_buf_p = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \
+		YY_DO_BEFORE_ACTION; /* set up yytext again */ \
+		} \
+	while ( 0 )
+
+#define unput(c) yyunput( c, yyg->yytext_ptr , yyscanner )
+
+/* The following is because we cannot portably get our hands on size_t
+ * (without autoconf's help, which isn't available because we want
+ * flex-generated scanners to compile on their own).
+ */
+
+#ifndef YY_TYPEDEF_YY_SIZE_T
+#define YY_TYPEDEF_YY_SIZE_T
+typedef unsigned int yy_size_t;
+#endif
+
+#ifndef YY_STRUCT_YY_BUFFER_STATE
+#define YY_STRUCT_YY_BUFFER_STATE
+struct yy_buffer_state
+	{
+	FILE *yy_input_file;
+
+	char *yy_ch_buf;		/* input buffer */
+	char *yy_buf_pos;		/* current position in input buffer */
+
+	/* Size of input buffer in bytes, not including room for EOB
+	 * characters.
+	 */
+	yy_size_t yy_buf_size;
+
+	/* Number of characters read into yy_ch_buf, not including EOB
+	 * characters.
+	 */
+	int yy_n_chars;
+
+	/* Whether we "own" the buffer - i.e., we know we created it,
+	 * and can realloc() it to grow it, and should free() it to
+	 * delete it.
+	 */
+	int yy_is_our_buffer;
+
+	/* Whether this is an "interactive" input source; if so, and
+	 * if we're using stdio for input, then we want to use getc()
+	 * instead of fread(), to make sure we stop fetching input after
+	 * each newline.
+	 */
+	int yy_is_interactive;
+
+	/* Whether we're considered to be at the beginning of a line.
+	 * If so, '^' rules will be active on the next match, otherwise
+	 * not.
+	 */
+	int yy_at_bol;
+
+    int yy_bs_lineno; /**< The line count. */
+    int yy_bs_column; /**< The column count. */
+    
+	/* Whether to try to fill the input buffer when we reach the
+	 * end of it.
+	 */
+	int yy_fill_buffer;
+
+	int yy_buffer_status;
+
+#define YY_BUFFER_NEW 0
+#define YY_BUFFER_NORMAL 1
+	/* When an EOF's been seen but there's still some text to process
+	 * then we mark the buffer as YY_EOF_PENDING, to indicate that we
+	 * shouldn't try reading from the input source any more.  We might
+	 * still have a bunch of tokens to match, though, because of
+	 * possible backing-up.
+	 *
+	 * When we actually see the EOF, we change the status to "new"
+	 * (via ael_yyrestart()), so that the user can continue scanning by
+	 * just pointing yyin at a new input file.
+	 */
+#define YY_BUFFER_EOF_PENDING 2
+
+	};
+#endif /* !YY_STRUCT_YY_BUFFER_STATE */
+
+/* We provide macros for accessing buffer states in case in the
+ * future we want to put the buffer states in a more general
+ * "scanner state".
+ *
+ * Returns the top of the stack, or NULL.
+ */
+#define YY_CURRENT_BUFFER ( yyg->yy_buffer_stack \
+                          ? yyg->yy_buffer_stack[yyg->yy_buffer_stack_top] \
+                          : NULL)
+
+/* Same as previous macro, but useful when we know that the buffer stack is not
+ * NULL or when we need an lvalue. For internal use only.
+ */
+#define YY_CURRENT_BUFFER_LVALUE yyg->yy_buffer_stack[yyg->yy_buffer_stack_top]
+
+void ael_yyrestart (FILE *input_file ,yyscan_t yyscanner );
+void ael_yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner );
+YY_BUFFER_STATE ael_yy_create_buffer (FILE *file,int size ,yyscan_t yyscanner );
+void ael_yy_delete_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner );
+void ael_yy_flush_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner );
+void ael_yypush_buffer_state (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner );
+void ael_yypop_buffer_state (yyscan_t yyscanner );
+
+static void ael_yyensure_buffer_stack (yyscan_t yyscanner );
+static void ael_yy_load_buffer_state (yyscan_t yyscanner );
+static void ael_yy_init_buffer (YY_BUFFER_STATE b,FILE *file ,yyscan_t yyscanner );
+
+#define YY_FLUSH_BUFFER ael_yy_flush_buffer(YY_CURRENT_BUFFER ,yyscanner)
+
+YY_BUFFER_STATE ael_yy_scan_buffer (char *base,yy_size_t size ,yyscan_t yyscanner );
+YY_BUFFER_STATE ael_yy_scan_string (yyconst char *yy_str ,yyscan_t yyscanner );
+YY_BUFFER_STATE ael_yy_scan_bytes (yyconst char *bytes,int len ,yyscan_t yyscanner );
+
+void *ael_yyalloc (yy_size_t ,yyscan_t yyscanner );
+void *ael_yyrealloc (void *,yy_size_t ,yyscan_t yyscanner );
+void ael_yyfree (void * ,yyscan_t yyscanner );
+
+#define yy_new_buffer ael_yy_create_buffer
+
+#define yy_set_interactive(is_interactive) \
+	{ \
+	if ( ! YY_CURRENT_BUFFER ){ \
+        ael_yyensure_buffer_stack (yyscanner); \
+		YY_CURRENT_BUFFER_LVALUE =    \
+            ael_yy_create_buffer(yyin,YY_BUF_SIZE ,yyscanner); \
+	} \
+	YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \
+	}
+
+#define yy_set_bol(at_bol) \
+	{ \
+	if ( ! YY_CURRENT_BUFFER ){\
+        ael_yyensure_buffer_stack (yyscanner); \
+		YY_CURRENT_BUFFER_LVALUE =    \
+            ael_yy_create_buffer(yyin,YY_BUF_SIZE ,yyscanner); \
+	} \
+	YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \
+	}
+
+#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol)
+
+/* Begin user sect3 */
+
+#define ael_yywrap(n) 1
+#define YY_SKIP_YYWRAP
+
+typedef unsigned char YY_CHAR;
+
+typedef int yy_state_type;
+
+#define yytext_ptr yytext_r
+
+static yy_state_type yy_get_previous_state (yyscan_t yyscanner );
+static yy_state_type yy_try_NUL_trans (yy_state_type current_state  ,yyscan_t yyscanner);
+static int yy_get_next_buffer (yyscan_t yyscanner );
+static void yy_fatal_error (yyconst char msg[] ,yyscan_t yyscanner );
+
+/* Done after the current pattern has been matched and before the
+ * corresponding action - sets up yytext.
+ */
+#define YY_DO_BEFORE_ACTION \
+	yyg->yytext_ptr = yy_bp; \
+	yyg->yytext_ptr -= yyg->yy_more_len; \
+	yyleng = (size_t) (yy_cp - yyg->yytext_ptr); \
+	yyg->yy_hold_char = *yy_cp; \
+	*yy_cp = '\0'; \
+	yyg->yy_c_buf_p = yy_cp;
+
+#define YY_NUM_RULES 65
+#define YY_END_OF_BUFFER 66
+/* This struct is not used in this scanner,
+   but its presence is necessary. */
+struct yy_trans_info
+	{
+	flex_int32_t yy_verify;
+	flex_int32_t yy_nxt;
+	};
+static yyconst flex_int16_t yy_accept[226] =
+    {   0,
+        0,    0,    0,    0,    0,    0,    0,    0,   66,   65,
+       42,   40,   41,   43,   43,    9,    3,    4,    7,   43,
+        8,    5,    6,   12,   43,   43,   43,   43,   43,   43,
+       43,   43,   43,   43,   43,   43,   43,   43,   43,    1,
+       10,    2,   65,   45,   44,   46,   47,   48,   49,   65,
+       61,   62,   63,   57,   58,   59,   60,   65,   51,   50,
+       52,   55,   56,   53,   54,   42,   41,   43,   43,   13,
+       11,   43,   43,   43,   43,   43,   43,   43,   43,   43,
+       43,   43,   20,   43,   43,   43,   43,   43,   43,   43,
+       43,   43,    0,   45,   44,   46,   47,   48,   49,    0,
+
+       61,   62,   63,   57,   58,   59,   60,    0,   51,   50,
+       52,   55,   56,   53,   54,   43,   13,   13,   43,   43,
+       43,   43,   43,   43,   43,   43,   31,   43,   43,   43,
+       43,   43,   43,   43,   43,   43,   43,   43,   43,   43,
+       43,   43,   43,   43,   33,   43,   43,   43,   25,   43,
+       43,   26,   24,   43,   43,   43,   27,   43,   43,   43,
+       43,   43,   43,   43,   43,   43,   29,   36,   43,   43,
+       43,   43,   43,   43,   43,   43,   16,   43,   43,   43,
+       43,   43,   32,   43,   43,   43,   43,   43,   43,   43,
+       21,   43,   43,   43,   22,   43,   28,   19,   43,   43,
+
+       14,   43,   34,   43,   17,   43,   43,   35,   43,   43,
+       43,   15,   30,   43,   43,   39,   23,   37,    0,   38,
+       18,    0,    0,   64,    0
+    } ;
+
+static yyconst flex_int32_t yy_ec[256] =
+    {   0,
+        1,    1,    1,    1,    1,    1,    1,    1,    2,    3,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    4,    5,    6,    7,    5,    1,    8,    5,    9,
+       10,    5,    5,   11,    5,    5,   12,    5,    5,    5,
+        5,    5,    5,    5,    5,    5,    5,   13,   14,    5,
+       15,   16,    1,   17,    5,    5,    5,    5,    5,    5,
+        5,    5,    5,    5,    5,    5,    5,    5,    5,    5,
+        5,    5,    5,   18,    5,    5,    5,    5,    5,    5,
+       19,    1,   20,    1,    5,    1,   21,   22,   23,   24,
+
+       25,   26,   27,   28,   29,   30,   31,   32,   33,   34,
+       35,   36,    5,   37,   38,   39,   40,    5,   41,   42,
+        5,    5,   43,   44,   45,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1
+    } ;
+
+static yyconst flex_int32_t yy_meta[46] =
+    {   0,
+        1,    1,    2,    1,    3,    4,    3,    1,    1,    1,
+        1,    3,    1,    1,    1,    3,    1,    3,    3,    3,
+        3,    3,    3,    3,    3,    3,    3,    3,    3,    3,
+        3,    3,    3,    3,    3,    3,    3,    3,    3,    3,
+        3,    3,    3,    1,    3
+    } ;
+
+static yyconst flex_int16_t yy_base[236] =
+    {   0,
+        0,    0,   37,   40,   77,  114,  151,  188,  237,  507,
+      234,  507,  228,    0,  201,  507,  507,  507,  507,  217,
+      507,  507,  212,  507,  205,  189,   27,  200,   20,  189,
+       19,  194,   37,  182,  200,  199,   40,  178,  190,  507,
+      507,  507,   57,  507,  507,  507,  507,  507,  507,  225,
+      507,  507,  507,  507,  507,  507,  507,  262,  507,  507,
+      507,  507,  507,  507,  507,  215,  212,    0,  181,  307,
+      507,  176,  188,   30,  178,  185,  172,  168,  169,  170,
+      165,  169,  184,  167,  177,  162,  170,  153,  157,   45,
+      161,  160,   69,  507,  507,  507,  507,  507,  507,  343,
+
+      507,  507,  507,  507,  507,  507,  507,  380,  507,  507,
+      507,  507,  507,  507,  507,  165,    0,  425,  148,  165,
+      160,  161,  144,  161,  156,  151,    0,  157,  143,  138,
+      147,  140,  142,  137,  135,  130,  144,  142,  126,  126,
+      132,  131,  121,  125,    0,  127,   45,  114,    0,  114,
+      131,    0,    0,  118,  113,  109,    0,  113,  122,  111,
+      103,  107,  120,  117,  101,  119,    0,    0,   97,  104,
+      105,  113,  103,  107,  106,  106,    0,   92,   94,   87,
+       91,   93,    0,   95,   95,   78,   76,   76,   85,   73,
+        0,   74,   84,   74,    0,   82,    0,   81,   80,   65,
+
+        0,   78,    0,   76,    0,   78,   60,    0,   61,   55,
+       51,    0,    0,   43,   36,    0,    0,    0,   88,    0,
+        0,    0,   67,  507,  507,  469,  473,  477,  479,  483,
+      487,  491,  495,  499,  503
+    } ;
+
+static yyconst flex_int16_t yy_def[236] =
+    {   0,
+      225,    1,  226,  226,  227,  227,  228,  228,  225,  225,
+      225,  225,  225,  229,  229,  225,  225,  225,  225,  229,
+      225,  225,  225,  225,  229,  229,  229,  229,  229,  229,
+      229,  229,  229,  229,  229,  229,  229,  229,  229,  225,
+      225,  225,  230,  225,  225,  225,  225,  225,  225,  231,
+      225,  225,  225,  225,  225,  225,  225,  232,  225,  225,
+      225,  225,  225,  225,  225,  225,  225,  229,  229,  233,
+      225,  229,  229,  229,  229,  229,  229,  229,  229,  229,
+      229,  229,  229,  229,  229,  229,  229,  229,  229,  229,
+      229,  229,  230,  225,  225,  225,  225,  225,  225,  231,
+
+      225,  225,  225,  225,  225,  225,  225,  232,  225,  225,
+      225,  225,  225,  225,  225,  229,  234,  233,  229,  229,
+      229,  229,  229,  229,  229,  229,  229,  229,  229,  229,
+      229,  229,  229,  229,  229,  229,  229,  229,  229,  229,
+      229,  229,  229,  229,  229,  229,  229,  229,  229,  229,
+      229,  229,  229,  229,  229,  229,  229,  229,  229,  229,
+      229,  229,  229,  229,  229,  229,  229,  229,  229,  229,
+      229,  229,  229,  229,  229,  229,  229,  229,  229,  229,
+      229,  229,  229,  229,  229,  229,  229,  229,  229,  229,
+      229,  229,  229,  229,  229,  229,  229,  229,  229,  229,
+
+      229,  229,  229,  229,  229,  229,  229,  229,  229,  229,
+      229,  229,  229,  229,  229,  229,  229,  229,  225,  229,
+      229,  235,  235,  225,    0,  225,  225,  225,  225,  225,
+      225,  225,  225,  225,  225
+    } ;
+
+static yyconst flex_int16_t yy_nxt[553] =
+    {   0,
+       10,   11,   12,   13,   14,   14,   15,   16,   17,   18,
+       19,   20,   21,   22,   23,   14,   24,   14,   14,   14,
+       25,   26,   27,   28,   29,   30,   31,   32,   33,   34,
+       14,   14,   35,   14,   14,   36,   37,   38,   14,   14,
+       39,   14,   40,   41,   42,   44,   45,   74,   44,   45,
+       80,   77,  219,   81,  219,   46,   47,   78,   46,   47,
+       89,   75,   83,   84,   90,   94,   95,  121,  122,  169,
+       85,  138,  224,  170,  221,   96,   97,   94,   95,   48,
+      220,   49,   48,  139,   49,   51,   52,   96,   97,  219,
+       53,  219,  218,  222,  217,   54,   55,  216,  215,   98,
+
+      214,   99,  213,  212,  211,  210,  209,  208,  207,  206,
+      205,   98,  204,   99,  203,  202,  201,  200,  199,   56,
+      198,   57,   51,   52,  197,  196,  195,   53,  194,  193,
+      192,  191,   54,   55,  190,  189,  188,  187,  186,  185,
+      184,  183,  182,  181,  180,  179,  178,  177,  176,  175,
+      174,  173,  172,  171,  168,  167,   56,  166,   57,   59,
+       60,   61,  165,  164,  163,  162,  161,  160,  159,   62,
+       63,  158,  157,  156,  155,  154,  153,  152,  151,  150,
+      149,  148,  147,  146,  145,  144,  143,  142,  141,  140,
+      137,  136,  135,   64,  134,   65,   59,   60,   61,  133,
+
+      132,  131,  130,  129,  128,  127,   62,   63,  126,  125,
+      124,  123,  120,  119,  116,   67,   66,   92,   91,   88,
+       87,   86,   82,   79,   76,   73,   72,   71,   70,   69,
+       64,   67,   65,  101,  102,   66,  225,  225,  103,  225,
+      225,  225,  225,  104,  105,  225,  225,  225,  225,  225,
+      225,  225,  225,  225,  225,  225,  225,  225,  225,  225,
+      225,  225,  225,  225,  225,  225,  225,  106,  225,  107,
+      109,  110,  111,  225,  225,  225,  225,  225,  225,  225,
+      112,  113,  225,  225,  225,  225,  225,  225,  225,  225,
+      225,  225,  225,  225,  225,  225,  225,  225,  225,  225,
+
+      225,  225,  225,  225,  114,  225,  115,  117,  117,  225,
+      117,  225,  225,  225,  117,  117,  117,  117,  225,  117,
+      117,  117,  225,  117,  225,  225,  225,  225,  225,  225,
+      225,  225,  225,  225,  225,  225,  225,  225,  225,  225,
+      225,  225,  225,  225,  225,  225,  225,  225,  225,  225,
+      117,  101,  102,  225,  225,  225,  103,  225,  225,  225,
+      225,  104,  105,  225,  225,  225,  225,  225,  225,  225,
+      225,  225,  225,  225,  225,  225,  225,  225,  225,  225,
+      225,  225,  225,  225,  225,  106,  225,  107,  109,  110,
+      111,  225,  225,  225,  225,  225,  225,  225,  112,  113,
+
+      225,  225,  225,  225,  225,  225,  225,  225,  225,  225,
+      225,  225,  225,  225,  225,  225,  225,  225,  225,  225,
+      225,  225,  114,  225,  115,  117,  117,  225,  117,  225,
+      225,  225,  117,  117,  117,  117,  225,  117,  117,  117,
+      225,  117,  225,  225,  225,  225,  225,  225,  225,  225,
+      225,  225,  225,  225,  225,  225,  225,  225,  225,  225,
+      225,  225,  225,  225,  225,  225,  225,  225,  117,   43,
+       43,   43,   43,   50,   50,   50,   50,   58,   58,   58,
+       58,   68,   68,   93,   93,   93,   93,  100,  100,  100,
+      100,  108,  108,  108,  108,  118,  225,  118,  118,  117,
+
+      225,  117,  117,  223,  223,  223,    9,  225,  225,  225,
+      225,  225,  225,  225,  225,  225,  225,  225,  225,  225,
+      225,  225,  225,  225,  225,  225,  225,  225,  225,  225,
+      225,  225,  225,  225,  225,  225,  225,  225,  225,  225,
+      225,  225,  225,  225,  225,  225,  225,  225,  225,  225,
+      225,  225
+    } ;
+
+static yyconst flex_int16_t yy_chk[553] =
+    {   0,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    3,    3,   27,    4,    4,
+       31,   29,  211,   31,  211,    3,    3,   29,    4,    4,
+       37,   27,   33,   33,   37,   43,   43,   74,   74,  147,
+       33,   90,  223,  147,  215,   43,   43,   93,   93,    3,
+      214,    3,    4,   90,    4,    5,    5,   93,   93,  219,
+        5,  219,  210,  219,  209,    5,    5,  207,  206,   43,
+
+      204,   43,  202,  200,  199,  198,  196,  194,  193,  192,
+      190,   93,  189,   93,  188,  187,  186,  185,  184,    5,
+      182,    5,    6,    6,  181,  180,  179,    6,  178,  176,
+      175,  174,    6,    6,  173,  172,  171,  170,  169,  166,
+      165,  164,  163,  162,  161,  160,  159,  158,  156,  155,
+      154,  151,  150,  148,  146,  144,    6,  143,    6,    7,
+        7,    7,  142,  141,  140,  139,  138,  137,  136,    7,
+        7,  135,  134,  133,  132,  131,  130,  129,  128,  126,
+      125,  124,  123,  122,  121,  120,  119,  116,   92,   91,
+       89,   88,   87,    7,   86,    7,    8,    8,    8,   85,
+
+       84,   83,   82,   81,   80,   79,    8,    8,   78,   77,
+       76,   75,   73,   72,   69,   67,   66,   39,   38,   36,
+       35,   34,   32,   30,   28,   26,   25,   23,   20,   15,
+        8,   13,    8,   50,   50,   11,    9,    0,   50,    0,
+        0,    0,    0,   50,   50,    0,    0,    0,    0,    0,
+        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+        0,    0,    0,    0,    0,    0,    0,   50,    0,   50,
+       58,   58,   58,    0,    0,    0,    0,    0,    0,    0,
+       58,   58,    0,    0,    0,    0,    0,    0,    0,    0,
+        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+
+        0,    0,    0,    0,   58,    0,   58,   70,   70,    0,
+       70,    0,    0,    0,   70,   70,   70,   70,    0,   70,
+       70,   70,    0,   70,    0,    0,    0,    0,    0,    0,
+        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+       70,  100,  100,    0,    0,    0,  100,    0,    0,    0,
+        0,  100,  100,    0,    0,    0,    0,    0,    0,    0,
+        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+        0,    0,    0,    0,    0,  100,    0,  100,  108,  108,
+      108,    0,    0,    0,    0,    0,    0,    0,  108,  108,
+
+        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+        0,    0,  108,    0,  108,  118,  118,    0,  118,    0,
+        0,    0,  118,  118,  118,  118,    0,  118,  118,  118,
+        0,  118,    0,    0,    0,    0,    0,    0,    0,    0,
+        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+        0,    0,    0,    0,    0,    0,    0,    0,  118,  226,
+      226,  226,  226,  227,  227,  227,  227,  228,  228,  228,
+      228,  229,  229,  230,  230,  230,  230,  231,  231,  231,
+      231,  232,  232,  232,  232,  233,    0,  233,  233,  234,
+
+        0,  234,  234,  235,  235,  235,  225,  225,  225,  225,
+      225,  225,  225,  225,  225,  225,  225,  225,  225,  225,
+      225,  225,  225,  225,  225,  225,  225,  225,  225,  225,
+      225,  225,  225,  225,  225,  225,  225,  225,  225,  225,
+      225,  225,  225,  225,  225,  225,  225,  225,  225,  225,
+      225,  225
+    } ;
+
+/* The intent behind this definition is that it'll catch
+ * any uses of REJECT which flex missed.
+ */
+#define REJECT reject_used_but_not_detected
+#define yymore() (yyg->yy_more_flag = 1)
+#define YY_MORE_ADJ yyg->yy_more_len
+#define YY_RESTORE_YY_MORE_OFFSET
+#line 1 "ael.flex"
+#line 2 "ael.flex"
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 2006, Digium, Inc.
+ *
+ * Steve Murphy <murf@parsetree.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+/*! \file
+ *
+ * \brief Flex scanner description of tokens used in AEL2 .
+ * 
+ */#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include "asterisk.h"
+#include "asterisk/logger.h"
+#include "ael.tab.h"
+#include "asterisk/ael_structs.h"
+
+static char pbcstack[400];
+static int pbcpos = 0;
+
+static int parencount = 0;
+static int commaout = 0;
+int my_lineno = 1;
+int my_col = 0;
+char *my_file = 0;
+char *prev_word;
+#define MAX_INCLUDE_DEPTH 50
+
+void reset_parencount(yyscan_t yyscanner );
+void reset_semicount(yyscan_t yyscanner );
+void reset_argcount(yyscan_t yyscanner );
+struct pval *ael2_parse(char *filename, int *errors);
+int ael_yyget_column  (yyscan_t yyscanner);
+void ael_yyset_column (int  column_no , yyscan_t yyscanner);
+int ael_yyparse (struct parse_io *);
+static void pbcpush(char x);
+static int pbcpop(char x);
+static void pbcwhere(char *text, int *line, int *col );
+static int c_prevword(void);
+
+struct stackelement
+{
+     char *fname;
+	 int lineno;
+     int colno;
+	 YY_BUFFER_STATE bufstate;
+};
+struct stackelement  include_stack[MAX_INCLUDE_DEPTH];
+int include_stack_index = 0;
+
+
+/* %option yylineno I've tried hard, but haven't been able to use this */
+#line 703 "ael_lex.c"
+
+#define INITIAL 0
+#define paren 1
+#define semic 2
+#define argg 3
+
+#ifndef YY_NO_UNISTD_H
+/* Special case for "unistd.h", since it is non-ANSI. We include it way
+ * down here because we want the user's section 1 to have been scanned first.
+ * The user has a chance to override it with an option.
+ */
+#include <unistd.h>
+#endif
+
+#ifndef YY_EXTRA_TYPE
+#define YY_EXTRA_TYPE void *
+#endif
+
+/* Holds the entire state of the reentrant scanner. */
+struct yyguts_t
+    {
+
+    /* User-defined. Not touched by flex. */
+    YY_EXTRA_TYPE yyextra_r;
+
+    /* The rest are the same as the globals declared in the non-reentrant scanner. */
+    FILE *yyin_r, *yyout_r;
+    size_t yy_buffer_stack_top; /**< index of top of stack. */
+    size_t yy_buffer_stack_max; /**< capacity of stack. */
+    YY_BUFFER_STATE * yy_buffer_stack; /**< Stack as an array. */
+    char yy_hold_char;
+    int yy_n_chars;
+    int yyleng_r;
+    char *yy_c_buf_p;
+    int yy_init;
+    int yy_start;
+    int yy_did_buffer_switch_on_eof;
+    int yy_start_stack_ptr;
+    int yy_start_stack_depth;
+    int *yy_start_stack;
+    yy_state_type yy_last_accepting_state;
+    char* yy_last_accepting_cpos;
+
+    int yylineno_r;
+    int yy_flex_debug_r;
+
+    char *yytext_r;
+    int yy_more_flag;
+    int yy_more_len;
+
+    YYSTYPE * yylval_r;
+
+    YYLTYPE * yylloc_r;
+
+    }; /* end struct yyguts_t */
+
+static int yy_init_globals (yyscan_t yyscanner );
+
+    /* This must go here because YYSTYPE and YYLTYPE are included
+     * from bison output in section 1.*/
+    #    define yylval yyg->yylval_r
+    
+    #    define yylloc yyg->yylloc_r
+    
+/* Accessor methods to globals.
+   These are made visible to non-reentrant scanners for convenience. */
+
+int ael_yylex_destroy (yyscan_t yyscanner );
+
+int ael_yyget_debug (yyscan_t yyscanner );
+
+void ael_yyset_debug (int debug_flag ,yyscan_t yyscanner );
+
+YY_EXTRA_TYPE ael_yyget_extra (yyscan_t yyscanner );
+
+void ael_yyset_extra (YY_EXTRA_TYPE user_defined ,yyscan_t yyscanner );
+
+FILE *ael_yyget_in (yyscan_t yyscanner );
+
+void ael_yyset_in  (FILE * in_str ,yyscan_t yyscanner );
+
+FILE *ael_yyget_out (yyscan_t yyscanner );
+
+void ael_yyset_out  (FILE * out_str ,yyscan_t yyscanner );
+
+int ael_yyget_leng (yyscan_t yyscanner );
+
+char *ael_yyget_text (yyscan_t yyscanner );
+
+int ael_yyget_lineno (yyscan_t yyscanner );
+
+void ael_yyset_lineno (int line_number ,yyscan_t yyscanner );
+
+YYSTYPE * ael_yyget_lval (yyscan_t yyscanner );
+
+void ael_yyset_lval (YYSTYPE * yylval_param ,yyscan_t yyscanner );
+
+       YYLTYPE *ael_yyget_lloc (yyscan_t yyscanner );
+    
+        void ael_yyset_lloc (YYLTYPE * yylloc_param ,yyscan_t yyscanner );
+    
+/* Macros after this point can all be overridden by user definitions in
+ * section 1.
+ */
+
+#ifndef YY_SKIP_YYWRAP
+#ifdef __cplusplus
+extern "C" int ael_yywrap (yyscan_t yyscanner );
+#else
+extern int ael_yywrap (yyscan_t yyscanner );
+#endif
+#endif
+
+    static void yyunput (int c,char *buf_ptr  ,yyscan_t yyscanner);
+    
+#ifndef yytext_ptr
+static void yy_flex_strncpy (char *,yyconst char *,int ,yyscan_t yyscanner);
+#endif
+
+#ifdef YY_NEED_STRLEN
+static int yy_flex_strlen (yyconst char * ,yyscan_t yyscanner);
+#endif
+
+#ifndef YY_NO_INPUT
+
+#ifdef __cplusplus
+static int yyinput (yyscan_t yyscanner );
+#else
+static int input (yyscan_t yyscanner );
+#endif
+
+#endif
+
+/* Amount of stuff to slurp up with each read. */
+#ifndef YY_READ_BUF_SIZE
+#define YY_READ_BUF_SIZE 8192
+#endif
+
+/* Copy whatever the last rule matched to the standard output. */
+#ifndef ECHO
+/* This used to be an fputs(), but since the string might contain NUL's,
+ * we now use fwrite().
+ */
+#define ECHO (void) fwrite( yytext, yyleng, 1, yyout )
+#endif
+
+/* Gets input and stuffs it into "buf".  number of characters read, or YY_NULL,
+ * is returned in "result".
+ */
+#ifndef YY_INPUT
+#define YY_INPUT(buf,result,max_size) \
+	if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \
+		{ \
+		int c = '*'; \
+		size_t n; \
+		for ( n = 0; n < max_size && \
+			     (c = getc( yyin )) != EOF && c != '\n'; ++n ) \
+			buf[n] = (char) c; \
+		if ( c == '\n' ) \
+			buf[n++] = (char) c; \
+		if ( c == EOF && ferror( yyin ) ) \
+			YY_FATAL_ERROR( "input in flex scanner failed" ); \
+		result = n; \
+		} \
+	else \
+		{ \
+		errno=0; \
+		while ( (result = fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \
+			{ \
+			if( errno != EINTR) \
+				{ \
+				YY_FATAL_ERROR( "input in flex scanner failed" ); \
+				break; \
+				} \
+			errno=0; \
+			clearerr(yyin); \
+			} \
+		}\
+\
+
+#endif
+
+/* No semi-colon after return; correct usage is to write "yyterminate();" -
+ * we don't want an extra ';' after the "return" because that will cause
+ * some compilers to complain about unreachable statements.
+ */
+#ifndef yyterminate
+#define yyterminate() return YY_NULL
+#endif
+
+/* Number of entries by which start-condition stack grows. */
+#ifndef YY_START_STACK_INCR
+#define YY_START_STACK_INCR 25
+#endif
+
+/* Report a fatal error. */
+#ifndef YY_FATAL_ERROR
+#define YY_FATAL_ERROR(msg) yy_fatal_error( msg , yyscanner)
+#endif
+
+/* end tables serialization structures and prototypes */
+
+/* Default declaration of generated scanner - a define so the user can
+ * easily add parameters.
+ */
+#ifndef YY_DECL
+#define YY_DECL_IS_OURS 1
+
+extern int ael_yylex \
+               (YYSTYPE * yylval_param,YYLTYPE * yylloc_param ,yyscan_t yyscanner);
+
+#define YY_DECL int ael_yylex \
+               (YYSTYPE * yylval_param, YYLTYPE * yylloc_param , yyscan_t yyscanner)
+#endif /* !YY_DECL */
+
+/* Code executed at the beginning of each rule, after yytext and yyleng
+ * have been set up.
+ */
+#ifndef YY_USER_ACTION
+#define YY_USER_ACTION
+#endif
+
+/* Code executed at the end of each rule. */
+#ifndef YY_BREAK
+#define YY_BREAK break;
+#endif
+
+#define YY_RULE_SETUP \
+	YY_USER_ACTION
+
+/** The main scanner function which does all the work.
+ */
+YY_DECL
+{
+	register yy_state_type yy_current_state;
+	register char *yy_cp, *yy_bp;
+	register int yy_act;
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+#line 77 "ael.flex"
+
+#line 945 "ael_lex.c"
+
+    yylval = yylval_param;
+
+    yylloc = yylloc_param;
+
+	if ( !yyg->yy_init )
+		{
+		yyg->yy_init = 1;
+
+#ifdef YY_USER_INIT
+		YY_USER_INIT;
+#endif
+
+		if ( ! yyg->yy_start )
+			yyg->yy_start = 1;	/* first start state */
+
+		if ( ! yyin )
+			yyin = stdin;
+
+		if ( ! yyout )
+			yyout = stdout;
+
+		if ( ! YY_CURRENT_BUFFER ) {
+			ael_yyensure_buffer_stack (yyscanner);
+			YY_CURRENT_BUFFER_LVALUE =
+				ael_yy_create_buffer(yyin,YY_BUF_SIZE ,yyscanner);
+		}
+
+		ael_yy_load_buffer_state(yyscanner );
+		}
+
+	while ( 1 )		/* loops until end-of-file is reached */
+		{
+		yyg->yy_more_len = 0;
+		if ( yyg->yy_more_flag )
+			{
+			yyg->yy_more_len = yyg->yy_c_buf_p - yyg->yytext_ptr;
+			yyg->yy_more_flag = 0;
+			}
+		yy_cp = yyg->yy_c_buf_p;
+
+		/* Support of yytext. */
+		*yy_cp = yyg->yy_hold_char;
+
+		/* yy_bp points to the position in yy_ch_buf of the start of
+		 * the current run.
+		 */
+		yy_bp = yy_cp;
+
+		yy_current_state = yyg->yy_start;
+yy_match:
+		do
+			{
+			register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)];
+			if ( yy_accept[yy_current_state] )
+				{
+				yyg->yy_last_accepting_state = yy_current_state;
+				yyg->yy_last_accepting_cpos = yy_cp;
+				}
+			while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+				{
+				yy_current_state = (int) yy_def[yy_current_state];
+				if ( yy_current_state >= 226 )
+					yy_c = yy_meta[(unsigned int) yy_c];
+				}
+			yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+			++yy_cp;
+			}
+		while ( yy_current_state != 225 );
+		yy_cp = yyg->yy_last_accepting_cpos;
+		yy_current_state = yyg->yy_last_accepting_state;
+
+yy_find_action:
+		yy_act = yy_accept[yy_current_state];
+
+		YY_DO_BEFORE_ACTION;
+
+do_action:	/* This label is used only to access EOF actions. */
+
+		switch ( yy_act )
+	{ /* beginning of action switch */
+			case 0: /* must back up */
+			/* undo the effects of YY_DO_BEFORE_ACTION */
+			*yy_cp = yyg->yy_hold_char;
+			yy_cp = yyg->yy_last_accepting_cpos;
+			yy_current_state = yyg->yy_last_accepting_state;
+			goto yy_find_action;
+
+case 1:
+YY_RULE_SETUP
+#line 78 "ael.flex"
+{yylloc->first_line = yylloc->last_line = my_lineno; yylloc->last_column=my_col+yyleng-1; yylloc->first_column=my_col;my_col+=yyleng;return LC;}
+	YY_BREAK
+case 2:
+YY_RULE_SETUP
+#line 79 "ael.flex"
+{yylloc->first_line = yylloc->last_line = my_lineno; yylloc->last_column=my_col+yyleng-1; yylloc->first_column=my_col;my_col+=yyleng;return RC;}
+	YY_BREAK
+case 3:
+YY_RULE_SETUP
+#line 80 "ael.flex"
+{yylloc->first_line = yylloc->last_line = my_lineno; yylloc->last_column=my_col+yyleng-1; yylloc->first_column=my_col;my_col+=yyleng;return LP;}
+	YY_BREAK
+case 4:
+YY_RULE_SETUP
+#line 81 "ael.flex"
+{yylloc->first_line = yylloc->last_line = my_lineno; yylloc->last_column=my_col+yyleng-1; yylloc->first_column=my_col;my_col+=yyleng;return RP;}
+	YY_BREAK
+case 5:
+YY_RULE_SETUP
+#line 82 "ael.flex"
+{yylloc->first_line = yylloc->last_line = my_lineno; yylloc->last_column=my_col+yyleng-1; yylloc->first_column=my_col;my_col+=yyleng;return SEMI;}
+	YY_BREAK
+case 6:
+YY_RULE_SETUP
+#line 83 "ael.flex"
+{yylloc->first_line = yylloc->last_line = my_lineno; yylloc->last_column=my_col+yyleng-1; yylloc->first_column=my_col;my_col+=yyleng;return EQ;}
+	YY_BREAK
+case 7:
+YY_RULE_SETUP
+#line 84 "ael.flex"
+{yylloc->first_line = yylloc->last_line = my_lineno; yylloc->last_column=my_col+yyleng-1; yylloc->first_column=my_col;my_col+=yyleng;return COMMA;}
+	YY_BREAK
+case 8:
+YY_RULE_SETUP
+#line 85 "ael.flex"
+{yylloc->first_line = yylloc->last_line = my_lineno; yylloc->last_column=my_col+yyleng-1; yylloc->first_column=my_col;my_col+=yyleng;return COLON;}
+	YY_BREAK
+case 9:
+YY_RULE_SETUP
+#line 86 "ael.flex"
+{yylloc->first_line = yylloc->last_line = my_lineno; yylloc->last_column=my_col+yyleng-1; yylloc->first_column=my_col;my_col+=yyleng;return AMPER;}
+	YY_BREAK
+case 10:
+YY_RULE_SETUP
+#line 87 "ael.flex"
+{yylloc->first_line = yylloc->last_line = my_lineno; yylloc->last_column=my_col+yyleng-1; yylloc->first_column=my_col;my_col+=yyleng;return BAR;}
+	YY_BREAK
+case 11:
+YY_RULE_SETUP
+#line 88 "ael.flex"
+{yylloc->first_line = yylloc->last_line = my_lineno; yylloc->last_column=my_col+yyleng-1; yylloc->first_column=my_col;my_col+=yyleng;return EXTENMARK;}
+	YY_BREAK
+case 12:
+YY_RULE_SETUP
+#line 89 "ael.flex"
+{yylloc->first_line = yylloc->last_line = my_lineno; yylloc->last_column=my_col+yyleng-1; yylloc->first_column=my_col;my_col+=yyleng;return AT;}
+	YY_BREAK
+case 13:
+YY_RULE_SETUP
+#line 90 "ael.flex"
+{/*comment*/}
+	YY_BREAK
+case 14:
+YY_RULE_SETUP
+#line 91 "ael.flex"
+{yylloc->first_line = yylloc->last_line = my_lineno; yylloc->last_column=my_col+yyleng-1; yylloc->first_column=my_col;my_col+=yyleng;return KW_CONTEXT;}
+	YY_BREAK
+case 15:
+YY_RULE_SETUP
+#line 92 "ael.flex"
+{yylloc->first_line = yylloc->last_line = my_lineno; yylloc->last_column=my_col+yyleng-1; yylloc->first_column=my_col;my_col+=yyleng;return KW_ABSTRACT;}
+	YY_BREAK
+case 16:
+YY_RULE_SETUP
+#line 93 "ael.flex"
+{yylloc->first_line = yylloc->last_line = my_lineno; yylloc->last_column=my_col+yyleng-1; yylloc->first_column=my_col;my_col+=yyleng;return KW_MACRO;};
+	YY_BREAK
+case 17:
+YY_RULE_SETUP
+#line 94 "ael.flex"
+{yylloc->first_line = yylloc->last_line = my_lineno; yylloc->last_column=my_col+yyleng-1; yylloc->first_column=my_col;my_col+=yyleng;return KW_GLOBALS;}
+	YY_BREAK
+case 18:
+YY_RULE_SETUP
+#line 95 "ael.flex"
+{yylloc->first_line = yylloc->last_line = my_lineno; yylloc->last_column=my_col+yyleng-1; yylloc->first_column=my_col;my_col+=yyleng;return KW_IGNOREPAT;}
+	YY_BREAK
+case 19:
+YY_RULE_SETUP
+#line 96 "ael.flex"
+{yylloc->first_line = yylloc->last_line = my_lineno; yylloc->last_column=my_col+yyleng-1; yylloc->first_column=my_col;my_col+=yyleng;return KW_SWITCH;}
+	YY_BREAK
+case 20:
+YY_RULE_SETUP
+#line 97 "ael.flex"
+{yylloc->first_line = yylloc->last_line = my_lineno; yylloc->last_column=my_col+yyleng-1; yylloc->first_column=my_col;my_col+=yyleng;return KW_IF;}
+	YY_BREAK
+case 21:
+YY_RULE_SETUP
+#line 98 "ael.flex"
+{yylloc->first_line = yylloc->last_line = my_lineno; yylloc->last_column=my_col+yyleng-1; yylloc->first_column=my_col;my_col+=yyleng;return KW_IFTIME;}
+	YY_BREAK
+case 22:
+YY_RULE_SETUP
+#line 99 "ael.flex"
+{yylloc->first_line = yylloc->last_line = my_lineno; yylloc->last_column=my_col+yyleng-1; yylloc->first_column=my_col;my_col+=yyleng;return KW_RANDOM;}
+	YY_BREAK
+case 23:
+YY_RULE_SETUP
+#line 100 "ael.flex"
+{yylloc->first_line = yylloc->last_line = my_lineno; yylloc->last_column=my_col+yyleng-1; yylloc->first_column=my_col;my_col+=yyleng;return KW_REGEXTEN;}
+	YY_BREAK
+case 24:
+YY_RULE_SETUP
+#line 101 "ael.flex"
+{yylloc->first_line = yylloc->last_line = my_lineno; yylloc->last_column=my_col+yyleng-1; yylloc->first_column=my_col;my_col+=yyleng;return KW_HINT;}
+	YY_BREAK
+case 25:
+YY_RULE_SETUP
+#line 102 "ael.flex"
+{yylloc->first_line = yylloc->last_line = my_lineno; yylloc->last_column=my_col+yyleng-1; yylloc->first_column=my_col;my_col+=yyleng;return KW_ELSE;}
+	YY_BREAK
+case 26:
+YY_RULE_SETUP
+#line 103 "ael.flex"
+{yylloc->first_line = yylloc->last_line = my_lineno; yylloc->last_column=my_col+yyleng-1; yylloc->first_column=my_col;my_col+=yyleng;return KW_GOTO;}
+	YY_BREAK
+case 27:
+YY_RULE_SETUP
+#line 104 "ael.flex"
+{yylloc->first_line = yylloc->last_line = my_lineno; yylloc->last_column=my_col+yyleng-1; yylloc->first_column=my_col;my_col+=yyleng;return KW_JUMP;}
+	YY_BREAK
+case 28:
+YY_RULE_SETUP
+#line 105 "ael.flex"
+{yylloc->first_line = yylloc->last_line = my_lineno; yylloc->last_column=my_col+yyleng-1; yylloc->first_column=my_col;my_col+=yyleng;return KW_RETURN;}
+	YY_BREAK
+case 29:
+YY_RULE_SETUP
+#line 106 "ael.flex"
+{yylloc->first_line = yylloc->last_line = my_lineno; yylloc->last_column=my_col+yyleng-1; yylloc->first_column=my_col;my_col+=yyleng;return KW_BREAK;}
+	YY_BREAK
+case 30:
+YY_RULE_SETUP
+#line 107 "ael.flex"
+{yylloc->first_line = yylloc->last_line = my_lineno; yylloc->last_column=my_col+yyleng-1; yylloc->first_column=my_col;my_col+=yyleng;return KW_CONTINUE;}
+	YY_BREAK
+case 31:
+YY_RULE_SETUP
+#line 108 "ael.flex"
+{yylloc->first_line = yylloc->last_line = my_lineno; yylloc->last_column=my_col+yyleng-1; yylloc->first_column=my_col;my_col+=yyleng;return KW_FOR;}
+	YY_BREAK
+case 32:
+YY_RULE_SETUP
+#line 109 "ael.flex"
+{yylloc->first_line = yylloc->last_line = my_lineno; yylloc->last_column=my_col+yyleng-1; yylloc->first_column=my_col;my_col+=yyleng;return KW_WHILE;}
+	YY_BREAK
+case 33:
+YY_RULE_SETUP
+#line 110 "ael.flex"
+{yylloc->first_line = yylloc->last_line = my_lineno; yylloc->last_column=my_col+yyleng-1; yylloc->first_column=my_col;my_col+=yyleng;return KW_CASE;}
+	YY_BREAK
+case 34:
+YY_RULE_SETUP
+#line 111 "ael.flex"
+{yylloc->first_line = yylloc->last_line = my_lineno; yylloc->last_column=my_col+yyleng-1; yylloc->first_column=my_col;my_col+=yyleng;return KW_DEFAULT;}
+	YY_BREAK
+case 35:
+YY_RULE_SETUP
+#line 112 "ael.flex"
+{yylloc->first_line = yylloc->last_line = my_lineno; yylloc->last_column=my_col+yyleng-1; yylloc->first_column=my_col;my_col+=yyleng;return KW_PATTERN;}
+	YY_BREAK
+case 36:
+YY_RULE_SETUP
+#line 113 "ael.flex"
+{yylloc->first_line = yylloc->last_line = my_lineno; yylloc->last_column=my_col+yyleng-1; yylloc->first_column=my_col;my_col+=yyleng;return KW_CATCH;}
+	YY_BREAK
+case 37:
+YY_RULE_SETUP
+#line 114 "ael.flex"
+{yylloc->first_line = yylloc->last_line = my_lineno; yylloc->last_column=my_col+yyleng-1; yylloc->first_column=my_col;my_col+=yyleng;return KW_SWITCHES;}
+	YY_BREAK
+case 38:
+YY_RULE_SETUP
+#line 115 "ael.flex"
+{yylloc->first_line = yylloc->last_line = my_lineno; yylloc->last_column=my_col+yyleng-1; yylloc->first_column=my_col;my_col+=yyleng;return KW_ESWITCHES;}
+	YY_BREAK
+case 39:
+YY_RULE_SETUP
+#line 116 "ael.flex"
+{yylloc->first_line = yylloc->last_line = my_lineno; yylloc->last_column=my_col+yyleng-1; yylloc->first_column=my_col;my_col+=yyleng;return KW_INCLUDES;}
+	YY_BREAK
+case 40:
+/* rule 40 can match eol */
+YY_RULE_SETUP
+#line 118 "ael.flex"
+{my_lineno++;my_col=0;}
+	YY_BREAK
+case 41:
+YY_RULE_SETUP
+#line 119 "ael.flex"
+{/* nothing */ my_col+=yyleng;}
+	YY_BREAK
+case 42:
+YY_RULE_SETUP
+#line 120 "ael.flex"
+{/* nothing */ int wid = 8-(my_col%8); my_col+=wid;}
+	YY_BREAK
+case 43:
+YY_RULE_SETUP
+#line 122 "ael.flex"
+{
+                                               yylloc->first_line = yylloc->last_line = my_lineno;yylloc->last_column=my_col+yyleng-1; yylloc->first_column=my_col; /* set up the ptr */
+                                               yylval->str = strdup(yytext);  
+                                               /* printf("\nGot WORD %s[%d][%d:%d]\n", yylval->str, my_lineno ,yylloc->first_column,yylloc->last_column );  */
+                                               my_col+=yyleng; 
+                                               prev_word = yylval->str;
+                                               return word;
+                                        }
+	YY_BREAK
+case 44:
+/* rule 44 can match eol */
+YY_RULE_SETUP
+#line 131 "ael.flex"
+{yylloc->first_line = my_lineno; yylloc->first_column=my_col; 
+                         if ( pbcpop(')') ) {
+                             /* error */
+                             int l4,c4;
+                             pbcwhere(yytext, &l4, &c4);
+                             ast_log(LOG_ERROR,"File=%s, line=%d, column=%d: Mismatched ')' in expression: %s !\n", my_file, my_lineno+l4, c4, yytext);
+                             BEGIN(0);
+                             yylloc->last_line = my_lineno+l4;
+                             yylloc->last_column=c4; 
+                             my_col=c4;
+                             my_lineno += l4;
+		                     yylval->str = strdup(yytext);
+                             prev_word = 0;
+                             return word;
+                         }
+                 parencount--;
+                 if ( parencount >= 0) {
+                   yymore();
+                 } else { 
+                   int l4,c4;
+                   pbcwhere(yytext, &l4, &c4);
+                   yylloc->last_line = my_lineno+l4;
+				   yylloc->last_column=c4; 
+                   yylval->str = strdup(yytext); 
+                   *(yylval->str+strlen(yylval->str)-1)=0;
+                   /* printf("Got paren word %s\n", yylval->str); */ 
+                   unput(')'); 
+	               my_col=c4;
+                   my_lineno += l4;
+                   BEGIN(0); 
+                   return word;
+                 } 
+                }
+	YY_BREAK
+case 45:
+/* rule 45 can match eol */
+YY_RULE_SETUP
+#line 165 "ael.flex"
+{yylloc->first_line = my_lineno; yylloc->first_column=my_col; 
+                  parencount++; pbcpush('(');
+                  yymore();
+                 }
+	YY_BREAK
+case 46:
+/* rule 46 can match eol */
+YY_RULE_SETUP
+#line 169 "ael.flex"
+{yylloc->first_line = my_lineno;yylloc->first_column=my_col; yymore(); pbcpush('['); }
+	YY_BREAK
+case 47:
+/* rule 47 can match eol */
+YY_RULE_SETUP
+#line 170 "ael.flex"
+{yylloc->first_line = my_lineno;yylloc->first_column=my_col; 
+                         if ( pbcpop(']') ) {
+                             /* error */
+                             int l4,c4;
+                             pbcwhere(yytext, &l4, &c4);
+                             ast_log(LOG_ERROR,"File=%s, line=%d, column=%d: Mismatched ']' in expression!\n", my_file, my_lineno+l4, c4);
+                             BEGIN(0);
+                             yylloc->last_line = my_lineno+l4;
+                             yylloc->last_column=c4; 
+                             my_col=c4;
+                             my_lineno += l4;
+		                     yylval->str = strdup(yytext);
+                             return word;
+                         }
+                         yymore();
+                        }
+	YY_BREAK
+case 48:
+/* rule 48 can match eol */
+YY_RULE_SETUP
+#line 186 "ael.flex"
+{yylloc->first_line = my_lineno;yylloc->first_column=my_col;  yymore(); pbcpush('{'); }
+	YY_BREAK
+case 49:
+/* rule 49 can match eol */
+YY_RULE_SETUP
+#line 187 "ael.flex"
+{yylloc->first_line = my_lineno;
+                         yylloc->first_column=my_col; 
+                         if ( pbcpop('}') ) {
+                             /* error */
+                             int l4,c4;
+                             pbcwhere(yytext, &l4, &c4);
+                             ast_log(LOG_ERROR,"File=%s, line=%d, column=%d: Mismatched '}' in expression!\n", my_file, my_lineno+l4, c4);
+                             BEGIN(0);
+                             yylloc->last_line = my_lineno+l4;
+                             yylloc->last_column=c4; 
+                             my_col=c4;
+                             my_lineno += l4;
+		                     yylval->str = strdup(yytext);
+                             return word;
+                         }
+                         yymore();
+                        }
+	YY_BREAK
+case 50:
+/* rule 50 can match eol */
+YY_RULE_SETUP
+#line 206 "ael.flex"
+{/* printf("ARGG:%s\n",yytext); */
+					int linecount = 0;
+                    int colcount = my_col;
+					char *pt = yytext;
+
+					yylloc->first_line = my_lineno;
+                    yylloc->first_column=my_col; 
+                         if ( pbcpop(')') ) {
+                             /* error */
+                             int l4,c4;
+                             pbcwhere(yytext, &l4, &c4);
+                             ast_log(LOG_ERROR,"File=%s, line=%d, column=%d: Mismatched ')' in expression!\n", my_file, my_lineno+l4, c4);
+                             BEGIN(0);
+                             yylloc->last_line = my_lineno+l4;
+                             yylloc->last_column=c4; 
+                             my_col=c4;
+                             my_lineno += l4;
+		                     yylval->str = strdup(yytext);
+                             return word;
+                         }
+                   
+
+					while (*pt) {
+                       if (*pt == '\n') {
+                           linecount++;
+                           colcount=0;
+                       }
+                       pt++;
+                       colcount++;
+                    }
+                    yylloc->last_line = my_lineno+linecount;
+                    yylloc->last_column=colcount; 
+                    parencount--;
+                    if( parencount >= 0){ 
+                        yymore(); 
+                    } else { 
+                        yylval->str = strdup(yytext); 
+					   if(yyleng > 1 ) 
+                              *(yylval->str+yyleng-1)=0;
+                       /* printf("Got argg word '%s'\n", yylval->str);  */
+                       BEGIN(0); 
+                       if ( !strcmp(yylval->str,")") ) { 
+                             free(yylval->str); 
+                             yylval->str = 0; 
+                             my_col+=1;
+                             return RP;  
+                       } else {
+                             unput(')');
+                             my_col=colcount;
+							 my_lineno+=linecount;
+                             return word;
+                       }
+                    } 
+                }
+	YY_BREAK
+case 51:
+/* rule 51 can match eol */
+YY_RULE_SETUP
+#line 260 "ael.flex"
+{ /* printf("ARGG:%s\n",yytext); */
+                      /* printf("GOT AN LP!!!\n"); */
+                      yylloc->first_line = my_lineno;
+                      yylloc->first_column=my_col; 
+                      parencount++; 
+                      pbcpush('(');
+                      yymore();
+                  }
+	YY_BREAK
+case 52:
+/* rule 52 can match eol */
+YY_RULE_SETUP
+#line 269 "ael.flex"
+{  /* printf("ARGG:%s\n",yytext); */
+                  if( parencount != 0) { 
+					/* printf("Folding in a comma!\n"); */ 
+					yymore();
+				  } else  { 
+                     /* printf("got a comma!\n\n");  */
+					 int linecount = 0;
+                     int colcount = my_col;
+					 char *pt;
+
+					 pt = yytext;
+					 while (*pt) {
+                        if ( *pt == '\n' ) {
+                           linecount++;
+                           colcount=0;
+                        }
+                        pt++;
+                        colcount++;
+                     }
+                     yylloc->first_line = my_lineno; 
+                     yylloc->last_line = my_lineno+linecount; 
+                     yylloc->last_column=colcount; 
+                     yylloc->first_column=my_col;
+                     if( !commaout ) { 
+						if( !strcmp(yytext,"," ) ) 
+							{commaout = 0; my_col+=1; return COMMA;} 
+						yylval->str = strdup(yytext); /* printf("Got argg2 word %s\n", yylval->str); */ 
+						unput(','); 
+						commaout = 1; 
+						if(yyleng > 1 ) 
+							*(yylval->str+yyleng-1)=0;
+                        my_lineno+=linecount;
+						my_col=colcount;
+						return word;
+					 } else {
+                            commaout = 0;
+							my_col+=1;
+							return COMMA;
+						}
+                   }
+				}
+	YY_BREAK
+case 53:
+/* rule 53 can match eol */
+YY_RULE_SETUP
+#line 311 "ael.flex"
+{/*printf("ARGG:%s\n",yytext);*/yylloc->first_line = my_lineno;yylloc->first_column=my_col; pbcpush('{'); yymore();  }
+	YY_BREAK
+case 54:
+/* rule 54 can match eol */
+YY_RULE_SETUP
+#line 312 "ael.flex"
+{/*printf("ARGG:%s\n",yytext);*/yylloc->first_line = my_lineno;yylloc->first_column=my_col; 
+                         if ( pbcpop('}') ) {
+                             /* error */
+                             int l4,c4;
+                             pbcwhere(yytext, &l4, &c4);
+                             ast_log(LOG_ERROR,"File=%s, line=%d, column=%d: Mismatched '}' in expression!\n", my_file, my_lineno+l4, my_col+c4);
+                             BEGIN(0);
+                             yylloc->last_line = my_lineno+l4;
+                             yylloc->last_column=my_col+c4; 
+                             my_col=c4;
+                             my_lineno += l4;
+		                     yylval->str = strdup(yytext);
+                             return word;
+                         }
+                         yymore();
+				}
+	YY_BREAK
+case 55:
+/* rule 55 can match eol */
+YY_RULE_SETUP
+#line 328 "ael.flex"
+{/*printf("ARGG:%s\n",yytext);*/yylloc->first_line = my_lineno;yylloc->first_column=my_col; yymore(); pbcpush('['); }
+	YY_BREAK
+case 56:
+/* rule 56 can match eol */
+YY_RULE_SETUP
+#line 329 "ael.flex"
+{/*printf("ARGG:%s\n",yytext);*/yylloc->first_line = my_lineno;yylloc->first_column=my_col; 
+                         if ( pbcpop(']') ) {
+                             /* error */
+                             int l4,c4;
+                             pbcwhere(yytext, &l4, &c4);
+                             ast_log(LOG_ERROR,"File=%s, line=%d, column=%d: Mismatched ']' in expression!\n", my_file, my_lineno+l4, c4);
+                             BEGIN(0);
+                             yylloc->last_line = my_lineno+l4;
+                             yylloc->last_column=c4; 
+                             my_col=c4;
+                             my_lineno += l4;
+		                     yylval->str = strdup(yytext);
+                             return word;
+                         }
+                         yymore();
+				}
+	YY_BREAK
+case 57:
+/* rule 57 can match eol */
+YY_RULE_SETUP
+#line 347 "ael.flex"
+{/*printf("SEMIC:%s\n",yytext);*/yylloc->first_line = my_lineno;yylloc->first_column=my_col; yymore(); pbcpush('['); }
+	YY_BREAK
+case 58:
+/* rule 58 can match eol */
+YY_RULE_SETUP
+#line 348 "ael.flex"
+{/*printf("SEMIC:%s\n",yytext);*/yylloc->first_line = my_lineno;yylloc->first_column=my_col; 
+                         if ( pbcpop(']') ) {
+                             /* error */
+                             int l4,c4;
+                             pbcwhere(yytext, &l4, &c4);
+                             ast_log(LOG_ERROR,"File=%s, line=%d, column=%d: Mismatched ']' in expression!\n", my_file, my_lineno+l4, c4);
+                             BEGIN(0);
+                             yylloc->last_line = my_lineno+l4;
+                             yylloc->last_column=c4; 
+                             my_col=c4;
+                             my_lineno += l4;
+		                     yylval->str = strdup(yytext);
+                             return word;
+                         }
+                         yymore();}
+	YY_BREAK
+case 59:
+/* rule 59 can match eol */
+YY_RULE_SETUP
+#line 363 "ael.flex"
+{/*printf("SEMIC:%s\n",yytext);*/yylloc->first_line = my_lineno;yylloc->first_column=my_col; yymore(); pbcpush('{');}
+	YY_BREAK
+case 60:
+/* rule 60 can match eol */
+YY_RULE_SETUP
+#line 364 "ael.flex"
+{/*printf("SEMIC:%s\n",yytext);*/yylloc->first_line = my_lineno;yylloc->first_column=my_col; 
+                         if ( pbcpop('}') ) {
+                             /* error */
+                             int l4,c4;
+                             pbcwhere(yytext, &l4, &c4);
+                             ast_log(LOG_ERROR,"File=%s, line=%d, column=%d: Mismatched '}' in expression!\n", my_file, my_lineno+l4, my_col+c4);
+                             BEGIN(0);
+                             yylloc->last_line = my_lineno+l4;
+                             yylloc->last_column=my_col+c4; 
+                             my_col=c4;
+                             my_lineno += l4;
+		                     yylval->str = strdup(yytext);
+                             return word;
+                         }
+                         yymore();}
+	YY_BREAK
+case 61:
+/* rule 61 can match eol */
+YY_RULE_SETUP
+#line 379 "ael.flex"
+{/*printf("SEMIC:%s\n",yytext);*/yylloc->first_line = my_lineno;yylloc->first_column=my_col; yymore(); pbcpush('(');}
+	YY_BREAK
+case 62:
+/* rule 62 can match eol */
+YY_RULE_SETUP
+#line 380 "ael.flex"
+{/*printf("SEMIC:%s\n",yytext);*/yylloc->first_line = my_lineno;yylloc->first_column=my_col; 
+                         if ( pbcpop(')') ) {
+                             /* error */
+                             int l4,c4;
+                             pbcwhere(yytext, &l4, &c4);
+                             ast_log(LOG_ERROR,"File=%s, line=%d, column=%d: Mismatched ')' in expression!\n", my_file, my_lineno+l4, my_col+c4);
+                             BEGIN(0);
+                             yylloc->last_line = my_lineno+l4;
+                             yylloc->last_column=my_col+c4; 
+                             my_col=c4;
+                             my_lineno += l4;
+		                     yylval->str = strdup(yytext);
+                             return word;
+                         }
+                         yymore();}
+	YY_BREAK
+case 63:
+/* rule 63 can match eol */
+YY_RULE_SETUP
+#line 395 "ael.flex"
+{
+					int linecount = 0;
+                    int colcount = my_col;
+					char *pt = yytext;
+					while (*pt) {
+                       if ( *pt == '\n' ) {
+                           linecount++;
+                           colcount=0;
+                       }
+                       pt++;
+                       colcount++;
+                    }
+                    yylloc->first_line = my_lineno; 
+					yylloc->last_line = my_lineno+linecount; 
+					yylloc->last_column=colcount; 
+					yylloc->first_column=my_col;
+                    yylval->str = strdup(yytext);
+                    if(yyleng > 1)
+                      *(yylval->str+yyleng-1)=0;
+                    /* printf("Got semic word %s\n", yylval->str); */
+                    unput(';');
+                    BEGIN(0);
+                    my_col=colcount;
+                    my_lineno += linecount;
+                    return word;
+                }
+	YY_BREAK
+case 64:
+/* rule 64 can match eol */
+YY_RULE_SETUP
+#line 422 "ael.flex"
+{
+                     FILE *in1;
+					 char fnamebuf[1024],*p1,*p2;
+                     if ( include_stack_index >= MAX_INCLUDE_DEPTH ) {
+						ast_log(LOG_ERROR,"File=%s, line=%d, column=%d: Includes nested too deeply! Wow!!! How did you do that?\n", my_file, my_lineno, my_col);
+                     } else {
+                         p1 = strchr(yytext,'"');
+                         p2 = strrchr(yytext,'"');
+                         if ( (int)(p2-p1) > 1023 ) {
+							ast_log(LOG_ERROR,"File=%s, line=%d, column=%d: Filename is incredibly way too long (%d chars!). Inclusion ignored!\n", my_file, my_lineno, my_col, yyleng - 10);
+        	             } else {
+								int i;
+								int found = 0;
+								strncpy(fnamebuf,p1,p2-p1);
+								fnamebuf[p2-p1] = 0;
+								for (i=0; i<include_stack_index; i++) {
+									if ( !strcmp(fnamebuf,include_stack[i].fname )) {
+										ast_log(LOG_ERROR,"File=%s, line=%d, column=%d: Nice Try!!! But %s has already been included (perhaps by another file), and would cause an infinite loop of file inclusions!!! Include directive ignored\n", 
+												my_file, my_lineno, my_col, fnamebuf);
+										found=1;
+										break;
+									}
+								}
+								if( !found )
+								{
+                                	*p2 = 0;
+                                    /* relative vs. absolute */
+                                    if ( *(p1+1) != '/' )
+                                    {
+                                        strcpy(fnamebuf,ast_config_AST_CONFIG_DIR);
+										strcat(fnamebuf,"/");
+										strcat(fnamebuf,p1+1);
+                                    }
+                                    else
+                                	    strcpy(fnamebuf,p1+1);
+		                        	in1 = fopen( fnamebuf, "r" );
+                                	if ( ! in1 ) {
+						ast_log(LOG_ERROR,"File=%s, line=%d, column=%d: Couldn't find the include file: %s; ignoring the Include directive!\n", my_file, my_lineno, my_col, fnamebuf);
+                                	} else {
+						char *buffer;
+	                             	 	struct stat stats;
+	                            		stat(fnamebuf, &stats);
+	                             		buffer = (char*)malloc(stats.st_size+1);
+	                             		fread(buffer, 1, stats.st_size, in1);
+						buffer[stats.st_size] = 0;
+						ast_log(LOG_NOTICE,"  --Read in included file %s, %d chars\n",fnamebuf, (int)stats.st_size);
+	                                	fclose(in1);
+
+						include_stack[include_stack_index].fname = my_file;
+						my_file = strdup(fnamebuf);
+						include_stack[include_stack_index].lineno = my_lineno;
+						include_stack[include_stack_index].colno = my_col+yyleng;
+						include_stack[include_stack_index++].bufstate = YY_CURRENT_BUFFER;
+
+	                                	ael_yy_switch_to_buffer(ael_yy_scan_string (buffer ,yyscanner),yyscanner);
+                                    		free(buffer);
+                                  	  	my_lineno = 1;
+                                    		my_col = 1;
+                                    		BEGIN(INITIAL);
+                                	}
+                                }
+                         }
+                     }
+                 }
+	YY_BREAK
+case YY_STATE_EOF(INITIAL):
+case YY_STATE_EOF(paren):
+case YY_STATE_EOF(semic):
+case YY_STATE_EOF(argg):
+#line 487 "ael.flex"
+{
+                 if ( --include_stack_index < 0 ) {
+                 	    yyterminate();
+                     } else {
+						 free(my_file);
+                         ael_yy_delete_buffer(YY_CURRENT_BUFFER,yyscanner );
+                         ael_yy_switch_to_buffer(include_stack[include_stack_index].bufstate,yyscanner );
+                         my_lineno = include_stack[include_stack_index].lineno;
+                         my_col    = include_stack[include_stack_index].colno;
+                         my_file   = include_stack[include_stack_index].fname;
+                     }
+          }
+	YY_BREAK
+case 65:
+YY_RULE_SETUP
+#line 501 "ael.flex"
+ECHO;
+	YY_BREAK
+#line 1732 "ael_lex.c"
+
+	case YY_END_OF_BUFFER:
+		{
+		/* Amount of text matched not including the EOB char. */
+		int yy_amount_of_matched_text = (int) (yy_cp - yyg->yytext_ptr) - 1;
+
+		/* Undo the effects of YY_DO_BEFORE_ACTION. */
+		*yy_cp = yyg->yy_hold_char;
+		YY_RESTORE_YY_MORE_OFFSET
+
+		if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW )
+			{
+			/* We're scanning a new file or input source.  It's
+			 * possible that this happened because the user
+			 * just pointed yyin at a new source and called
+			 * ael_yylex().  If so, then we have to assure
+			 * consistency between YY_CURRENT_BUFFER and our
+			 * globals.  Here is the right place to do so, because
+			 * this is the first action (other than possibly a
+			 * back-up) that will match for the new input source.
+			 */
+			yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
+			YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin;
+			YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL;
+			}
+
+		/* Note that here we test for yy_c_buf_p "<=" to the position
+		 * of the first EOB in the buffer, since yy_c_buf_p will
+		 * already have been incremented past the NUL character
+		 * (since all states make transitions on EOB to the
+		 * end-of-buffer state).  Contrast this with the test
+		 * in input().
+		 */
+		if ( yyg->yy_c_buf_p <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] )
+			{ /* This was really a NUL. */
+			yy_state_type yy_next_state;
+
+			yyg->yy_c_buf_p = yyg->yytext_ptr + yy_amount_of_matched_text;
+
+			yy_current_state = yy_get_previous_state( yyscanner );
+
+			/* Okay, we're now positioned to make the NUL
+			 * transition.  We couldn't have
+			 * yy_get_previous_state() go ahead and do it
+			 * for us because it doesn't know how to deal
+			 * with the possibility of jamming (and we don't
+			 * want to build jamming into it because then it
+			 * will run more slowly).
+			 */
+
+			yy_next_state = yy_try_NUL_trans( yy_current_state , yyscanner);
+
+			yy_bp = yyg->yytext_ptr + YY_MORE_ADJ;
+
+			if ( yy_next_state )
+				{
+				/* Consume the NUL. */
+				yy_cp = ++yyg->yy_c_buf_p;
+				yy_current_state = yy_next_state;
+				goto yy_match;
+				}
+
+			else
+				{
+				yy_cp = yyg->yy_last_accepting_cpos;
+				yy_current_state = yyg->yy_last_accepting_state;
+				goto yy_find_action;
+				}
+			}
+
+		else switch ( yy_get_next_buffer( yyscanner ) )
+			{
+			case EOB_ACT_END_OF_FILE:
+				{
+				yyg->yy_did_buffer_switch_on_eof = 0;
+
+				if ( ael_yywrap(yyscanner ) )
+					{
+					/* Note: because we've taken care in
+					 * yy_get_next_buffer() to have set up
+					 * yytext, we can now set up
+					 * yy_c_buf_p so that if some total
+					 * hoser (like flex itself) wants to
+					 * call the scanner after we return the
+					 * YY_NULL, it'll still work - another
+					 * YY_NULL will get returned.
+					 */
+					yyg->yy_c_buf_p = yyg->yytext_ptr + YY_MORE_ADJ;
+
+					yy_act = YY_STATE_EOF(YY_START);
+					goto do_action;
+					}
+
+				else
+					{
+					if ( ! yyg->yy_did_buffer_switch_on_eof )
+						YY_NEW_FILE;
+					}
+				break;
+				}
+
+			case EOB_ACT_CONTINUE_SCAN:
+				yyg->yy_c_buf_p =
+					yyg->yytext_ptr + yy_amount_of_matched_text;
+
+				yy_current_state = yy_get_previous_state( yyscanner );
+
+				yy_cp = yyg->yy_c_buf_p;
+				yy_bp = yyg->yytext_ptr + YY_MORE_ADJ;
+				goto yy_match;
+
+			case EOB_ACT_LAST_MATCH:
+				yyg->yy_c_buf_p =
+				&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars];
+
+				yy_current_state = yy_get_previous_state( yyscanner );
+
+				yy_cp = yyg->yy_c_buf_p;
+				yy_bp = yyg->yytext_ptr + YY_MORE_ADJ;
+				goto yy_find_action;
+			}
+		break;
+		}
+
+	default:
+		YY_FATAL_ERROR(
+			"fatal flex scanner internal error--no action found" );
+	} /* end of action switch */
+		} /* end of scanning one token */
+} /* end of ael_yylex */
+
+/* yy_get_next_buffer - try to read in a new buffer
+ *
+ * Returns a code representing an action:
+ *	EOB_ACT_LAST_MATCH -
+ *	EOB_ACT_CONTINUE_SCAN - continue scanning from current position
+ *	EOB_ACT_END_OF_FILE - end of file
+ */
+static int yy_get_next_buffer (yyscan_t yyscanner)
+{
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+	register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf;
+	register char *source = yyg->yytext_ptr;
+	register int number_to_move, i;
+	int ret_val;
+
+	if ( yyg->yy_c_buf_p > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars + 1] )
+		YY_FATAL_ERROR(
+		"fatal flex scanner internal error--end of buffer missed" );
+
+	if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 )
+		{ /* Don't try to fill the buffer, so this is an EOF. */
+		if ( yyg->yy_c_buf_p - yyg->yytext_ptr - YY_MORE_ADJ == 1 )
+			{
+			/* We matched a single character, the EOB, so
+			 * treat this as a final EOF.
+			 */
+			return EOB_ACT_END_OF_FILE;
+			}
+
+		else
+			{
+			/* We matched some text prior to the EOB, first
+			 * process it.
+			 */
+			return EOB_ACT_LAST_MATCH;
+			}
+		}
+
+	/* Try to read more data. */
+
+	/* First move last chars to start of buffer. */
+	number_to_move = (int) (yyg->yy_c_buf_p - yyg->yytext_ptr) - 1;
+
+	for ( i = 0; i < number_to_move; ++i )
+		*(dest++) = *(source++);
+
+	if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING )
+		/* don't do the read, it's not guaranteed to return an EOF,
+		 * just force an EOF
+		 */
+		YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars = 0;
+
+	else
+		{
+			int num_to_read =
+			YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1;
+
+		while ( num_to_read <= 0 )
+			{ /* Not enough room in the buffer - grow it. */
+
+			/* just a shorter name for the current buffer */
+			YY_BUFFER_STATE b = YY_CURRENT_BUFFER;
+
+			int yy_c_buf_p_offset =
+				(int) (yyg->yy_c_buf_p - b->yy_ch_buf);
+
+			if ( b->yy_is_our_buffer )
+				{
+				int new_size = b->yy_buf_size * 2;
+
+				if ( new_size <= 0 )
+					b->yy_buf_size += b->yy_buf_size / 8;
+				else
+					b->yy_buf_size *= 2;
+
+				b->yy_ch_buf = (char *)
+					/* Include room in for 2 EOB chars. */
+					ael_yyrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 ,yyscanner );
+				}
+			else
+				/* Can't grow it, we don't own it. */
+				b->yy_ch_buf = 0;
+
+			if ( ! b->yy_ch_buf )
+				YY_FATAL_ERROR(
+				"fatal error - scanner input buffer overflow" );
+
+			yyg->yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset];
+
+			num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size -
+						number_to_move - 1;
+
+			}
+
+		if ( num_to_read > YY_READ_BUF_SIZE )
+			num_to_read = YY_READ_BUF_SIZE;
+
+		/* Read in more data. */
+		YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]),
+			yyg->yy_n_chars, num_to_read );
+
+		YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars;
+		}
+
+	if ( yyg->yy_n_chars == 0 )
+		{
+		if ( number_to_move == YY_MORE_ADJ )
+			{
+			ret_val = EOB_ACT_END_OF_FILE;
+			ael_yyrestart(yyin  ,yyscanner);
+			}
+
+		else
+			{
+			ret_val = EOB_ACT_LAST_MATCH;
+			YY_CURRENT_BUFFER_LVALUE->yy_buffer_status =
+				YY_BUFFER_EOF_PENDING;
+			}
+		}
+
+	else
+		ret_val = EOB_ACT_CONTINUE_SCAN;
+
+	yyg->yy_n_chars += number_to_move;
+	YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] = YY_END_OF_BUFFER_CHAR;
+	YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR;
+
+	yyg->yytext_ptr = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0];
+
+	return ret_val;
+}
+
+/* yy_get_previous_state - get the state just before the EOB char was reached */
+
+    static yy_state_type yy_get_previous_state (yyscan_t yyscanner)
+{
+	register yy_state_type yy_current_state;
+	register char *yy_cp;
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+	yy_current_state = yyg->yy_start;
+
+	for ( yy_cp = yyg->yytext_ptr + YY_MORE_ADJ; yy_cp < yyg->yy_c_buf_p; ++yy_cp )
+		{
+		register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1);
+		if ( yy_accept[yy_current_state] )
+			{
+			yyg->yy_last_accepting_state = yy_current_state;
+			yyg->yy_last_accepting_cpos = yy_cp;
+			}
+		while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+			{
+			yy_current_state = (int) yy_def[yy_current_state];
+			if ( yy_current_state >= 226 )
+				yy_c = yy_meta[(unsigned int) yy_c];
+			}
+		yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+		}
+
+	return yy_current_state;
+}
+
+/* yy_try_NUL_trans - try to make a transition on the NUL character
+ *
+ * synopsis
+ *	next_state = yy_try_NUL_trans( current_state );
+ */
+    static yy_state_type yy_try_NUL_trans  (yy_state_type yy_current_state , yyscan_t yyscanner)
+{
+	register int yy_is_jam;
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; /* This var may be unused depending upon options. */
+	register char *yy_cp = yyg->yy_c_buf_p;
+
+	register YY_CHAR yy_c = 1;
+	if ( yy_accept[yy_current_state] )
+		{
+		yyg->yy_last_accepting_state = yy_current_state;
+		yyg->yy_last_accepting_cpos = yy_cp;
+		}
+	while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+		{
+		yy_current_state = (int) yy_def[yy_current_state];
+		if ( yy_current_state >= 226 )
+			yy_c = yy_meta[(unsigned int) yy_c];
+		}
+	yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+	yy_is_jam = (yy_current_state == 225);
+
+	return yy_is_jam ? 0 : yy_current_state;
+}
+
+    static void yyunput (int c, register char * yy_bp , yyscan_t yyscanner)
+{
+	register char *yy_cp;
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+    yy_cp = yyg->yy_c_buf_p;
+
+	/* undo effects of setting up yytext */
+	*yy_cp = yyg->yy_hold_char;
+
+	if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 )
+		{ /* need to shift things up to make room */
+		/* +2 for EOB chars. */
+		register int number_to_move = yyg->yy_n_chars + 2;
+		register char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[
+					YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2];
+		register char *source =
+				&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move];
+
+		while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
+			*--dest = *--source;
+
+		yy_cp += (int) (dest - source);
+		yy_bp += (int) (dest - source);
+		YY_CURRENT_BUFFER_LVALUE->yy_n_chars =
+			yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_buf_size;
+
+		if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 )
+			YY_FATAL_ERROR( "flex scanner push-back overflow" );
+		}
+
+	*--yy_cp = (char) c;
+
+	yyg->yytext_ptr = yy_bp;
+	yyg->yy_hold_char = *yy_cp;
+	yyg->yy_c_buf_p = yy_cp;
+}
+
+#ifndef YY_NO_INPUT
+#ifdef __cplusplus
+    static int yyinput (yyscan_t yyscanner)
+#else
+    static int input  (yyscan_t yyscanner)
+#endif
+
+{
+	int c;
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+	*yyg->yy_c_buf_p = yyg->yy_hold_char;
+
+	if ( *yyg->yy_c_buf_p == YY_END_OF_BUFFER_CHAR )
+		{
+		/* yy_c_buf_p now points to the character we want to return.
+		 * If this occurs *before* the EOB characters, then it's a
+		 * valid NUL; if not, then we've hit the end of the buffer.
+		 */
+		if ( yyg->yy_c_buf_p < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] )
+			/* This was really a NUL. */
+			*yyg->yy_c_buf_p = '\0';
+
+		else
+			{ /* need more input */
+			int offset = yyg->yy_c_buf_p - yyg->yytext_ptr;
+			++yyg->yy_c_buf_p;
+
+			switch ( yy_get_next_buffer( yyscanner ) )
+				{
+				case EOB_ACT_LAST_MATCH:
+					/* This happens because yy_g_n_b()
+					 * sees that we've accumulated a
+					 * token and flags that we need to
+					 * try matching the token before
+					 * proceeding.  But for input(),
+					 * there's no matching to consider.
+					 * So convert the EOB_ACT_LAST_MATCH
+					 * to EOB_ACT_END_OF_FILE.
+					 */
+
+					/* Reset buffer status. */
+					ael_yyrestart(yyin ,yyscanner);
+
+					/*FALLTHROUGH*/
+
+				case EOB_ACT_END_OF_FILE:
+					{
+					if ( ael_yywrap(yyscanner ) )
+						return EOF;
+
+					if ( ! yyg->yy_did_buffer_switch_on_eof )
+						YY_NEW_FILE;
+#ifdef __cplusplus
+					return yyinput(yyscanner);
+#else
+					return input(yyscanner);
+#endif
+					}
+
+				case EOB_ACT_CONTINUE_SCAN:
+					yyg->yy_c_buf_p = yyg->yytext_ptr + offset;
+					break;
+				}
+			}
+		}
+
+	c = *(unsigned char *) yyg->yy_c_buf_p;	/* cast for 8-bit char's */
+	*yyg->yy_c_buf_p = '\0';	/* preserve yytext */
+	yyg->yy_hold_char = *++yyg->yy_c_buf_p;
+
+	return c;
+}
+#endif	/* ifndef YY_NO_INPUT */
+
+/** Immediately switch to a different input stream.
+ * @param input_file A readable stream.
+ * @param yyscanner The scanner object.
+ * @note This function does not reset the start condition to @c INITIAL .
+ */
+    void ael_yyrestart  (FILE * input_file , yyscan_t yyscanner)
+{
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+	if ( ! YY_CURRENT_BUFFER ){
+        ael_yyensure_buffer_stack (yyscanner);
+		YY_CURRENT_BUFFER_LVALUE =
+            ael_yy_create_buffer(yyin,YY_BUF_SIZE ,yyscanner);
+	}
+
+	ael_yy_init_buffer(YY_CURRENT_BUFFER,input_file ,yyscanner);
+	ael_yy_load_buffer_state(yyscanner );
+}
+
+/** Switch to a different input buffer.
+ * @param new_buffer The new input buffer.
+ * @param yyscanner The scanner object.
+ */
+    void ael_yy_switch_to_buffer  (YY_BUFFER_STATE  new_buffer , yyscan_t yyscanner)
+{
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+	/* TODO. We should be able to replace this entire function body
+	 * with
+	 *		ael_yypop_buffer_state();
+	 *		ael_yypush_buffer_state(new_buffer);
+     */
+	ael_yyensure_buffer_stack (yyscanner);
+	if ( YY_CURRENT_BUFFER == new_buffer )
+		return;
+
+	if ( YY_CURRENT_BUFFER )
+		{
+		/* Flush out information for old buffer. */
+		*yyg->yy_c_buf_p = yyg->yy_hold_char;
+		YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = yyg->yy_c_buf_p;
+		YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars;
+		}
+
+	YY_CURRENT_BUFFER_LVALUE = new_buffer;
+	ael_yy_load_buffer_state(yyscanner );
+
+	/* We don't actually know whether we did this switch during
+	 * EOF (ael_yywrap()) processing, but the only time this flag
+	 * is looked at is after ael_yywrap() is called, so it's safe
+	 * to go ahead and always set it.
+	 */
+	yyg->yy_did_buffer_switch_on_eof = 1;
+}
+
+static void ael_yy_load_buffer_state  (yyscan_t yyscanner)
+{
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+	yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
+	yyg->yytext_ptr = yyg->yy_c_buf_p = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos;
+	yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file;
+	yyg->yy_hold_char = *yyg->yy_c_buf_p;
+}
+
+/** Allocate and initialize an input buffer state.
+ * @param file A readable stream.
+ * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE.
+ * @param yyscanner The scanner object.
+ * @return the allocated buffer state.
+ */
+    YY_BUFFER_STATE ael_yy_create_buffer  (FILE * file, int  size , yyscan_t yyscanner)
+{
+	YY_BUFFER_STATE b;
+    
+	b = (YY_BUFFER_STATE) ael_yyalloc(sizeof( struct yy_buffer_state ) ,yyscanner );
+	if ( ! b )
+		YY_FATAL_ERROR( "out of dynamic memory in ael_yy_create_buffer()" );
+
+	b->yy_buf_size = size;
+
+	/* yy_ch_buf has to be 2 characters longer than the size given because
+	 * we need to put in 2 end-of-buffer characters.
+	 */
+	b->yy_ch_buf = (char *) ael_yyalloc(b->yy_buf_size + 2 ,yyscanner );
+	if ( ! b->yy_ch_buf )
+		YY_FATAL_ERROR( "out of dynamic memory in ael_yy_create_buffer()" );
+
+	b->yy_is_our_buffer = 1;
+
+	ael_yy_init_buffer(b,file ,yyscanner);
+
+	return b;
+}
+
+/** Destroy the buffer.
+ * @param b a buffer created with ael_yy_create_buffer()
+ * @param yyscanner The scanner object.
+ */
+    void ael_yy_delete_buffer (YY_BUFFER_STATE  b , yyscan_t yyscanner)
+{
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+	if ( ! b )
+		return;
+
+	if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */
+		YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0;
+
+	if ( b->yy_is_our_buffer )
+		ael_yyfree((void *) b->yy_ch_buf ,yyscanner );
+
+	ael_yyfree((void *) b ,yyscanner );
+}
+
+#ifndef __cplusplus
+extern int isatty (int );
+#endif /* __cplusplus */
+    
+/* Initializes or reinitializes a buffer.
+ * This function is sometimes called more than once on the same buffer,
+ * such as during a ael_yyrestart() or at EOF.
+ */
+    static void ael_yy_init_buffer  (YY_BUFFER_STATE  b, FILE * file , yyscan_t yyscanner)
+
+{
+	int oerrno = errno;
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+	ael_yy_flush_buffer(b ,yyscanner);
+
+	b->yy_input_file = file;
+	b->yy_fill_buffer = 1;
+
+    /* If b is the current buffer, then ael_yy_init_buffer was _probably_
+     * called from ael_yyrestart() or through yy_get_next_buffer.
+     * In that case, we don't want to reset the lineno or column.
+     */
+    if (b != YY_CURRENT_BUFFER){
+        b->yy_bs_lineno = 1;
+        b->yy_bs_column = 0;
+    }
+
+        b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0;
+    
+	errno = oerrno;
+}
+
+/** Discard all buffered characters. On the next scan, YY_INPUT will be called.
+ * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER.
+ * @param yyscanner The scanner object.
+ */
+    void ael_yy_flush_buffer (YY_BUFFER_STATE  b , yyscan_t yyscanner)
+{
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+	if ( ! b )
+		return;
+
+	b->yy_n_chars = 0;
+
+	/* We always need two end-of-buffer characters.  The first causes
+	 * a transition to the end-of-buffer state.  The second causes
+	 * a jam in that state.
+	 */
+	b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR;
+	b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR;
+
+	b->yy_buf_pos = &b->yy_ch_buf[0];
+
+	b->yy_at_bol = 1;
+	b->yy_buffer_status = YY_BUFFER_NEW;
+
+	if ( b == YY_CURRENT_BUFFER )
+		ael_yy_load_buffer_state(yyscanner );
+}
+
+/** Pushes the new state onto the stack. The new state becomes
+ *  the current state. This function will allocate the stack
+ *  if necessary.
+ *  @param new_buffer The new state.
+ *  @param yyscanner The scanner object.
+ */
+void ael_yypush_buffer_state (YY_BUFFER_STATE new_buffer , yyscan_t yyscanner)
+{
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+	if (new_buffer == NULL)
+		return;
+
+	ael_yyensure_buffer_stack(yyscanner);
+
+	/* This block is copied from ael_yy_switch_to_buffer. */
+	if ( YY_CURRENT_BUFFER )
+		{
+		/* Flush out information for old buffer. */
+		*yyg->yy_c_buf_p = yyg->yy_hold_char;
+		YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = yyg->yy_c_buf_p;
+		YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars;
+		}
+
+	/* Only push if top exists. Otherwise, replace top. */
+	if (YY_CURRENT_BUFFER)
+		yyg->yy_buffer_stack_top++;
+	YY_CURRENT_BUFFER_LVALUE = new_buffer;
+
+	/* copied from ael_yy_switch_to_buffer. */
+	ael_yy_load_buffer_state(yyscanner );
+	yyg->yy_did_buffer_switch_on_eof = 1;
+}
+
+/** Removes and deletes the top of the stack, if present.
+ *  The next element becomes the new top.
+ *  @param yyscanner The scanner object.
+ */
+void ael_yypop_buffer_state (yyscan_t yyscanner)
+{
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+	if (!YY_CURRENT_BUFFER)
+		return;
+
+	ael_yy_delete_buffer(YY_CURRENT_BUFFER ,yyscanner);
+	YY_CURRENT_BUFFER_LVALUE = NULL;
+	if (yyg->yy_buffer_stack_top > 0)
+		--yyg->yy_buffer_stack_top;
+
+	if (YY_CURRENT_BUFFER) {
+		ael_yy_load_buffer_state(yyscanner );
+		yyg->yy_did_buffer_switch_on_eof = 1;
+	}
+}
+
+/* Allocates the stack if it does not exist.
+ *  Guarantees space for at least one push.
+ */
+static void ael_yyensure_buffer_stack (yyscan_t yyscanner)
+{
+	int num_to_alloc;
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+	if (!yyg->yy_buffer_stack) {
+
+		/* First allocation is just for 2 elements, since we don't know if this
+		 * scanner will even need a stack. We use 2 instead of 1 to avoid an
+		 * immediate realloc on the next call.
+         */
+		num_to_alloc = 1;
+		yyg->yy_buffer_stack = (struct yy_buffer_state**)ael_yyalloc
+								(num_to_alloc * sizeof(struct yy_buffer_state*)
+								, yyscanner);
+		
+		memset(yyg->yy_buffer_stack, 0, num_to_alloc * sizeof(struct yy_buffer_state*));
+				
+		yyg->yy_buffer_stack_max = num_to_alloc;
+		yyg->yy_buffer_stack_top = 0;
+		return;
+	}
+
+	if (yyg->yy_buffer_stack_top >= (yyg->yy_buffer_stack_max) - 1){
+
+		/* Increase the buffer to prepare for a possible push. */
+		int grow_size = 8 /* arbitrary grow size */;
+
+		num_to_alloc = yyg->yy_buffer_stack_max + grow_size;
+		yyg->yy_buffer_stack = (struct yy_buffer_state**)ael_yyrealloc
+								(yyg->yy_buffer_stack,
+								num_to_alloc * sizeof(struct yy_buffer_state*)
+								, yyscanner);
+
+		/* zero only the new slots.*/
+		memset(yyg->yy_buffer_stack + yyg->yy_buffer_stack_max, 0, grow_size * sizeof(struct yy_buffer_state*));
+		yyg->yy_buffer_stack_max = num_to_alloc;
+	}
+}
+
+/** Setup the input buffer state to scan directly from a user-specified character buffer.
+ * @param base the character buffer
+ * @param size the size in bytes of the character buffer
+ * @param yyscanner The scanner object.
+ * @return the newly allocated buffer state object. 
+ */
+YY_BUFFER_STATE ael_yy_scan_buffer  (char * base, yy_size_t  size , yyscan_t yyscanner)
+{
+	YY_BUFFER_STATE b;
+    
+	if ( size < 2 ||
+	     base[size-2] != YY_END_OF_BUFFER_CHAR ||
+	     base[size-1] != YY_END_OF_BUFFER_CHAR )
+		/* They forgot to leave room for the EOB's. */
+		return 0;
+
+	b = (YY_BUFFER_STATE) ael_yyalloc(sizeof( struct yy_buffer_state ) ,yyscanner );
+	if ( ! b )
+		YY_FATAL_ERROR( "out of dynamic memory in ael_yy_scan_buffer()" );
+
+	b->yy_buf_size = size - 2;	/* "- 2" to take care of EOB's */
+	b->yy_buf_pos = b->yy_ch_buf = base;
+	b->yy_is_our_buffer = 0;
+	b->yy_input_file = 0;
+	b->yy_n_chars = b->yy_buf_size;
+	b->yy_is_interactive = 0;
+	b->yy_at_bol = 1;
+	b->yy_fill_buffer = 0;
+	b->yy_buffer_status = YY_BUFFER_NEW;
+
+	ael_yy_switch_to_buffer(b ,yyscanner );
+
+	return b;
+}
+
+/** Setup the input buffer state to scan a string. The next call to ael_yylex() will
+ * scan from a @e copy of @a str.
+ * @param yystr a NUL-terminated string to scan
+ * @param yyscanner The scanner object.
+ * @return the newly allocated buffer state object.
+ * @note If you want to scan bytes that may contain NUL values, then use
+ *       ael_yy_scan_bytes() instead.
+ */
+YY_BUFFER_STATE ael_yy_scan_string (yyconst char * yystr , yyscan_t yyscanner)
+{
+    
+	return ael_yy_scan_bytes(yystr,strlen(yystr) ,yyscanner);
+}
+
+/** Setup the input buffer state to scan the given bytes. The next call to ael_yylex() will
+ * scan from a @e copy of @a bytes.
+ * @param bytes the byte buffer to scan
+ * @param len the number of bytes in the buffer pointed to by @a bytes.
+ * @param yyscanner The scanner object.
+ * @return the newly allocated buffer state object.
+ */
+YY_BUFFER_STATE ael_yy_scan_bytes  (yyconst char * yybytes, int  _yybytes_len , yyscan_t yyscanner)
+{
+	YY_BUFFER_STATE b;
+	char *buf;
+	yy_size_t n;
+	int i;
+    
+	/* Get memory for full buffer, including space for trailing EOB's. */
+	n = _yybytes_len + 2;
+	buf = (char *) ael_yyalloc(n ,yyscanner );
+	if ( ! buf )
+		YY_FATAL_ERROR( "out of dynamic memory in ael_yy_scan_bytes()" );
+
+	for ( i = 0; i < _yybytes_len; ++i )
+		buf[i] = yybytes[i];
+
+	buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR;
+
+	b = ael_yy_scan_buffer(buf,n ,yyscanner);
+	if ( ! b )
+		YY_FATAL_ERROR( "bad buffer in ael_yy_scan_bytes()" );
+
+	/* It's okay to grow etc. this buffer, and we should throw it
+	 * away when we're done.
+	 */
+	b->yy_is_our_buffer = 1;
+
+	return b;
+}
+
+#ifndef YY_EXIT_FAILURE
+#define YY_EXIT_FAILURE 2
+#endif
+
+static void yy_fatal_error (yyconst char* msg , yyscan_t yyscanner)
+{
+    	(void) fprintf( stderr, "%s\n", msg );
+	exit( YY_EXIT_FAILURE );
+}
+
+/* Redefine yyless() so it works in section 3 code. */
+
+#undef yyless
+#define yyless(n) \
+	do \
+		{ \
+		/* Undo effects of setting up yytext. */ \
+        int yyless_macro_arg = (n); \
+        YY_LESS_LINENO(yyless_macro_arg);\
+		yytext[yyleng] = yyg->yy_hold_char; \
+		yyg->yy_c_buf_p = yytext + yyless_macro_arg; \
+		yyg->yy_hold_char = *yyg->yy_c_buf_p; \
+		*yyg->yy_c_buf_p = '\0'; \
+		yyleng = yyless_macro_arg; \
+		} \
+	while ( 0 )
+
+/* Accessor  methods (get/set functions) to struct members. */
+
+/** Get the user-defined data for this scanner.
+ * @param yyscanner The scanner object.
+ */
+YY_EXTRA_TYPE ael_yyget_extra  (yyscan_t yyscanner)
+{
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+    return yyextra;
+}
+
+/** Get the current line number.
+ * @param yyscanner The scanner object.
+ */
+int ael_yyget_lineno  (yyscan_t yyscanner)
+{
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+    
+        if (! YY_CURRENT_BUFFER)
+            return 0;
+    
+    return yylineno;
+}
+
+/** Get the current column number.
+ * @param yyscanner The scanner object.
+ */
+int ael_yyget_column  (yyscan_t yyscanner)
+{
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+    
+        if (! YY_CURRENT_BUFFER)
+            return 0;
+    
+    return yycolumn;
+}
+
+/** Get the input stream.
+ * @param yyscanner The scanner object.
+ */
+FILE *ael_yyget_in  (yyscan_t yyscanner)
+{
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+    return yyin;
+}
+
+/** Get the output stream.
+ * @param yyscanner The scanner object.
+ */
+FILE *ael_yyget_out  (yyscan_t yyscanner)
+{
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+    return yyout;
+}
+
+/** Get the length of the current token.
+ * @param yyscanner The scanner object.
+ */
+int ael_yyget_leng  (yyscan_t yyscanner)
+{
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+    return yyleng;
+}
+
+/** Get the current token.
+ * @param yyscanner The scanner object.
+ */
+
+char *ael_yyget_text  (yyscan_t yyscanner)
+{
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+    return yytext;
+}
+
+/** Set the user-defined data. This data is never touched by the scanner.
+ * @param user_defined The data to be associated with this scanner.
+ * @param yyscanner The scanner object.
+ */
+void ael_yyset_extra (YY_EXTRA_TYPE  user_defined , yyscan_t yyscanner)
+{
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+    yyextra = user_defined ;
+}
+
+/** Set the current line number.
+ * @param line_number
+ * @param yyscanner The scanner object.
+ */
+void ael_yyset_lineno (int  line_number , yyscan_t yyscanner)
+{
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+        /* lineno is only valid if an input buffer exists. */
+        if (! YY_CURRENT_BUFFER )
+           yy_fatal_error( "ael_yyset_lineno called with no buffer" , yyscanner); 
+    
+    yylineno = line_number;
+}
+
+/** Set the current column.
+ * @param line_number
+ * @param yyscanner The scanner object.
+ */
+void ael_yyset_column (int  column_no , yyscan_t yyscanner)
+{
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+        /* column is only valid if an input buffer exists. */
+        if (! YY_CURRENT_BUFFER )
+           yy_fatal_error( "ael_yyset_column called with no buffer" , yyscanner); 
+    
+    yycolumn = column_no;
+}
+
+/** Set the input stream. This does not discard the current
+ * input buffer.
+ * @param in_str A readable stream.
+ * @param yyscanner The scanner object.
+ * @see ael_yy_switch_to_buffer
+ */
+void ael_yyset_in (FILE *  in_str , yyscan_t yyscanner)
+{
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+    yyin = in_str ;
+}
+
+void ael_yyset_out (FILE *  out_str , yyscan_t yyscanner)
+{
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+    yyout = out_str ;
+}
+
+int ael_yyget_debug  (yyscan_t yyscanner)
+{
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+    return yy_flex_debug;
+}
+
+void ael_yyset_debug (int  bdebug , yyscan_t yyscanner)
+{
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+    yy_flex_debug = bdebug ;
+}
+
+/* Accessor methods for yylval and yylloc */
+
+YYSTYPE * ael_yyget_lval  (yyscan_t yyscanner)
+{
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+    return yylval;
+}
+
+void ael_yyset_lval (YYSTYPE *  yylval_param , yyscan_t yyscanner)
+{
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+    yylval = yylval_param;
+}
+
+YYLTYPE *ael_yyget_lloc  (yyscan_t yyscanner)
+{
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+    return yylloc;
+}
+    
+void ael_yyset_lloc (YYLTYPE *  yylloc_param , yyscan_t yyscanner)
+{
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+    yylloc = yylloc_param;
+}
+    
+/* User-visible API */
+
+/* ael_yylex_init is special because it creates the scanner itself, so it is
+ * the ONLY reentrant function that doesn't take the scanner as the last argument.
+ * That's why we explicitly handle the declaration, instead of using our macros.
+ */
+
+int ael_yylex_init(yyscan_t* ptr_yy_globals)
+
+{
+    if (ptr_yy_globals == NULL){
+        errno = EINVAL;
+        return 1;
+    }
+
+    *ptr_yy_globals = (yyscan_t) ael_yyalloc ( sizeof( struct yyguts_t ), NULL );
+
+    if (*ptr_yy_globals == NULL){
+        errno = ENOMEM;
+        return 1;
+    }
+
+    /* By setting to 0xAA, we expose bugs in yy_init_globals. Leave at 0x00 for releases. */
+    memset(*ptr_yy_globals,0x00,sizeof(struct yyguts_t));
+
+    return yy_init_globals ( *ptr_yy_globals );
+}
+
+static int yy_init_globals (yyscan_t yyscanner)
+{
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+    /* Initialization is the same as for the non-reentrant scanner.
+     * This function is called from ael_yylex_destroy(), so don't allocate here.
+     */
+
+    yyg->yy_buffer_stack = 0;
+    yyg->yy_buffer_stack_top = 0;
+    yyg->yy_buffer_stack_max = 0;
+    yyg->yy_c_buf_p = (char *) 0;
+    yyg->yy_init = 0;
+    yyg->yy_start = 0;
+
+    yyg->yy_start_stack_ptr = 0;
+    yyg->yy_start_stack_depth = 0;
+    yyg->yy_start_stack =  NULL;
+
+/* Defined in main.c */
+#ifdef YY_STDINIT
+    yyin = stdin;
+    yyout = stdout;
+#else
+    yyin = (FILE *) 0;
+    yyout = (FILE *) 0;
+#endif
+
+    /* For future reference: Set errno on error, since we are called by
+     * ael_yylex_init()
+     */
+    return 0;
+}
+
+/* ael_yylex_destroy is for both reentrant and non-reentrant scanners. */
+int ael_yylex_destroy  (yyscan_t yyscanner)
+{
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+    /* Pop the buffer stack, destroying each element. */
+	while(YY_CURRENT_BUFFER){
+		ael_yy_delete_buffer(YY_CURRENT_BUFFER ,yyscanner );
+		YY_CURRENT_BUFFER_LVALUE = NULL;
+		ael_yypop_buffer_state(yyscanner);
+	}
+
+	/* Destroy the stack itself. */
+	ael_yyfree(yyg->yy_buffer_stack ,yyscanner);
+	yyg->yy_buffer_stack = NULL;
+
+    /* Destroy the start condition stack. */
+        ael_yyfree(yyg->yy_start_stack ,yyscanner );
+        yyg->yy_start_stack = NULL;
+
+    /* Reset the globals. This is important in a non-reentrant scanner so the next time
+     * ael_yylex() is called, initialization will occur. */
+    yy_init_globals( yyscanner);
+
+    /* Destroy the main struct (reentrant only). */
+    ael_yyfree ( yyscanner , yyscanner );
+    yyscanner = NULL;
+    return 0;
+}
+
+/*
+ * Internal utility routines.
+ */
+
+#ifndef yytext_ptr
+static void yy_flex_strncpy (char* s1, yyconst char * s2, int n , yyscan_t yyscanner)
+{
+	register int i;
+	for ( i = 0; i < n; ++i )
+		s1[i] = s2[i];
+}
+#endif
+
+#ifdef YY_NEED_STRLEN
+static int yy_flex_strlen (yyconst char * s , yyscan_t yyscanner)
+{
+	register int n;
+	for ( n = 0; s[n]; ++n )
+		;
+
+	return n;
+}
+#endif
+
+void *ael_yyalloc (yy_size_t  size , yyscan_t yyscanner)
+{
+	return (void *) malloc( size );
+}
+
+void *ael_yyrealloc  (void * ptr, yy_size_t  size , yyscan_t yyscanner)
+{
+	/* The cast to (char *) in the following accommodates both
+	 * implementations that use char* generic pointers, and those
+	 * that use void* generic pointers.  It works with the latter
+	 * because both ANSI C and C++ allow castless assignment from
+	 * any pointer type to void*, and deal with argument conversions
+	 * as though doing an assignment.
+	 */
+	return (void *) realloc( (char *) ptr, size );
+}
+
+void ael_yyfree (void * ptr , yyscan_t yyscanner)
+{
+	free( (char *) ptr );	/* see ael_yyrealloc() for (char *) cast */
+}
+
+#define YYTABLES_NAME "yytables"
+
+#line 501 "ael.flex"
+
+
+
+static void pbcpush(char x)
+{
+	pbcstack[pbcpos++] = x;
+}
+
+static int pbcpop(char x)
+{
+	if (   ( x == ')' && pbcstack[pbcpos-1] == '(' )
+		|| ( x == ']' && pbcstack[pbcpos-1] == '[' )
+		|| ( x == '}' && pbcstack[pbcpos-1] == '{' )) {
+		pbcpos--;
+		return 0;
+	}
+	else
+		return 1; /* error */
+}
+
+static int c_prevword(void)
+{
+    char *c = prev_word;
+	int ret = 0;
+	while ( c && *c ) {
+        switch (*c) {
+            case '{': pbcpush('{');break;
+            case '}': ret = pbcpop('}');break;
+            case '[':pbcpush('[');break;
+            case ']':ret = pbcpop(']');break;
+            case '(':pbcpush('(');break;
+            case ')':ret = pbcpop(')'); break;
+        }
+        if( ret )
+            return 1;
+		c++;
+	}
+	return 0;
+}
+
+static void pbcwhere(char *text, int *line, int *col )
+{
+	int loc_line = 0;
+    int loc_col = 0;
+	while ( *text ) {
+       if ( *text == '\n' ) {
+             loc_line++;
+             loc_col = 1;
+       } else {
+             loc_col++;
+       }
+       text++;
+    }
+	*line = loc_line;
+    *col = loc_col;
+}
+
+void reset_parencount(yyscan_t yyscanner )
+{
+	struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+	parencount = 0;
+	pbcpos = 0;
+	pbcpush('(');
+	c_prevword();
+	BEGIN(paren);
+}
+
+void reset_semicount(yyscan_t yyscanner )
+{
+	struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+	pbcpos = 0;
+	BEGIN(semic);
+}
+
+void reset_argcount(yyscan_t yyscanner )
+{
+	struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+	parencount = 0;
+	pbcpos = 0;
+	commaout = 0;
+	pbcpush('(');
+	c_prevword();
+	BEGIN(argg);
+}
+
+
+struct pval *ael2_parse(char *filename, int *errors)
+{
+	struct pval *pval;
+	struct parse_io *io;
+	char *buffer;
+	struct stat stats;
+	FILE *fin;
+
+	/* extern int ael_yydebug; */
+
+	io = calloc(sizeof(struct parse_io),1);
+	/* reset the global counters */
+	prev_word = 0;
+	my_lineno = 1;
+	include_stack_index=0;
+	my_col = 0;
+	/* ael_yydebug = 1; */
+	ael_yylex_init(&io->scanner);
+	fin = fopen(filename,"r");
+	if ( !fin ) {
+		ast_log(LOG_ERROR,"File %s could not be opened\n", filename);
+		*errors = 1;
+		return 0;
+	}
+	my_file = strdup(filename);
+	stat(filename, &stats);
+	buffer = (char*)malloc(stats.st_size+2);
+	fread(buffer, 1, stats.st_size, fin);
+	buffer[stats.st_size]=0;
+	fclose(fin);
+	
+	ael_yy_scan_string (buffer ,io->scanner);
+	ael_yyset_lineno(1 , io->scanner);
+
+	/* ael_yyset_in (fin , io->scanner);	OLD WAY */
+
+	ael_yyparse(io);
+
+
+	pval = io->pval;
+	*errors = io->syntax_error_count;
+
+	ael_yylex_destroy(io->scanner);
+	free(buffer);
+	free(io);
+
+	return pval;
+}
+
diff --git a/pbx/pbx_ael.c b/pbx/pbx_ael.c
index e16b7f6941..8ecacfb13d 100644
--- a/pbx/pbx_ael.c
+++ b/pbx/pbx_ael.c
@@ -1,9 +1,9 @@
 /*
  * Asterisk -- An open source telephony toolkit.
  *
- * Copyright (C) 1999 - 2005, Digium, Inc.
+ * Copyright (C) 2006, Digium, Inc.
  *
- * Mark Spencer <markster@digium.com>
+ * Steve Murphy <murf@parsetree.com>
  *
  * See http://www.asterisk.org for more information about
  * the Asterisk project. Please do not directly contact
@@ -18,7 +18,7 @@
 
 /*! \file
  *
- * \brief Compile symbolic Asterisk Extension Logic into Asterisk extensions
+ * \brief Compile symbolic Asterisk Extension Logic into Asterisk extensions, version 2.
  * 
  */
 
@@ -28,6 +28,7 @@
 #include <string.h>
 #include <ctype.h>
 #include <errno.h>
+#include <regex.h>
 
 #include "asterisk.h"
 
@@ -38,23 +39,18 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
 #include "asterisk/module.h"
 #include "asterisk/logger.h"
 #include "asterisk/cli.h"
+#include "asterisk/app.h"
 #include "asterisk/callerid.h"
+#include "asterisk/ael_structs.h"
+#ifdef AAL_ARGCHECK
+#include "asterisk/argdesc.h"
+#endif
 
-struct stringlink {
-	struct stringlink *next;
-	char data[0];
-};
-
-#define FILLIN_BREAK		1
-#define FILLIN_CONTINUE		2
+static char expr_output[2096];
 
-struct fillin {
-	struct fillin *next;
-	char exten[AST_MAX_EXTENSION];
-	int priority;
-	int type;
-};
+/* these functions are in ../ast_expr2.fl */
 
+	
 #ifdef __AST_DEBUG_MALLOC
 static void FREE(void *ptr)
 {
@@ -71,1177 +67,3438 @@ static void FREE(void *ptr)
 
 static int aeldebug = 0;
 
+static char *dtext = "Asterisk Extension Language Compiler v2";
 static char *config = "extensions.ael";
 static char *registrar = "pbx_ael";
 
-static char *__grab_token(char *src, const char *filename, int lineno, int link)
+static int errs, warns, notes;
+
+#ifndef AAL_ARGCHECK
+/* for the time being, short circuit all the AAL related structures
+   without permanently removing the code; after/during the AAL 
+   development, this code can be properly re-instated 
+*/
+
+/* null definitions for structs passed down the infrastructure */
+struct argapp
 {
-	char *c;
-	char *b;
-	char *a;
-	int level = 0;
-	char *ret;
-#if 0
-	if (aeldebug || DEBUG_TOKENS) 
-		ast_verbose("Searching for token in '%s'!\n", src);
+	struct argapp *next;
+};
+
+#endif
+
+#ifdef AAL_ARGCHECK
+int option_matches_j( struct argdesc *should, pval *is, struct argapp *app);
+int option_matches( struct argdesc *should, pval *is, struct argapp *app);
+int ael_is_funcname(char *name);
 #endif
-	c = src;
-	while(*c) {
-		if ((*c == '\\')) {
-			c++;
-			if (!*c)
-				c--;
+
+int check_app_args(pval *appcall, pval *arglist, struct argapp *app);
+void check_pval(pval *item, struct argapp *apps);
+void check_pval_item(pval *item, struct argapp *apps);
+void check_switch_expr(pval *item, struct argapp *apps);
+void ast_expr_register_extra_error_info(char *errmsg);
+void ast_expr_clear_extra_error_info(void);
+int  ast_expr(char *expr, char *buf, int length);
+struct pval *find_macro(char *name);
+struct pval *find_context(char *name);
+struct pval *find_context(char *name);
+struct pval *find_macro(char *name);
+struct ael_priority *new_prio(void);
+struct ael_extension *new_exten(void);
+void linkprio(struct ael_extension *exten, struct ael_priority *prio);
+void destroy_extensions(struct ael_extension *exten);
+void linkexten(struct ael_extension *exten, struct ael_extension *add);
+void gen_prios(struct ael_extension *exten, char *label, pval *statement, struct ael_extension *mother_exten );
+void set_priorities(struct ael_extension *exten);
+void add_extensions(struct ael_extension *exten, struct ast_context *context);
+void ast_compile_ael2(struct ast_context **local_contexts, struct pval *root);
+void destroy_pval(pval *item);
+void destroy_pval_item(pval *item);
+int is_float(char *arg );
+int is_int(char *arg );
+int is_empty(char *arg);
+static pval *current_db;
+static pval *current_context;
+static pval *current_extension;
+static const char *description(void);
+static const char *key(void);
+
+static char *match_context;
+static char *match_exten;
+static char *match_label;
+static int in_abstract_context;
+static int count_labels; /* true, put matcher in label counting mode */
+static int label_count;  /* labels are only meant to be counted in a context or exten */
+static int return_on_context_match;
+static pval *last_matched_label;
+struct pval *match_pval(pval *item);
+static void check_timerange(pval *p);
+static void check_dow(pval *DOW);
+static void check_day(pval *DAY);
+static void check_month(pval *MON);
+static void check_expr2_input(pval *expr, char *str);
+static int extension_matches(pval *here, char *exten, char *pattern);
+static void check_goto(pval *item);
+static void find_pval_goto_item(pval *item, int lev);
+static void find_pval_gotos(pval *item, int lev);
+
+
+/* PRETTY PRINTER FOR AEL:  ============================================================================= */
+
+void print_pval(FILE *fin, pval *item, int depth)
+{
+	int i;
+	pval *lp;
+	
+	for (i=0; i<depth; i++) {
+		fprintf(fin, "\t"); /* depth == indentation */
+	}
+	
+	switch ( item->type ) {
+	case PV_WORD:
+		fprintf(fin,"%s;\n", item->u1.str); /* usually, words are encapsulated in something else */
+		break;
+		
+	case PV_MACRO:
+		fprintf(fin,"macro %s(", item->u1.str);
+		for (lp=item->u2.arglist; lp; lp=lp->next) {
+			if (lp != item->u2.arglist )
+				fprintf(fin,", ");
+			fprintf(fin,"%s", lp->u1.str);
+		}
+		fprintf(fin,") {\n");
+		print_pval_list(fin,item->u3.macro_statements,depth+1);
+		for (i=0; i<depth; i++) {
+			fprintf(fin,"\t"); /* depth == indentation */
+		}
+		fprintf(fin,"};\n\n");
+		break;
+			
+	case PV_CONTEXT:
+		if ( item->u3.abstract )
+			fprintf(fin,"abstract context %s {\n", item->u1.str);
+		else
+			fprintf(fin,"context %s {\n", item->u1.str);
+		print_pval_list(fin,item->u2.statements,depth+1);
+		for (i=0; i<depth; i++) {
+			fprintf(fin,"\t"); /* depth == indentation */
+		}
+		fprintf(fin,"};\n\n");
+		break;
+			
+	case PV_MACRO_CALL:
+		fprintf(fin,"&%s(", item->u1.str);
+		for (lp=item->u2.arglist; lp; lp=lp->next) {
+			if ( lp != item->u2.arglist )
+				fprintf(fin,", ");
+			fprintf(fin,"%s", lp->u1.str);
+		}
+		fprintf(fin,");\n");
+		break;
+			
+	case PV_APPLICATION_CALL:
+		fprintf(fin,"%s(", item->u1.str);
+		for (lp=item->u2.arglist; lp; lp=lp->next) {
+			if ( lp != item->u2.arglist )
+				fprintf(fin,", ");
+			fprintf(fin,"%s", lp->u1.str);
+		}
+		fprintf(fin,");\n");
+		break;
+			
+	case PV_CASE:
+		fprintf(fin,"case %s:\n", item->u1.str);
+		print_pval_list(fin,item->u2.statements, depth+1);
+		break;
+			
+	case PV_PATTERN:
+		fprintf(fin,"pattern %s:\n", item->u1.str);
+		print_pval_list(fin,item->u2.statements, depth+1);
+		break;
+			
+	case PV_DEFAULT:
+		fprintf(fin,"default:\n");
+		print_pval_list(fin,item->u2.statements, depth+1);
+		break;
+			
+	case PV_CATCH:
+		fprintf(fin,"catch %s {\n", item->u1.str);
+		print_pval_list(fin,item->u2.statements, depth+1);
+		for (i=0; i<depth; i++) {
+			fprintf(fin,"\t"); /* depth == indentation */
+		}
+		fprintf(fin,"};\n");
+		break;
+			
+	case PV_SWITCHES:
+		fprintf(fin,"switches {\n");
+		print_pval_list(fin,item->u1.list,depth+1);
+		for (i=0; i<depth; i++) {
+			fprintf(fin,"\t"); /* depth == indentation */
+		}
+		fprintf(fin,"};\n");
+		break;
+			
+	case PV_ESWITCHES:
+		fprintf(fin,"eswitches {\n");
+		print_pval_list(fin,item->u1.list,depth+1);
+		for (i=0; i<depth; i++) {
+			fprintf(fin,"\t"); /* depth == indentation */
+		}
+		fprintf(fin,"};\n");
+		break;
+			
+	case PV_INCLUDES:
+		fprintf(fin,"includes {\n");
+		for (lp=item->u1.list; lp; lp=lp->next) {
+			for (i=0; i<depth+1; i++) {
+				fprintf(fin,"\t"); /* depth == indentation */
+			}
+			fprintf(fin,"%s", lp->u1.str); /* usually, words are encapsulated in something else */
+			if ( lp->u2.arglist )
+				fprintf(fin,"|%s|%s|%s|%s", 
+						lp->u2.arglist->u1.str,
+						lp->u2.arglist->next->u1.str,
+						lp->u2.arglist->next->next->u1.str,
+						lp->u2.arglist->next->next->next->u1.str
+					);
+			fprintf(fin,";\n"); /* usually, words are encapsulated in something else */
+		}
+		
+		print_pval_list(fin,item->u1.list,depth+1);
+		for (i=0; i<depth; i++) {
+			fprintf(fin,"\t"); /* depth == indentation */
+		}
+		fprintf(fin,"};\n");
+		break;
+			
+	case PV_STATEMENTBLOCK:
+		fprintf(fin,"{\n");
+		print_pval_list(fin,item->u1.list, depth+1);
+		for (i=0; i<depth; i++) {
+			fprintf(fin,"\t"); /* depth == indentation */
+		}
+		fprintf(fin,"};\n");
+		break;
+			
+	case PV_VARDEC:
+		fprintf(fin,"%s=%s;\n", item->u1.str, item->u2.val);
+		break;
+			
+	case PV_GOTO:
+		fprintf(fin,"goto %s", item->u1.list->u1.str);
+		if ( item->u1.list->next )
+			fprintf(fin,"|%s", item->u1.list->next->u1.str);
+		if ( item->u1.list->next && item->u1.list->next->next )
+			fprintf(fin,"|%s", item->u1.list->next->next->u1.str);
+		fprintf(fin,"\n");
+		break;
+			
+	case PV_LABEL:
+		fprintf(fin,"%s:\n", item->u1.str);
+		break;
+			
+	case PV_FOR:
+		fprintf(fin,"for (%s; %s; %s)\n", item->u1.for_init, item->u2.for_test, item->u3.for_inc);
+		print_pval_list(fin,item->u4.for_statements,depth+1);
+		break;
+			
+	case PV_WHILE:
+		fprintf(fin,"while (%s)\n", item->u1.str);
+		print_pval_list(fin,item->u2.statements,depth+1);
+		break;
+			
+	case PV_BREAK:
+		fprintf(fin,"break;\n");
+		break;
+			
+	case PV_RETURN:
+		fprintf(fin,"return;\n");
+		break;
+			
+	case PV_CONTINUE:
+		fprintf(fin,"continue;\n");
+		break;
+			
+	case PV_RANDOM:
+	case PV_IFTIME:
+	case PV_IF:
+		if ( item->type == PV_IFTIME ) {
+			
+			fprintf(fin,"ifTime ( %s|%s|%s|%s )\n", 
+					item->u1.list->u1.str, 
+					item->u1.list->next->u1.str, 
+					item->u1.list->next->next->u1.str, 
+					item->u1.list->next->next->next->u1.str
+					);
+		} else if ( item->type == PV_RANDOM ) {
+			fprintf(fin,"random ( %s )\n", item->u1.str );
+		} else
+			fprintf(fin,"if ( %s )\n", item->u1.str);
+		if ( item->u2.statements && item->u2.statements->next ) {
+			for (i=0; i<depth; i++) {
+				fprintf(fin,"\t"); /* depth == indentation */
+			}
+			fprintf(fin,"{\n");
+			print_pval_list(fin,item->u2.statements,depth+1);
+			for (i=0; i<depth; i++) {
+				fprintf(fin,"\t"); /* depth == indentation */
+			}
+			if ( item->u3.else_statements )
+				fprintf(fin,"}\n");
+			else
+				fprintf(fin,"};\n");
+		} else if (item->u2.statements ) {
+			print_pval_list(fin,item->u2.statements,depth+1);
 		} else {
-			if ((*c == '{') || (*c == '(')) {
-				level++;
-			} else if ((*c == '}') || (*c == ')')) {
-				if (level)
-					level--;
-				else
-					ast_log(LOG_WARNING, "Syntax error at line %d of '%s', too many closing braces!\n", lineno, filename);
-			} else if ((*c == ';') && !level) {
-				/* Got a token! */
-				*c = '\0';
-				b = c;
-				b--;
-				c++;
-				while((b > src) && (*b < 33)) { 
-					*b = '\0'; 
-					b--; 
-				}
-				a = ast_skip_blanks(src);
-				if (link) {
-					ret = malloc(strlen(a) + sizeof(struct stringlink) + 1);
-					if (ret)
-						strcpy(ret + sizeof(struct stringlink), a);
-				} else
-					ret = strdup(a);
-				/* Save remainder */
-				memmove(src, c, strlen(c) + 1);
-				return ret;
+			if (item->u3.else_statements )
+				fprintf(fin, " {} ");
+			else
+				fprintf(fin, " {}; ");
+		}
+		if ( item->u3.else_statements ) {
+			for (i=0; i<depth; i++) {
+				fprintf(fin,"\t"); /* depth == indentation */
 			}
+			fprintf(fin,"else\n");
+			print_pval_list(fin,item->u3.else_statements, depth);
 		}
-		c++;
+		break;
+			
+	case PV_SWITCH:
+		fprintf(fin,"switch( %s ) {\n", item->u1.str);
+		print_pval_list(fin,item->u2.statements,depth+1);
+		for (i=0; i<depth; i++) {
+			fprintf(fin,"\t"); /* depth == indentation */
+		}
+		fprintf(fin,"}\n");
+		break;
+			
+	case PV_EXTENSION:
+		if ( item->u4.regexten )
+			fprintf(fin, "regexten ");
+		if ( item->u3.hints )
+			fprintf(fin,"hints(%s) ", item->u3.hints);
+		
+		fprintf(fin,"%s => \n", item->u1.str);
+		print_pval_list(fin,item->u2.statements,depth+1);
+		break;
+			
+	case PV_IGNOREPAT:
+		fprintf(fin,"ignorepat => %s\n", item->u1.str);
+		break;
+			
+	case PV_GLOBALS:
+		fprintf(fin,"globals {\n");
+		print_pval_list(fin,item->u1.statements,depth+1);
+		for (i=0; i<depth; i++) {
+			fprintf(fin,"\t"); /* depth == indentation */
+		}
+		fprintf(fin,"}\n");
+		break;
 	}
-	return NULL;		
 }
 
-static char *grab_token(char *src, const char *filename, int lineno)
+void print_pval_list(FILE *fin, pval *item, int depth)
 {
-	return __grab_token(src, filename, lineno, 0);
+	pval *i;
+	
+	for (i=item; i; i=i->next) {
+		print_pval(fin, i, depth);
+	}
 }
 
-static struct stringlink *arg_parse(char *args, const char *filename, int lineno)
+void ael2_print(char *fname, pval *tree)
 {
-	struct stringlink *cur, *prev=NULL, *root=NULL;
-	if (args) {
-		if (aeldebug & DEBUG_TOKENS) 
-			ast_verbose("Parsing args '%s'!\n", args);
-		if (args[0] == '{') {
-			/* Strip mandatory '}' from end */
-			args[strlen(args) - 1] = '\0';
-			while ((cur = (struct stringlink *)__grab_token(args + 1, filename, lineno, 1))) {
-				cur->next = NULL;
-				if (prev)
-					prev->next = cur;
-				else
-					root = cur;
-				prev = cur;
-			}
-		} else if (*args) {
-			root = malloc(sizeof(struct stringlink) + strlen(args) + 1);
-			if (root) {
-				strcpy(root->data, args);
-				root->next = NULL;
-			}
+	FILE *fin = fopen(fname,"w");
+	if ( !fin ) {
+		ast_log(LOG_ERROR, "Couldn't open %s for writing.\n", fname);
+		return;
+	}
+	print_pval_list(fin, tree, 0);
+	fclose(fin);
+}
+
+
+/* EMPTY TEMPLATE FUNCS FOR AEL TRAVERSAL:  ============================================================================= */
+
+void traverse_pval_template(pval *item, int depth);
+void traverse_pval_item_template(pval *item, int depth);
+
+
+void traverse_pval_item_template(pval *item, int depth)/* depth comes in handy for a pretty print (indentation),
+														  but you may not need it */
+{
+	pval *lp;
+	
+	switch ( item->type ) {
+	case PV_WORD:
+		/* fields: item->u1.str == string associated with this (word). */
+		break;
+		
+	case PV_MACRO:
+		/* fields: item->u1.str     == name of macro
+		           item->u2.arglist == pval list of PV_WORD arguments of macro, as given by user
+				   item->u2.arglist->u1.str  == argument
+				   item->u2.arglist->next   == next arg
+
+				   item->u3.macro_statements == pval list of statements in macro body.
+		*/
+		for (lp=item->u2.arglist; lp; lp=lp->next) {
+		
+		}
+		traverse_pval_item_template(item->u3.macro_statements,depth+1);
+		break;
+			
+	case PV_CONTEXT:
+		/* fields: item->u1.str     == name of context
+		           item->u2.statements == pval list of statements in context body
+				   item->u3.abstract == int 1 if an abstract keyword were present
+		*/
+		traverse_pval_item_template(item->u2.statements,depth+1);
+		break;
+			
+	case PV_MACRO_CALL:
+		/* fields: item->u1.str     == name of macro to call
+		           item->u2.arglist == pval list of PV_WORD arguments of macro call, as given by user
+				   item->u2.arglist->u1.str  == argument
+				   item->u2.arglist->next   == next arg
+		*/
+		for (lp=item->u2.arglist; lp; lp=lp->next) {
+		}
+		break;
+			
+	case PV_APPLICATION_CALL:
+		/* fields: item->u1.str     == name of application to call
+		           item->u2.arglist == pval list of PV_WORD arguments of macro call, as given by user
+				   item->u2.arglist->u1.str  == argument
+				   item->u2.arglist->next   == next arg
+		*/
+		for (lp=item->u2.arglist; lp; lp=lp->next) {
+		}
+		break;
+			
+	case PV_CASE:
+		/* fields: item->u1.str     == value of case
+		           item->u2.statements == pval list of statements under the case
+		*/
+		traverse_pval_item_template(item->u2.statements,depth+1);
+		break;
+			
+	case PV_PATTERN:
+		/* fields: item->u1.str     == value of case
+		           item->u2.statements == pval list of statements under the case
+		*/
+		traverse_pval_item_template(item->u2.statements,depth+1);
+		break;
+			
+	case PV_DEFAULT:
+		/* fields: 
+		           item->u2.statements == pval list of statements under the case
+		*/
+		traverse_pval_item_template(item->u2.statements,depth+1);
+		break;
+			
+	case PV_CATCH:
+		/* fields: item->u1.str     == name of extension to catch
+		           item->u2.statements == pval list of statements in context body
+		*/
+		traverse_pval_item_template(item->u2.statements,depth+1);
+		break;
+			
+	case PV_SWITCHES:
+		/* fields: item->u1.list     == pval list of PV_WORD elements, one per entry in the list
+		*/
+		traverse_pval_item_template(item->u1.list,depth+1);
+		break;
+			
+	case PV_ESWITCHES:
+		/* fields: item->u1.list     == pval list of PV_WORD elements, one per entry in the list
+		*/
+		traverse_pval_item_template(item->u1.list,depth+1);
+		break;
+			
+	case PV_INCLUDES:
+		/* fields: item->u1.list     == pval list of PV_WORD elements, one per entry in the list
+		           item->u2.arglist  == pval list of 4 PV_WORD elements for time values
+		*/
+		traverse_pval_item_template(item->u1.list,depth+1);
+		traverse_pval_item_template(item->u2.arglist,depth+1);
+		break;
+			
+	case PV_STATEMENTBLOCK:
+		/* fields: item->u1.list     == pval list of statements in block, one per entry in the list
+		*/
+		traverse_pval_item_template(item->u1.list,depth+1);
+		break;
+			
+	case PV_VARDEC:
+		/* fields: item->u1.str     == variable name
+		           item->u2.val     == variable value to assign
+		*/
+		break;
+			
+	case PV_GOTO:
+		/* fields: item->u1.list     == pval list of PV_WORD target names, up to 3, in order as given by user.
+		           item->u1.list->u1.str  == where the data on a PV_WORD will always be.
+		*/
+		
+		if ( item->u1.list->next )
+			;
+		if ( item->u1.list->next && item->u1.list->next->next )
+			;
+		
+		break;
+			
+	case PV_LABEL:
+		/* fields: item->u1.str     == label name
+		*/
+		break;
+			
+	case PV_FOR:
+		/* fields: item->u1.for_init     == a string containing the initalizer
+		           item->u2.for_test     == a string containing the loop test
+		           item->u3.for_inc      == a string containing the loop increment
+
+				   item->u4.for_statements == a pval list of statements in the for ()
+		*/
+		traverse_pval_item_template(item->u4.for_statements,depth+1);
+		break;
+			
+	case PV_WHILE:
+		/* fields: item->u1.str        == the while conditional, as supplied by user
+
+				   item->u2.statements == a pval list of statements in the while ()
+		*/
+		traverse_pval_item_template(item->u2.statements,depth+1);
+		break;
+			
+	case PV_BREAK:
+		/* fields: none
+		*/
+		break;
+			
+	case PV_RETURN:
+		/* fields: none
+		*/
+		break;
+			
+	case PV_CONTINUE:
+		/* fields: none
+		*/
+		break;
+			
+	case PV_IFTIME:
+		/* fields: item->u1.list        == there are 4 linked PV_WORDs here.
+
+				   item->u2.statements == a pval list of statements in the if ()
+				   item->u3.else_statements == a pval list of statements in the else
+											   (could be zero)
+		*/
+		traverse_pval_item_template(item->u2.statements,depth+1);
+		if ( item->u3.else_statements ) {
+			traverse_pval_item_template(item->u3.else_statements,depth+1);
 		}
+		break;
+			
+	case PV_RANDOM:
+		/* fields: item->u1.str        == the random number expression, as supplied by user
+
+				   item->u2.statements == a pval list of statements in the if ()
+				   item->u3.else_statements == a pval list of statements in the else
+											   (could be zero)
+		*/
+		traverse_pval_item_template(item->u2.statements,depth+1);
+		if ( item->u3.else_statements ) {
+			traverse_pval_item_template(item->u3.else_statements,depth+1);
+		}
+		break;
+			
+	case PV_IF:
+		/* fields: item->u1.str        == the if conditional, as supplied by user
+
+				   item->u2.statements == a pval list of statements in the if ()
+				   item->u3.else_statements == a pval list of statements in the else
+											   (could be zero)
+		*/
+		traverse_pval_item_template(item->u2.statements,depth+1);
+		if ( item->u3.else_statements ) {
+			traverse_pval_item_template(item->u3.else_statements,depth+1);
+		}
+		break;
+			
+	case PV_SWITCH:
+		/* fields: item->u1.str        == the switch expression
+
+				   item->u2.statements == a pval list of statements in the switch, 
+				   							(will be case statements, most likely!)
+		*/
+		traverse_pval_item_template(item->u2.statements,depth+1);
+		break;
+			
+	case PV_EXTENSION:
+		/* fields: item->u1.str        == the extension name, label, whatever it's called
+
+				   item->u2.statements == a pval list of statements in the extension
+				   item->u3.hints      == a char * hint argument
+				   item->u4.regexten   == an int boolean. non-zero says that regexten was specified
+		*/
+		traverse_pval_item_template(item->u2.statements,depth+1);
+		break;
+			
+	case PV_IGNOREPAT:
+		/* fields: item->u1.str        == the ignorepat data
+		*/
+		break;
+			
+	case PV_GLOBALS:
+		/* fields: item->u1.statements     == pval list of statements, usually vardecs
+		*/
+		traverse_pval_item_template(item->u1.statements,depth+1);
+		break;
 	}
-	return root;
 }
 
-static char *grab_else(char *args, const char *filename, int lineno)
+void traverse_pval_template(pval *item, int depth) /* depth comes in handy for a pretty print (indentation),
+													  but you may not need it */
 {
-	char *ret = NULL;
-	int level=0;
-	char *c;
-	if (args) {
-		if (args[0] == '{') {
-			c = args;
-			while(*c) {
-				if (*c == '{')
-					level++;
-				else if (*c == '}') {
-					level--;
-					if (!level) {
-						c++;
-						while(*c && (*c < 33)) { *c = '\0'; c++; };
-						if (!strncasecmp(c, "else", 4) && 
-							((c[4] == '{') || (c[4] < 33))) {
-								/* Ladies and gentlemen, we have an else clause */
-							*c = '\0';
-							c += 4;
-							c = ast_skip_blanks(c);
-							ret = c;
-							if (aeldebug & DEBUG_TOKENS)
-								ast_verbose("Returning else clause '%s'\n", c);
-						}
-						break;
-					}
+	pval *i;
+	
+	for (i=item; i; i=i->next) {
+		traverse_pval_item_template(i, depth);
+	}
+}
+
+
+/* SEMANTIC CHECKING FOR AEL:  ============================================================================= */
+
+/*   (not all that is syntactically legal is good! */
+
+
+
+static int extension_matches(pval *here, char *exten, char *pattern)
+{
+	int err1;
+	regex_t preg;
+	
+	/* simple case, they match exactly, the pattern and exten name */
+	if( !strcmp(pattern,exten) == 0 )
+		return 1;
+	
+	if ( pattern[0] == '_' ) {
+		char reg1[2000];
+		char *p,*r=reg1;
+		
+		if ( strlen(pattern)*5 >= 2000 ) /* safety valve */ {
+			ast_log(LOG_ERROR,"Error: The pattern %s is way too big. Pattern matching cancelled.\n",
+					pattern);
+			return 0;
+		}
+		/* form a regular expression from the pattern, and then match it against exten */
+		*r++ = '^'; /* what if the extension is a pattern ?? */
+		*r++ = '_'; /* what if the extension is a pattern ?? */
+		*r++ = '?';
+		for (p=pattern+1; *p; p++) {
+			switch ( *p ) {
+			case 'X':
+				*r++ = '[';
+				*r++ = '0';
+				*r++ = '-';
+				*r++ = '9';
+				*r++ = 'X';
+				*r++ = ']';
+				break;
+				
+			case 'Z':
+				*r++ = '[';
+				*r++ = '1';
+				*r++ = '-';
+				*r++ = '9';
+				*r++ = 'Z';
+				*r++ = ']';
+				break;
+				
+			case 'N':
+				*r++ = '[';
+				*r++ = '2';
+				*r++ = '-';
+				*r++ = '9';
+				*r++ = 'N';
+				*r++ = ']';
+				break;
+				
+			case '[':
+				while ( *p && *p != ']' ) {
+					*r++ = *p++;
+				}
+				if ( *p != ']') {
+					ast_log(LOG_WARNING, "Warning: file %s, line %d-%d: The extension pattern '%s' is missing a closing bracket \n",
+							here->filename, here->startline, here->endline, pattern);
 				}
-				c++;
+				break;
+				
+			case '.':
+			case '!':
+				*r++ = '.';
+				*r++ = '*';
+				break;
+			case '*':
+				*r++ = '\\';
+				*r++ = '*';
+				break;
+			default:
+				*r++ = *p;
+				break;
+				
 			}
 		}
+		*r++ = '$'; /* what if the extension is a pattern ?? */
+		*r++ = *p++; /* put in the closing null */
+		err1 = regcomp(&preg, reg1, REG_NOSUB|REG_EXTENDED);
+		if ( err1 ) {
+			char errmess[500];
+			regerror(err1,&preg,errmess,sizeof(errmess));
+			regfree(&preg);
+			ast_log(LOG_WARNING, "Regcomp of %s failed, error code %d\n",
+					reg1, err1);
+			return 0;
+		}
+		err1 = regexec(&preg, exten, 0, 0, 0);
+		regfree(&preg);
+		
+		if ( err1 ) {
+			/* ast_log(LOG_NOTICE,"*****************************[%d]Extension %s did not match %s(%s)\n",
+			   err1,exten, pattern, reg1); */
+			return 0; /* no match */
+		} else {
+			/* ast_log(LOG_NOTICE,"*****************************Extension %s matched %s\n",
+			   exten, pattern); */
+			return 1;
+		}
+		
+		
+	} else {
+		if ( strcmp(exten,pattern) == 0 ) {
+			return 1;
+		} else
+			return 0;
 	}
-	return ret;
 }
 
-static struct stringlink *param_parse(char *parms, const char *macro, const char *filename, int lineno)
+
+static void check_expr2_input(pval *expr, char *str)
 {
-	char *s, *e;
-	struct stringlink *root = NULL, *prev=NULL, *cur;
-	if (!parms || !*parms)
-		return NULL;
-	if (*parms != '(') {
-		ast_log(LOG_NOTICE, "Syntax error in parameter list for macro '%s' at about line %d of %s: Expecting '(' but got '%c'\n", macro, lineno, filename, *parms);
-		return NULL;
+	int spaces = strspn(str,"\t \n");
+	if ( !strncmp(str+spaces,"$[",2) ) {
+		ast_log(LOG_WARNING, "Warning: file %s, line %d-%d: The expression '%s' is redundantly wrapped in '$[ ]'. \n",
+				expr->filename, expr->startline, expr->endline, str);
+		warns++;
 	}
-	s = parms + 1;
-	while(*s) {
-		s = ast_skip_blanks(s);
-		e = s;
-		while(*e &&  (*e != ')') && (*e != ',')) {
-			if (*e < 33)
-				*e = '\0';
-			e++;
-		}
-		if (*e) {
-			/* Strip token */
-			*e = '\0';
-			e++;
-			/* Skip over whitespace */
-			e = ast_skip_blanks(e);
-			/* Link */
-			cur = malloc(strlen(s) + sizeof(struct stringlink) + 1);
-			if (cur) {
-				cur->next = NULL;
-				strcpy(cur->data, s);
-				if (prev)
-					prev->next = cur;
-				else
-					root = cur;
-				prev = cur;
-			}
-			s = e;
-		}
+}
+
+static void check_timerange(pval *p)
+{
+	char times[200];
+	char *e;
+	int s1, s2;
+	int e1, e2;
+
+
+	strncpy(times, p->u1.str, sizeof(times));
+	/* Star is all times */
+	if (ast_strlen_zero(times) || !strcmp(times, "*")) {
+		return;
+	}
+	/* Otherwise expect a range */
+	e = strchr(times, '-');
+	if (!e) {
+		ast_log(LOG_WARNING, "Warning: file %s, line %d-%d: The time range format (%s) requires a '-' surrounded by two 24-hour times of day!\n",
+				p->filename, p->startline, p->endline, times);
+		warns++;
+		return;
+	}
+	*e = '\0';
+	e++;
+	while (*e && !isdigit(*e)) 
+		e++;
+	if (!*e) {
+		ast_log(LOG_WARNING, "Warning: file %s, line %d-%d: The time range format (%s) is missing the end time!\n",
+				p->filename, p->startline, p->endline, p->u1.str);
+		warns++;
+	}
+	if (sscanf(times, "%d:%d", &s1, &s2) != 2) {
+		ast_log(LOG_WARNING, "Warning: file %s, line %d-%d: The start time (%s) isn't quite right!\n",
+				p->filename, p->startline, p->endline, times);
+		warns++;
+	}
+	if (sscanf(e, "%d:%d", &e1, &e2) != 2) {
+		ast_log(LOG_WARNING, "Warning: file %s, line %d-%d: The end time (%s) isn't quite right!\n",
+				p->filename, p->startline, p->endline, times);
+		warns++;
+	}
+
+	s1 = s1 * 30 + s2/2;
+	if ((s1 < 0) || (s1 >= 24*30)) {
+		ast_log(LOG_WARNING, "Warning: file %s, line %d-%d: The start time (%s) is out of range!\n",
+				p->filename, p->startline, p->endline, times);
+		warns++;
+	}
+	e1 = e1 * 30 + e2/2;
+	if ((e1 < 0) || (e1 >= 24*30)) {
+		ast_log(LOG_WARNING, "Warning: file %s, line %d-%d: The end time (%s) is out of range!\n",
+				p->filename, p->startline, p->endline, e);
+		warns++;
 	}
-	return root;
+	return;
 }
 
-static void arg_free(struct stringlink *cur)
+static char *days[] =
 {
-	struct stringlink *last;
-	while(cur) {
-		last = cur;
-		cur = cur->next;
-		free(last);
+	"sun",
+	"mon",
+	"tue",
+	"wed",
+	"thu",
+	"fri",
+	"sat",
+};
+
+/*! \brief  get_dow: Get day of week */
+static void check_dow(pval *DOW)
+{
+	char dow[200];
+	char *c;
+	/* The following line is coincidence, really! */
+	int s, e;
+	
+	strncpy(dow,DOW->u1.str,sizeof(dow));
+ 
+	/* Check for all days */
+	if (ast_strlen_zero(dow) || !strcmp(dow, "*"))
+		return;
+	/* Get start and ending days */
+	c = strchr(dow, '-');
+	if (c) {
+		*c = '\0';
+		c++;
+	} else
+		c = NULL;
+	/* Find the start */
+	s = 0;
+	while ((s < 7) && strcasecmp(dow, days[s])) s++;
+	if (s >= 7) {
+		ast_log(LOG_WARNING, "Warning: file %s, line %d-%d: The day (%s) must be one of 'sun', 'mon', 'tue', 'wed', 'thu', 'fri', or 'sat'!\n",
+				DOW->filename, DOW->startline, DOW->endline, dow);
+		warns++;
 	}
+	if (c) {
+		e = 0;
+		while ((e < 7) && strcasecmp(c, days[e])) e++;
+		if (e >= 7) {
+			ast_log(LOG_WARNING, "Warning: file %s, line %d-%d: The end day (%s) must be one of 'sun', 'mon', 'tue', 'wed', 'thu', 'fri', or 'sat'!\n",
+					DOW->filename, DOW->startline, DOW->endline, c);
+			warns++;
+		}
+	} else
+		e = s;
 }
 
-static void handle_globals(struct stringlink *vars)
+static void check_day(pval *DAY)
 {
-	while(vars) {
-		pbx_builtin_setvar(NULL, vars->data);
-		vars = vars->next;
+	char day[200];
+	char *c;
+	/* The following line is coincidence, really! */
+	int s, e;
+
+	strncpy(day,DAY->u1.str,sizeof(day));
+	/* Check for all days */
+	if (ast_strlen_zero(day) || !strcmp(day, "*")) {
+		return;
+	}
+	/* Get start and ending days */
+	c = strchr(day, '-');
+	if (c) {
+		*c = '\0';
+		c++;
 	}
+	/* Find the start */
+	if (sscanf(day, "%d", &s) != 1) {
+		ast_log(LOG_WARNING, "Warning: file %s, line %d-%d: The start day of month (%s) must be a number!\n",
+				DAY->filename, DAY->startline, DAY->endline, day);
+		warns++;
+	}
+	else if ((s < 1) || (s > 31)) {
+		ast_log(LOG_WARNING, "Warning: file %s, line %d-%d: The start day of month (%s) must be a number in the range [1-31]!\n",
+				DAY->filename, DAY->startline, DAY->endline, day);
+		warns++;
+	}
+	s--;
+	if (c) {
+		if (sscanf(c, "%d", &e) != 1) {
+			ast_log(LOG_WARNING, "Warning: file %s, line %d-%d: The end day of month (%s) must be a number!\n",
+					DAY->filename, DAY->startline, DAY->endline, c);
+			warns++;
+		}
+		else if ((e < 1) || (e > 31)) {
+			ast_log(LOG_WARNING, "Warning: file %s, line %d-%d: The end day of month (%s) must be a number in the range [1-31]!\n",
+					DAY->filename, DAY->startline, DAY->endline, day);
+			warns++;
+		}
+		e--;
+	} else
+		e = s;
 }
 
-static struct stringlink *split_token(char *token, const char *filename, int lineno)
+static char *months[] =
 {
-	char *args, *p;
-	struct stringlink *argv;
-	args = token;
-	while (*args && (*args > 32) && (*args != '{') && (*args != '(')) args++;
-	if (*args) {
-		p = args;
-		args = ast_skip_blanks(args);
-		if (*args != '(') {
-			*p = '\0';
-		} else {
-			while (*args && (*args != ')')) args++;
-			if (*args == ')') {
-				args++;
-				args = ast_skip_blanks(args);
-			}
+	"jan",
+	"feb",
+	"mar",
+	"apr",
+	"may",
+	"jun",
+	"jul",
+	"aug",
+	"sep",
+	"oct",
+	"nov",
+	"dec",
+};
+
+static void check_month(pval *MON)
+{
+	char mon[200];
+	char *c;
+	/* The following line is coincidence, really! */
+	int s, e;
+
+	strncpy(mon,MON->u1.str,sizeof(mon));
+	/* Check for all days */
+	if (ast_strlen_zero(mon) || !strcmp(mon, "*")) 
+		return ;
+	/* Get start and ending days */
+	c = strchr(mon, '-');
+	if (c) {
+		*c = '\0';
+		c++;
+	}
+	/* Find the start */
+	s = 0;
+	while ((s < 12) && strcasecmp(mon, months[s])) s++;
+	if (s >= 12) {
+		ast_log(LOG_WARNING, "Warning: file %s, line %d-%d: The start month (%s) must be a one of: 'jan', 'feb', ..., 'dec'!\n",
+				MON->filename, MON->startline, MON->endline, mon);
+		warns++;
+	}
+	if (c) {
+		e = 0;
+		while ((e < 12) && strcasecmp(mon, months[e])) e++;
+		if (e >= 12) {
+			ast_log(LOG_WARNING, "Warning: file %s, line %d-%d: The end month (%s) must be a one of: 'jan', 'feb', ..., 'dec'!\n",
+					MON->filename, MON->startline, MON->endline, c);
+			warns++;
 		}
-		if (!*args)
-			args = NULL;
-	} else args = NULL;
-	argv = arg_parse(args, filename, lineno);
-	if (args)
-		*args = '\0';
-	return argv;
+	} else
+		e = s;
 }
 
-static int matches_keyword(const char *data, const char *keyword)
+/* general purpose goto finder */
+
+
+static void check_goto(pval *item)
 {
-	char c;
-	if (!strncasecmp(data, keyword, strlen(keyword))) {
-		c = data[strlen(keyword)];
-		if ((c < 33) || (c == '(') || (c == '{'))
-			return 1;
+	/* check for the target of the goto-- does it exist? */
+	if ( !(item->u1.list)->next && !(item->u1.list)->u1.str ) {
+		ast_log(LOG_ERROR,"Error: file %s, line %d-%d: goto:  empty label reference found!\n",
+				item->filename, item->startline, item->endline);
+		errs++;
+	}
+	
+	/* just one item-- the label should be in the current extension */
+	
+	if (item->u1.list && !item->u1.list->next && !strstr((item->u1.list)->u1.str,"${")) {
+		struct pval *x = find_label_in_current_extension((char*)((item->u1.list)->u1.str));
+		/* printf("Calling find_label_in_current_extension with args %s\n",
+		   (char*)((item->u1.list)->u1.str)); */
+		if (!x) {
+			ast_log(LOG_ERROR,"Error: file %s, line %d-%d: goto:  no label %s exists in the current extension!\n",
+					item->filename, item->startline, item->endline, item->u1.list->u1.str);
+			errs++;
+		}
+		else
+			return;
+	}
+	
+	/* TWO items */
+	if (item->u1.list->next && !item->u1.list->next->next) {
+		/* two items */
+		/* printf("Calling find_label_in_current_context with args %s, %s\n",
+		   (char*)((item->u1.list)->u1.str), (char *)item->u1.list->next->u1.str); */
+		if (!strstr((item->u1.list)->u1.str,"${") 
+			&& !strstr(item->u1.list->next->u1.str,"${") ) /* Don't try to match variables */ {
+			struct pval *x = find_label_in_current_context((char *)item->u1.list->u1.str, (char *)item->u1.list->next->u1.str);
+			if (!x) {
+				ast_log(LOG_ERROR,"Error: file %s, line %d-%d: goto:  no label %s|%s exists in the current context, or any of its inclusions!\n",
+						item->filename, item->startline, item->endline, item->u1.list->u1.str, item->u1.list->next->u1.str );
+				errs++;
+			}
+			else
+				return;
+		}
+	}
+	
+	/* All 3 items! */
+	if (item->u1.list->next && item->u1.list->next->next) {
+		/* all three */
+		pval *first = item->u1.list;
+		pval *second = item->u1.list->next;
+		pval *third = item->u1.list->next->next;
+		
+		/* printf("Calling find_label_in_current_context with args %s, %s, %s\n",
+		   (char*)first->u1.str, (char*)second->u1.str, (char*)third->u1.str); */
+		if (!strstr((item->u1.list)->u1.str,"${") 
+			&& !strstr(item->u1.list->next->u1.str,"${")
+			&& !strstr(item->u1.list->next->next->u1.str,"${")) /* Don't try to match variables */ {
+			struct pval *x = find_label_in_current_db((char*)first->u1.str, (char*)second->u1.str, (char*)third->u1.str);
+			if (!x) {
+				struct pval *p3;
+				struct pval *found = 0;
+				struct pval *that_context = find_context(item->u1.list->u1.str);
+				
+				/* the target of the goto could be in an included context!! Fancy that!! */
+				/* look for includes in the current context */
+				if (that_context) {
+					for (p3=that_context->u2.statements; p3; p3=p3->next) {
+						if (p3->type == PV_INCLUDES) {
+							struct pval *p4;
+							for (p4=p3->u1.list; p4; p4=p4->next) {
+								/* for each context pointed to, find it, then find a context/label that matches the
+								   target here! */
+								char *incl_context = p4->u1.str;
+								/* find a matching context name */
+								struct pval *that_other_context = find_context(incl_context);
+								if (that_other_context) {
+									struct pval *context_save = current_context;
+									current_context = that_other_context;
+									struct pval *x3 = find_label_in_current_context((char *)item->u1.list->next->u1.str, (char *)item->u1.list->next->next->u1.str);
+									current_context = context_save;
+									if (x3) {
+										found = x3;
+										break;
+									}
+								}
+							}
+						}
+					}
+					if (!found) {
+						ast_log(LOG_ERROR,"Error: file %s, line %d-%d: goto:  no label %s|%s exists in the context %s or its inclusions!\n",
+								item->filename, item->startline, item->endline, item->u1.list->next->u1.str, item->u1.list->next->next->u1.str, item->u1.list->u1.str );
+						errs++;
+					}
+				} else {
+					ast_log(LOG_ERROR,"Error: file %s, line %d-%d: goto:  no context %s could be found that matches the goto target!\n",
+							item->filename, item->startline, item->endline, item->u1.list->u1.str);
+					errs++;
+				}
+			}
+		}
 	}
-	return 0;
 }
+	
+
+static void find_pval_goto_item(pval *item, int lev)
+{
+	struct pval *p4;
+	if (lev>100) {
+		ast_log(LOG_ERROR,"find_pval_goto in infinite loop!\n\n");
+		return;
+	}
+	
+	switch ( item->type ) {
+	case PV_MACRO:
+		/* fields: item->u1.str     == name of macro
+		           item->u2.arglist == pval list of PV_WORD arguments of macro, as given by user
+				   item->u2.arglist->u1.str  == argument
+				   item->u2.arglist->next   == next arg
+
+				   item->u3.macro_statements == pval list of statements in macro body.
+		*/
+			
+		/* printf("Descending into matching macro %s\n", match_context); */
+		find_pval_gotos(item->u2.statements,lev+1); /* if we're just searching for a context, don't bother descending into them */
+		
+		break;
+			
+	case PV_CONTEXT:
+		/* fields: item->u1.str     == name of context
+		           item->u2.statements == pval list of statements in context body
+				   item->u3.abstract == int 1 if an abstract keyword were present
+		*/
+		break;
+
+	case PV_CASE:
+		/* fields: item->u1.str     == value of case
+		           item->u2.statements == pval list of statements under the case
+		*/
+		find_pval_gotos(item->u2.statements,lev+1);
+		break;
+			
+	case PV_PATTERN:
+		/* fields: item->u1.str     == value of case
+		           item->u2.statements == pval list of statements under the case
+		*/
+		find_pval_gotos(item->u2.statements,lev+1);
+		break;
+			
+	case PV_DEFAULT:
+		/* fields: 
+		           item->u2.statements == pval list of statements under the case
+		*/
+		find_pval_gotos(item->u2.statements,lev+1);
+		break;
+			
+	case PV_CATCH:
+		/* fields: item->u1.str     == name of extension to catch
+		           item->u2.statements == pval list of statements in context body
+		*/
+		find_pval_gotos(item->u2.statements,lev+1);
+		break;
+			
+	case PV_STATEMENTBLOCK:
+		/* fields: item->u1.list     == pval list of statements in block, one per entry in the list
+		*/
+		find_pval_gotos(item->u1.list,lev+1);
+		break;
+			
+	case PV_GOTO:
+		/* fields: item->u1.list     == pval list of PV_WORD target names, up to 3, in order as given by user.
+		           item->u1.list->u1.str  == where the data on a PV_WORD will always be.
+		*/
+		check_goto(item);  /* THE WHOLE FUNCTION OF THIS ENTIRE ROUTINE!!!! */
+		break;
+			
+	case PV_INCLUDES:
+		/* fields: item->u1.list     == pval list of PV_WORD elements, one per entry in the list
+		*/
+		for (p4=item->u1.list; p4; p4=p4->next) {
+			/* for each context pointed to, find it, then find a context/label that matches the
+			   target here! */
+			char *incl_context = p4->u1.str;
+			/* find a matching context name */
+			struct pval *that_context = find_context(incl_context);
+			if (that_context) {
+				find_pval_gotos(that_context,lev+1); /* keep working up the includes */
+			}
+		}
+		break;
+		
+	case PV_FOR:
+		/* fields: item->u1.for_init     == a string containing the initalizer
+		           item->u2.for_test     == a string containing the loop test
+		           item->u3.for_inc      == a string containing the loop increment
+
+				   item->u4.for_statements == a pval list of statements in the for ()
+		*/
+		find_pval_gotos(item->u4.for_statements,lev+1);
+		break;
+			
+	case PV_WHILE:
+		/* fields: item->u1.str        == the while conditional, as supplied by user
+
+				   item->u2.statements == a pval list of statements in the while ()
+		*/
+		find_pval_gotos(item->u2.statements,lev+1);
+		break;
+			
+	case PV_RANDOM:
+		/* fields: item->u1.str        == the random number expression, as supplied by user
+
+				   item->u2.statements == a pval list of statements in the if ()
+				   item->u3.else_statements == a pval list of statements in the else
+											   (could be zero)
+		 fall thru to PV_IF */
+		
+	case PV_IFTIME:
+		/* fields: item->u1.list        == the time values, 4 of them, as PV_WORD structs in a list
+
+				   item->u2.statements == a pval list of statements in the if ()
+				   item->u3.else_statements == a pval list of statements in the else
+											   (could be zero)
+		fall thru to PV_IF*/
+	case PV_IF:
+		/* fields: item->u1.str        == the if conditional, as supplied by user
+
+				   item->u2.statements == a pval list of statements in the if ()
+				   item->u3.else_statements == a pval list of statements in the else
+											   (could be zero)
+		*/
+		find_pval_gotos(item->u2.statements,lev+1);
+
+		if (item->u3.else_statements) {
+			find_pval_gotos(item->u3.else_statements,lev+1);
+		}
+		break;
+			
+	case PV_SWITCH:
+		/* fields: item->u1.str        == the switch expression
+
+				   item->u2.statements == a pval list of statements in the switch, 
+				   							(will be case statements, most likely!)
+		*/
+		find_pval_gotos(item->u3.else_statements,lev+1);
+		break;
+			
+	case PV_EXTENSION:
+		/* fields: item->u1.str        == the extension name, label, whatever it's called
+
+				   item->u2.statements == a pval list of statements in the extension
+				   item->u3.hints      == a char * hint argument
+				   item->u4.regexten   == an int boolean. non-zero says that regexten was specified
+		*/
+
+		find_pval_gotos(item->u2.statements,lev+1);
+		break;
+
+	default:
+		break;
+	}
+}
+
+static void find_pval_gotos(pval *item,int lev)
+{
+	pval *i;
+
+	for (i=item; i; i=i->next) {
+		
+		find_pval_goto_item(i, lev);
+	}
+}
+
+
+
+/* general purpose label finder */
+static struct pval *match_pval_item(pval *item)
+{
+	pval *x;
+	
+	switch ( item->type ) {
+	case PV_MACRO:
+		/* fields: item->u1.str     == name of macro
+		           item->u2.arglist == pval list of PV_WORD arguments of macro, as given by user
+				   item->u2.arglist->u1.str  == argument
+				   item->u2.arglist->next   == next arg
+
+				   item->u3.macro_statements == pval list of statements in macro body.
+		*/
+		if (!strcmp(match_context,"*") || !strcmp(item->u1.str, match_context)) {
+			if (return_on_context_match && !strcmp(item->u1.str, match_context)) {
+				/* printf("Returning on matching macro %s\n", match_context); */
+				return item;
+			}
+			
+			
+			if (!return_on_context_match) {
+				/* printf("Descending into matching macro %s\n", match_context); */
+				if ((x=match_pval(item->u2.statements))) /* if we're just searching for a context, don't bother descending into them */ {
+					return x;
+				}
+			}
+		} else {
+			/* printf("Skipping context/macro %s\n", item->u1.str); */
+		}
+		
+		break;
+			
+	case PV_CONTEXT:
+		/* fields: item->u1.str     == name of context
+		           item->u2.statements == pval list of statements in context body
+				   item->u3.abstract == int 1 if an abstract keyword were present
+		*/
+		if (!strcmp(match_context,"*") || !strcmp(item->u1.str, match_context)) {
+			if (return_on_context_match && !strcmp(item->u1.str, match_context)) {
+				/* printf("Returning on matching context %s\n", match_context); */
+				return item;
+			}
+			
+			
+			if (!return_on_context_match ) {
+				/* printf("Descending into matching context %s\n", match_context); */
+				if ((x=match_pval(item->u2.statements))) /* if we're just searching for a context, don't bother descending into them */ {
+					return x;
+				}
+			}
+		} else {
+			/* printf("Skipping context/macro %s\n", item->u1.str); */
+		}
+		break;
+
+	case PV_CASE:
+		/* fields: item->u1.str     == value of case
+		           item->u2.statements == pval list of statements under the case
+		*/
+		if ((x=match_pval(item->u2.statements))) {
+			return x;
+		}
+		break;
+			
+	case PV_PATTERN:
+		/* fields: item->u1.str     == value of case
+		           item->u2.statements == pval list of statements under the case
+		*/
+		if ((x=match_pval(item->u2.statements))) {
+			return x;
+		}
+		break;
+			
+	case PV_DEFAULT:
+		/* fields: 
+		           item->u2.statements == pval list of statements under the case
+		*/
+		if ((x=match_pval(item->u2.statements))) {
+			return x;
+		}
+		break;
+			
+	case PV_CATCH:
+		/* fields: item->u1.str     == name of extension to catch
+		           item->u2.statements == pval list of statements in context body
+		*/
+		if ((x=match_pval(item->u2.statements))) {
+			return x;
+		}
+		break;
+			
+	case PV_STATEMENTBLOCK:
+		/* fields: item->u1.list     == pval list of statements in block, one per entry in the list
+		*/
+		if ((x=match_pval(item->u1.list))) {
+			return x;
+		}
+		break;
+			
+	case PV_LABEL:
+		/* fields: item->u1.str     == label name
+		*/
+		/* printf("PV_LABEL %s (cont=%s, exten=%s\n", 
+		   item->u1.str, current_context->u1.str, current_extension->u1.str); */
+		
+		if (count_labels) {
+			if (!strcmp(match_label, item->u1.str)) {
+				label_count++;
+				last_matched_label = item;
+			}
+			
+		} else {
+			if (!strcmp(match_label, item->u1.str)) {
+				return item;
+			}
+		}
+		break;
+			
+	case PV_FOR:
+		/* fields: item->u1.for_init     == a string containing the initalizer
+		           item->u2.for_test     == a string containing the loop test
+		           item->u3.for_inc      == a string containing the loop increment
+
+				   item->u4.for_statements == a pval list of statements in the for ()
+		*/
+		if ((x=match_pval(item->u4.for_statements))) {
+			return x;
+		}
+		break;
+			
+	case PV_WHILE:
+		/* fields: item->u1.str        == the while conditional, as supplied by user
+
+				   item->u2.statements == a pval list of statements in the while ()
+		*/
+		if ((x=match_pval(item->u2.statements))) {
+			return x;
+		}
+		break;
+			
+	case PV_RANDOM:
+		/* fields: item->u1.str        == the random number expression, as supplied by user
+
+				   item->u2.statements == a pval list of statements in the if ()
+				   item->u3.else_statements == a pval list of statements in the else
+											   (could be zero)
+		 fall thru to PV_IF */
+		
+	case PV_IFTIME:
+		/* fields: item->u1.list        == the time values, 4 of them, as PV_WORD structs in a list
+
+				   item->u2.statements == a pval list of statements in the if ()
+				   item->u3.else_statements == a pval list of statements in the else
+											   (could be zero)
+		fall thru to PV_IF*/
+	case PV_IF:
+		/* fields: item->u1.str        == the if conditional, as supplied by user
+
+				   item->u2.statements == a pval list of statements in the if ()
+				   item->u3.else_statements == a pval list of statements in the else
+											   (could be zero)
+		*/
+		if ((x=match_pval(item->u2.statements))) {
+			return x;
+		}
+		if (item->u3.else_statements) {
+			if ((x=match_pval(item->u3.else_statements))) {
+				return x;
+			}
+		}
+		break;
+			
+	case PV_SWITCH:
+		/* fields: item->u1.str        == the switch expression
+
+				   item->u2.statements == a pval list of statements in the switch, 
+				   							(will be case statements, most likely!)
+		*/
+		if ((x=match_pval(item->u3.else_statements))) {
+			return x;
+		}
+		break;
+			
+	case PV_EXTENSION:
+		/* fields: item->u1.str        == the extension name, label, whatever it's called
+
+				   item->u2.statements == a pval list of statements in the extension
+				   item->u3.hints      == a char * hint argument
+				   item->u4.regexten   == an int boolean. non-zero says that regexten was specified
+		*/
+		if (!strcmp(match_exten,"*") || extension_matches(item, match_exten, item->u1.str) ) {
+			/* printf("Descending into matching exten %s\n", match_exten); */
+			if (strcmp(match_label,"1") == 0) {
+				if (item->u2.statements) {
+					struct pval *p5 = item->u2.statements;
+					while (p5 && p5->type == PV_LABEL)  /* find the first non-label statement in this context. If it exists, there's a "1" */
+						p5 = p5->next;
+					if (p5)
+						return p5;
+					else
+						return 0;
+				}
+				else
+					return 0;
+			}
+
+			if ((x=match_pval(item->u2.statements))) {
+				return x;
+			}
+		} else {
+			/* printf("Skipping exten %s\n", item->u1.str); */
+		}
+		break;
+	default:
+		break;
+	}
+	return 0;
+}
+
+struct pval *match_pval(pval *item)
+{
+	pval *i;
+
+	for (i=item; i; i=i->next) {
+		pval *x;
+		
+		if ((x = match_pval_item(i)))
+			return x; /* cut the search short */
+	}
+	return 0;
+}
+
+
+int count_labels_in_current_context(char *label)
+{
+	label_count = 0;
+	count_labels = 1;
+	return_on_context_match = 0;
+	match_pval(current_context->u2.statements);
+	
+	return label_count;
+}
+
+struct pval *find_label_in_current_context(char *exten, char *label)
+{
+	/* printf("  --- Got args %s, %s\n", exten, label); */
+	struct pval *ret;
+	struct pval *p3;
+	
+	count_labels = 0;
+	return_on_context_match = 0;
+	match_context = "*";
+	match_exten = exten;
+	match_label = label;
+	ret =  match_pval(current_context->u2.statements);
+	if (ret)
+		return ret;
+					
+	/* the target of the goto could be in an included context!! Fancy that!! */
+	/* look for includes in the current context */
+	for (p3=current_context->u2.statements; p3; p3=p3->next) {
+		if (p3->type == PV_INCLUDES) {
+			struct pval *p4;
+			for (p4=p3->u1.list; p4; p4=p4->next) {
+				/* for each context pointed to, find it, then find a context/label that matches the
+				   target here! */
+				char *incl_context = p4->u1.str;
+				/* find a matching context name */
+				struct pval *that_context = find_context(incl_context);
+				if (that_context) {
+					struct pval *context_save = current_context;
+					current_context = that_context;
+					struct pval *x3 = find_label_in_current_context(exten, label);
+					current_context = context_save;
+					if (x3) {
+						return x3;
+					}
+				}
+			}
+		}
+	}
+	return 0;
+}
+
+struct pval *find_label_in_current_extension(char *label)
+{
+	/* printf("  --- Got args %s\n", label); */
+	count_labels = 0;
+	return_on_context_match = 0;
+	match_context = "*";
+	match_exten = "*";
+	match_label = label;
+	if (! current_extension) /* macros have no current extension, the whole thing is one extension... */
+		return match_pval(current_context->u3.macro_statements);
+	return match_pval(current_extension->u2.statements);
+}
+
+struct pval *find_label_in_current_db(char *context, char *exten, char *label)
+{
+	/* printf("  --- Got args %s, %s, %s\n", context, exten, label); */
+	count_labels = 0;
+	return_on_context_match = 0;
+
+	match_context = context;
+	match_exten = exten;
+	match_label = label;
+	
+	return match_pval(current_db);
+}
+
+
+struct pval *find_macro(char *name)
+{
+	return_on_context_match = 1;
+	count_labels = 0;
+	match_context = name;
+	match_exten = "*";  /* don't really need to set these, shouldn't be reached */
+	match_label = "*";
+	return match_pval(current_db);
+}
+
+struct pval *find_context(char *name)
+{
+	return_on_context_match = 1;
+	count_labels = 0;
+	match_context = name;
+	match_exten = "*";  /* don't really need to set these, shouldn't be reached */
+	match_label = "*";
+	return match_pval(current_db);
+}
+
+int is_float(char *arg )
+{
+	char *s;
+	for (s=arg; *s; s++) {
+		if (*s != '.' && (*s < '0' || *s > '9'))
+			return 0;
+	}
+	return 1;
+}
+int is_int(char *arg )
+{
+	char *s;
+	for (s=arg; *s; s++) {
+		if (*s < '0' || *s > '9')
+			return 0;
+	}
+	return 1;
+}
+int is_empty(char *arg)
+{
+	if (!arg)
+		return 1;
+	if (*arg == 0)
+		return 1;
+	while (*arg) {
+		if (*arg != ' ' && *arg != '\t')
+			return 0;
+		arg++;
+	}
+	return 1;
+}
+
+#ifdef AAL_ARGCHECK
+int option_matches_j( struct argdesc *should, pval *is, struct argapp *app)
+{
+	struct argchoice *ac;
+	char opcop[400],*q,*p;
+	
+	switch (should->dtype) {
+	case ARGD_OPTIONSET:
+		if ( strstr(is->u1.str,"${") )
+			return 0;  /* no checking anything if there's a var reference in there! */
+			
+		strncpy(opcop,is->u1.str,sizeof(opcop));
+
+		for (q=opcop;*q;q++) { /* erase the innards of X(innard) type arguments, so we don't get confused later */
+			if ( *q == '(' ) {
+				p = q+1;
+				while (*p && *p != ')' )
+					*p++ = '+';
+				q = p+1;
+			}
+		}
+		
+		for (ac=app->opts; ac; ac=ac->next) {
+			if (strlen(ac->name)>1  && strchr(ac->name,'(') == 0 && strcmp(ac->name,is->u1.str) == 0) /* multichar option, no parens, and a match? */
+				return 0;
+		}
+		for (ac=app->opts; ac; ac=ac->next) {
+			if (strlen(ac->name)==1  ||  strchr(ac->name,'(')) {
+				char *p = strchr(opcop,ac->name[0]);  /* wipe out all matched options in the user-supplied string */
+				
+				if (p && *p == 'j') {
+					ast_log(LOG_ERROR, "Error: file %s, line %d-%d: The j option in the %s application call is not appropriate for AEL!\n",
+							is->filename, is->startline, is->endline, app->name);
+					errs++;
+				}
+				
+				if (p) {
+					*p = '+';
+					if (ac->name[1] == '(') {
+						if (*(p+1) != '(') {
+							ast_log(LOG_WARNING, "Warning: file %s, line %d-%d: The %c option in the %s application call should have an (argument), but doesn't!\n",
+									is->filename, is->startline, is->endline, ac->name[0], app->name);
+							warns++;
+						}
+					}
+				}
+			}
+		}
+		for (q=opcop; *q; q++) {
+			if ( *q != '+' && *q != '(' && *q != ')') {
+				ast_log(LOG_WARNING, "Warning: file %s, line %d-%d: The %c option in the %s application call is not available as an option!\n",
+						is->filename, is->startline, is->endline, *q, app->name);
+				warns++;
+			}
+		}
+		return 1;
+		break;
+	default:
+		return 0;
+	}
+	
+}
+
+int option_matches( struct argdesc *should, pval *is, struct argapp *app)
+{
+	struct argchoice *ac;
+	char opcop[400];
+	
+	switch (should->dtype) {
+	case ARGD_STRING:
+		if (is_empty(is->u1.str) && should->type == ARGD_REQUIRED)
+			return 0;
+		if (is->u1.str && strlen(is->u1.str) > 0) /* most will match */
+			return 1;
+		break;
+		
+	case ARGD_INT:
+		if (is_int(is->u1.str))
+			return 1;
+		else
+			return 0;
+		break;
+		
+	case ARGD_FLOAT:
+		if (is_float(is->u1.str))
+			return 1;
+		else
+			return 0;
+		break;
+		
+	case ARGD_ENUM:
+		if( !is->u1.str || strlen(is->u1.str) == 0 )
+			return 1; /* a null arg in the call will match an enum, I guess! */
+		for (ac=should->choices; ac; ac=ac->next) {
+			if (strcmp(ac->name,is->u1.str) == 0)
+				return 1;
+		}
+		return 0;
+		break;
+		
+	case ARGD_OPTIONSET:
+		strncpy(opcop,is->u1.str,sizeof(opcop));
+		
+		for (ac=app->opts; ac; ac=ac->next) {
+			if (strlen(ac->name)>1  && strchr(ac->name,'(') == 0 && strcmp(ac->name,is->u1.str) == 0) /* multichar option, no parens, and a match? */
+				return 1;
+		}
+		for (ac=app->opts; ac; ac=ac->next) {
+			if (strlen(ac->name)==1  ||  strchr(ac->name,'(')) {
+				char *p = strchr(opcop,ac->name[0]);  /* wipe out all matched options in the user-supplied string */
+				
+				if (p) {
+					*p = '+';
+					if (ac->name[1] == '(') {
+						if (*(p+1) == '(') {
+							char *q = p+1;
+							while (*q && *q != ')') {
+								*q++ = '+';
+							}
+							*q = '+';
+						}
+					}
+				}
+			}
+		}
+		return 1;
+		break;
+	case ARGD_VARARG:
+		return 1; /* matches anything */
+		break;
+	}
+	return 1; /* unless some for-sure match or non-match returns, then it must be close enough ... */
+}
+#endif
+
+int check_app_args(pval* appcall, pval *arglist, struct argapp *app)
+{
+#ifdef AAL_ARGCHECK
+	struct argdesc *ad = app->args;
+	pval *pa;
+	int z;
+	
+	for (pa = arglist; pa; pa=pa->next) {
+		if (!ad) {
+			ast_log(LOG_WARNING, "Warning: file %s, line %d-%d: Extra argument %s not in application call to %s !\n",
+					arglist->filename, arglist->startline, arglist->endline, pa->u1.str, app->name);
+			warns++;
+			return 1;
+		} else {
+			/* find the first entry in the ad list that will match */
+			do {
+				if ( ad->dtype == ARGD_VARARG ) /* once we hit the VARARG, all bets are off. Discontinue the comparisons */
+					break;
+				
+				z= option_matches( ad, pa, app);
+				if (!z) {
+					if ( !arglist )
+						arglist=appcall;
+					
+					if (ad->type == ARGD_REQUIRED) {
+						ast_log(LOG_WARNING, "Warning: file %s, line %d-%d: Required argument %s not in application call to %s !\n",
+								arglist->filename, arglist->startline, arglist->endline, ad->dtype==ARGD_OPTIONSET?"options":ad->name, app->name);
+						warns++;
+						return 1;
+					}
+				} else if (z && ad->dtype == ARGD_OPTIONSET) {
+					option_matches_j( ad, pa, app);
+				}
+				ad = ad->next;
+			} while (ad && !z);
+		}
+	}
+	/* any app nodes left, that are not optional? */
+	for ( ; ad; ad=ad->next) {
+		if (ad->type == ARGD_REQUIRED && ad->dtype != ARGD_VARARG) {
+			if ( !arglist ) 
+				arglist=appcall;
+			ast_log(LOG_WARNING, "Warning: file %s, line %d-%d: Required argument %s not in application call to %s !\n",
+					arglist->filename, arglist->startline, arglist->endline, ad->dtype==ARGD_OPTIONSET?"options":ad->name, app->name);
+			warns++;
+			return 1;
+		}
+	}
+	return 0;
+#else
+	return 0;
+#endif
+}
+
+void check_switch_expr(pval *item, struct argapp *apps)
+{
+#ifdef AAL_ARGCHECK
+	/* get and clean the variable name */
+	char buff1[1024],*p;
+	struct argapp *a,*a2;
+	struct appsetvar *v,*v2;
+	struct argchoice *c;
+	pval *t;
+	
+	p = item->u1.str;
+	while (p && *p && (*p == ' ' || *p == '\t' || *p == '$' || *p == '{' ) )
+		p++;
+	
+	strncpy(buff1,p,sizeof(buff1));
+	while (strlen(buff1) > 0 && ( buff1[strlen(buff1)-1] == '}' || buff1[strlen(buff1)-1] == ' ' || buff1[strlen(buff1)-1] == '\t'))
+		buff1[strlen(buff1)-1] = 0;
+	/* buff1 now contains the variable name */
+	v = 0;
+	for (a=apps; a; a=a->next) {
+		for (v=a->setvars;v;v=v->next) {
+			if (strcmp(v->name,buff1) == 0) {
+				break;
+			}
+		}
+		if ( v )
+			break;
+	}
+	if (v && v->vals) {
+		/* we have a match, to a variable that has a set of determined values */
+		int def= 0;
+		int pat = 0;
+		int f1 = 0;
+		
+		/* first of all, does this switch have a default case ? */
+		for (t=item->u2.statements; t; t=t->next) {
+			if (t->type == PV_DEFAULT) {
+				def =1;
+				break;
+			}
+			if (t->type == PV_PATTERN) {
+				pat++;
+			}
+		}
+		if (def || pat) /* nothing to check. All cases accounted for! */
+			return;
+		for (c=v->vals; c; c=c->next) {
+			f1 = 0;
+			for (t=item->u2.statements; t; t=t->next) {
+				if (t->type == PV_CASE || t->type == PV_PATTERN) {
+					if (!strcmp(t->u1.str,c->name)) {
+						f1 = 1;
+						break;
+					}
+				}
+			}
+			if (!f1) {
+				ast_log(LOG_WARNING,"Warning: file %s, line %d-%d: switch with expression(%s) does not handle the case of %s !\n",
+						item->filename, item->startline, item->endline, item->u1.str, c->name);
+				warns++;
+			}
+		}
+		/* next, is there an app call in the current exten, that would set this var? */
+		f1 = 0;
+		t = current_extension->u2.statements;
+		if ( t && t->type == PV_STATEMENTBLOCK )
+			t = t->u1.statements;
+		for (; t && t != item; t=t->next) {
+			if (t->type == PV_APPLICATION_CALL) {
+				/* find the application that matches the u1.str */
+				for (a2=apps; a2; a2=a2->next) {
+					if (strcasecmp(a2->name, t->u1.str)==0) {
+						for (v2=a2->setvars; v2; v2=v2->next) {
+							if (strcmp(v2->name, buff1) == 0) {
+								/* found an app that sets the var */
+								f1 = 1;
+								break;
+							}
+						}
+					}
+					if (f1)
+						break;
+				}
+			}
+			if (f1)
+				break;
+		}
+				
+		/* see if it sets the var */
+		if (!f1) {
+			ast_log(LOG_WARNING,"Warning: file %s, line %d-%d: Couldn't find an application call in this extension that sets the  expression (%s) value!\n",
+					item->filename, item->startline, item->endline, item->u1.str);
+			warns++;
+		}
+	}
+#endif
+}
+
+static void check_context_names(void)
+{
+	pval *i,*j;
+	for (i=current_db; i; i=i->next) {
+		if (i->type == PV_CONTEXT || i->type == PV_MACRO) {
+			for (j=i->next; j; j=j->next) {
+				if ( j->type == PV_CONTEXT || j->type == PV_MACRO ) {
+					if ( !strcmp(i->u1.str, j->u1.str) )
+					{
+						ast_log(LOG_WARNING,"Warning: file %s, line %d-%d: The context name (%s) is also declared in file %s, line %d-%d!\n",
+								i->filename, i->startline, i->endline, i->u1.str,  j->filename, j->startline, j->endline);
+						warns++;
+					}
+				}
+			}
+		}
+	}
+}
+
+static void check_abstract_reference(pval *abstract_context)
+{
+	pval *i,*j;
+	/* find some context includes that reference this context */
+	
+
+	/* otherwise, print out a warning */
+	for (i=current_db; i; i=i->next) {
+		if (i->type == PV_CONTEXT) {
+			for (j=i->u2. statements; j; j=j->next) {
+				if ( j->type == PV_INCLUDES ) {
+					struct pval *p4;
+					for (p4=j->u1.list; p4; p4=p4->next) {
+						/* for each context pointed to, find it, then find a context/label that matches the
+						   target here! */
+						if ( !strcmp(p4->u1.str, abstract_context->u1.str) )
+							return; /* found a match! */
+					}
+				}
+			}
+		}
+	}
+	ast_log(LOG_WARNING,"Warning: file %s, line %d-%d: Couldn't find a reference to this abstract context (%s) in any other context!\n",
+			abstract_context->filename, abstract_context->startline, abstract_context->endline, abstract_context->u1.str);
+	warns++;
+}
+
+
+void check_pval_item(pval *item, struct argapp *apps)
+{
+	pval *lp;
+#ifdef AAL_ARGCHECK
+	struct argapp *app, *found;
+#endif
+	struct pval *macro_def;
+	struct pval *app_def;
+	
+	char errmsg[4096];
+	char *strp;
+	
+	switch (item->type) {
+	case PV_WORD:
+		/* fields: item->u1.str == string associated with this (word).
+		           item->u2.arglist  == pval list of 4 PV_WORD elements for time values (only in PV_INCLUDES) */
+		break;
+		
+	case PV_MACRO:
+		/* fields: item->u1.str     == name of macro
+		           item->u2.arglist == pval list of PV_WORD arguments of macro, as given by user
+				   item->u2.arglist->u1.str  == argument
+				   item->u2.arglist->next   == next arg
+
+				   item->u3.macro_statements == pval list of statements in macro body.
+		*/
+		in_abstract_context = 0;
+		current_context = item;
+		current_extension = 0;
+		for (lp=item->u2.arglist; lp; lp=lp->next) {
+		
+		}
+		check_pval(item->u3.macro_statements, apps);
+		break;
+			
+	case PV_CONTEXT:
+		/* fields: item->u1.str     == name of context
+		           item->u2.statements == pval list of statements in context body
+				   item->u3.abstract == int 1 if an abstract keyword were present
+		*/
+		current_context = item;
+		current_extension = 0;
+		if ( item->u3.abstract ) {
+			in_abstract_context = 1;
+			check_abstract_reference(item);
+		} else
+			in_abstract_context = 0;
+		check_pval(item->u2.statements, apps);
+		break;
+			
+	case PV_MACRO_CALL:
+		/* fields: item->u1.str     == name of macro to call
+		           item->u2.arglist == pval list of PV_WORD arguments of macro call, as given by user
+				   item->u2.arglist->u1.str  == argument
+				   item->u2.arglist->next   == next arg
+		*/
+		macro_def = find_macro(item->u1.str);
+		if (!macro_def) {
+			ast_log(LOG_ERROR, "Error: file %s, line %d-%d: macro call to non-existent %s !\n",
+					item->filename, item->startline, item->endline, item->u1.str);
+			errs++;
+		} else if (macro_def->type != PV_MACRO) {
+			ast_log(LOG_ERROR,"Error: file %s, line %d-%d: macro call to %s references a context, not a macro!\n",
+					item->filename, item->startline, item->endline, item->u1.str);
+			errs++;
+		} else {
+			/* macro_def is a MACRO, so do the args match in number? */
+			int hereargs = 0;
+			int thereargs = 0;
+			
+			for (lp=item->u2.arglist; lp; lp=lp->next) {
+				hereargs++;
+			}
+			for (lp=macro_def->u2.arglist; lp; lp=lp->next) {
+				thereargs++;
+			}
+			if (hereargs != thereargs ) {
+				ast_log(LOG_ERROR, "Error: file %s, line %d-%d: The macro call to %s has %d arguments, but the macro definition has %d arguments\n",
+						item->filename, item->startline, item->endline, item->u1.str, hereargs, thereargs);
+				errs++;
+			}
+		}
+		break;
+			
+	case PV_APPLICATION_CALL:
+		/* fields: item->u1.str     == name of application to call
+		           item->u2.arglist == pval list of PV_WORD arguments of macro call, as given by user
+				   item->u2.arglist->u1.str  == argument
+				   item->u2.arglist->next   == next arg
+		*/
+		/* Need to check to see if the application is available! */
+		app_def = find_context(item->u1.str);
+		if (app_def && app_def->type == PV_MACRO) {
+			ast_log(LOG_ERROR,"Error: file %s, line %d-%d: application call to %s references an existing macro, but had no & preceding it!\n",
+					item->filename, item->startline, item->endline, item->u1.str);
+			errs++;
+		}
+		if (strcasecmp(item->u1.str,"GotoIf") == 0
+			|| strcasecmp(item->u1.str,"GotoIfTime") == 0
+			|| strcasecmp(item->u1.str,"while") == 0
+			|| strcasecmp(item->u1.str,"endwhile") == 0
+			|| strcasecmp(item->u1.str,"random") == 0
+			|| strcasecmp(item->u1.str,"execIf") == 0 ) {
+			ast_log(LOG_WARNING,"Warning: file %s, line %d-%d: application call to %s needs to be re-written using AEL if, while, goto, etc. keywords instead!\n",
+					item->filename, item->startline, item->endline, item->u1.str);
+			warns++;
+		}
+#ifdef AAL_ARGCHECK
+		found = 0;
+		for (app=apps; app; app=app->next) {
+			if (strcasecmp(app->name, item->u1.str) == 0) {
+				found =app;
+				break;
+			}
+		}
+		if (!found) {
+			ast_log(LOG_WARNING,"Warning: file %s, line %d-%d: application call to %s not listed in applist database!\n",
+					item->filename, item->startline, item->endline, item->u1.str);
+			warns++;
+		} else
+			check_app_args(item, item->u2.arglist, app);
+#endif
+		break;
+		
+	case PV_CASE:
+		/* fields: item->u1.str     == value of case
+		           item->u2.statements == pval list of statements under the case
+		*/
+		/* Make sure sequence of statements under case is terminated with  goto, return, or break */
+		/* find the last statement */
+		check_pval(item->u2.statements, apps);
+		break;
+			
+	case PV_PATTERN:
+		/* fields: item->u1.str     == value of case
+		           item->u2.statements == pval list of statements under the case
+		*/
+		/* Make sure sequence of statements under case is terminated with  goto, return, or break */
+		/* find the last statement */
+		
+		check_pval(item->u2.statements, apps);
+		break;
+			
+	case PV_DEFAULT:
+		/* fields: 
+		           item->u2.statements == pval list of statements under the case
+		*/
+
+		check_pval(item->u2.statements, apps);
+		break;
+			
+	case PV_CATCH:
+		/* fields: item->u1.str     == name of extension to catch
+		           item->u2.statements == pval list of statements in context body
+		*/
+		check_pval(item->u2.statements, apps);
+		break;
+			
+	case PV_SWITCHES:
+		/* fields: item->u1.list     == pval list of PV_WORD elements, one per entry in the list
+		*/
+		check_pval(item->u1.list, apps);
+		break;
+			
+	case PV_ESWITCHES:
+		/* fields: item->u1.list     == pval list of PV_WORD elements, one per entry in the list
+		*/
+		check_pval(item->u1.list, apps);
+		break;
+			
+	case PV_INCLUDES:
+		/* fields: item->u1.list     == pval list of PV_WORD elements, one per entry in the list
+		*/
+		check_pval(item->u1.list, apps);
+		for (lp=item->u1.list; lp; lp=lp->next){
+			char *incl_context = lp->u1.str;
+			struct pval *that_context = find_context(incl_context);
+
+			if ( lp->u2.arglist ) {
+				check_timerange(lp->u2.arglist);
+				check_dow(lp->u2.arglist->next);
+				check_day(lp->u2.arglist->next->next);
+				check_month(lp->u2.arglist->next->next->next);
+			}
+			
+			if (that_context) {
+				find_pval_gotos(that_context->u2.statements,0);
+				
+			}
+		}
+		break;
+			
+	case PV_STATEMENTBLOCK:
+		/* fields: item->u1.list     == pval list of statements in block, one per entry in the list
+		*/
+		check_pval(item->u1.list, apps);
+		break;
+			
+	case PV_VARDEC:
+		/* fields: item->u1.str     == variable name
+		           item->u2.val     == variable value to assign
+		*/
+		/* the RHS of a vardec is encapsulated in a $[] expr. Is it legal? */
+		snprintf(errmsg,sizeof(errmsg), "file %s, line %d, columns %d-%d, variable declaration expr '%s':", config, item->startline, item->startcol, item->endcol, item->u2.val);
+		ast_expr_register_extra_error_info(errmsg);
+		ast_expr(item->u2.val, expr_output, sizeof(expr_output));
+		ast_expr_clear_extra_error_info();
+		if ( strpbrk(item->u2.val,"~!-+<>=*/&^") && !strstr(item->u2.val,"${") ) {
+			ast_log(LOG_WARNING,"Warning: file %s, line %d-%d: expression %s has operators, but no variables. Interesting...\n",
+					item->filename, item->startline, item->endline, item->u2.val);
+			warns++;
+		}
+		check_expr2_input(item,item->u2.val);
+		break;
+			
+	case PV_GOTO:
+		/* fields: item->u1.list     == pval list of PV_WORD target names, up to 3, in order as given by user.
+		           item->u1.list->u1.str  == where the data on a PV_WORD will always be.
+		*/
+		/* don't check goto's in abstract contexts */
+		if ( in_abstract_context )
+			break;
+		
+		check_goto(item);
+		break;
+			
+	case PV_LABEL:
+		/* fields: item->u1.str     == label name
+		*/
+		if ( strspn(item->u1.str, "0123456789") == strlen(item->u1.str) ) {
+			ast_log(LOG_WARNING,"Warning: file %s, line %d-%d: label '%s' is numeric, this is bad practice!\n",
+					item->filename, item->startline, item->endline, item->u1.str);
+			warns++;
+		}
+		break;
+			
+	case PV_FOR:
+		/* fields: item->u1.for_init     == a string containing the initalizer
+		           item->u2.for_test     == a string containing the loop test
+		           item->u3.for_inc      == a string containing the loop increment
+
+				   item->u4.for_statements == a pval list of statements in the for ()
+		*/
+		snprintf(errmsg,sizeof(errmsg),"file %s, line %d, columns %d-%d, for test expr '%s':", config, item->startline, item->startcol, item->endcol, item->u2.for_test);
+		ast_expr_register_extra_error_info(errmsg);
+
+		strp = strchr(item->u1.for_init, '=');
+		if (strp) {
+			ast_expr(strp+1, expr_output, sizeof(expr_output));
+		}
+		ast_expr(item->u2.for_test, expr_output, sizeof(expr_output));
+		strp = strchr(item->u3.for_inc, '=');
+		if (strp) {
+			ast_expr(strp+1, expr_output, sizeof(expr_output));
+		}
+		if ( strpbrk(item->u2.for_test,"~!-+<>=*/&^") && !strstr(item->u2.for_test,"${") ) {
+			ast_log(LOG_WARNING,"Warning: file %s, line %d-%d: expression %s has operators, but no variables. Interesting...\n",
+					item->filename, item->startline, item->endline, item->u2.for_test);
+			warns++;
+		}
+		if ( strpbrk(item->u3.for_inc,"~!-+<>=*/&^") && !strstr(item->u3.for_inc,"${") ) {
+			ast_log(LOG_WARNING,"Warning: file %s, line %d-%d: expression %s has operators, but no variables. Interesting...\n",
+					item->filename, item->startline, item->endline, item->u3.for_inc);
+			warns++;
+		}
+		check_expr2_input(item,item->u2.for_test);
+		check_expr2_input(item,item->u3.for_inc);
+		
+		ast_expr_clear_extra_error_info();
+		check_pval(item->u4.for_statements, apps);
+		break;
+			
+	case PV_WHILE:
+		/* fields: item->u1.str        == the while conditional, as supplied by user
+
+				   item->u2.statements == a pval list of statements in the while ()
+		*/
+		snprintf(errmsg,sizeof(errmsg),"file %s, line %d, columns %d-%d, while expr '%s':", config, item->startline, item->startcol, item->endcol, item->u1.str);
+		ast_expr_register_extra_error_info(errmsg);
+		ast_expr(item->u1.str, expr_output, sizeof(expr_output));
+		ast_expr_clear_extra_error_info();
+		if ( strpbrk(item->u1.str,"~!-+<>=*/&^") && !strstr(item->u1.str,"${") ) {
+			ast_log(LOG_WARNING,"Warning: file %s, line %d-%d: expression %s has operators, but no variables. Interesting...\n",
+					item->filename, item->startline, item->endline, item->u1.str);
+			warns++;
+		}
+		check_expr2_input(item,item->u1.str);
+		check_pval(item->u2.statements, apps);
+		break;
+			
+	case PV_BREAK:
+		/* fields: none
+		*/
+		break;
+			
+	case PV_RETURN:
+		/* fields: none
+		*/
+		break;
+			
+	case PV_CONTINUE:
+		/* fields: none
+		*/
+		break;
+			
+	case PV_RANDOM:
+		/* fields: item->u1.str        == the random number expression, as supplied by user
+
+				   item->u2.statements == a pval list of statements in the if ()
+				   item->u3.else_statements == a pval list of statements in the else
+											   (could be zero)
+		*/
+		snprintf(errmsg,sizeof(errmsg),"file %s, line %d, columns %d-%d, random expr '%s':", config, item->startline, item->startcol, item->endcol, item->u1.str);
+		ast_expr_register_extra_error_info(errmsg);
+		ast_expr(item->u1.str, expr_output, sizeof(expr_output));
+		ast_expr_clear_extra_error_info();
+		if ( strpbrk(item->u1.str,"~!-+<>=*/&^") && !strstr(item->u1.str,"${") ) {
+			ast_log(LOG_WARNING,"Warning: file %s, line %d-%d: random expression '%s' has operators, but no variables. Interesting...\n",
+					item->filename, item->startline, item->endline, item->u1.str);
+			warns++;
+		}
+		check_expr2_input(item,item->u1.str);
+		check_pval(item->u2.statements, apps);
+		if (item->u3.else_statements) {
+			check_pval(item->u3.else_statements, apps);
+		}
+		break;
+
+	case PV_IFTIME:
+		/* fields: item->u1.list        == the if time values, 4 of them, each in PV_WORD, linked list 
+
+				   item->u2.statements == a pval list of statements in the if ()
+				   item->u3.else_statements == a pval list of statements in the else
+											   (could be zero)
+		*/
+		if ( item->u2.arglist ) {
+			check_timerange(item->u1.list);
+			check_dow(item->u1.list->next);
+			check_day(item->u1.list->next->next);
+			check_month(item->u1.list->next->next->next);
+		}
+
+		check_pval(item->u2.statements, apps);
+		if (item->u3.else_statements) {
+			check_pval(item->u3.else_statements, apps);
+		}
+		break;
+			
+	case PV_IF:
+		/* fields: item->u1.str        == the if conditional, as supplied by user
+
+				   item->u2.statements == a pval list of statements in the if ()
+				   item->u3.else_statements == a pval list of statements in the else
+											   (could be zero)
+		*/
+		snprintf(errmsg,sizeof(errmsg),"file %s, line %d, columns %d-%d, if expr '%s':", config, item->startline, item->startcol, item->endcol, item->u1.str);
+		ast_expr_register_extra_error_info(errmsg);
+		ast_expr(item->u1.str, expr_output, sizeof(expr_output));
+		ast_expr_clear_extra_error_info();
+		if ( strpbrk(item->u1.str,"~!-+<>=*/&^") && !strstr(item->u1.str,"${") ) {
+			ast_log(LOG_WARNING,"Warning: file %s, line %d-%d: expression '%s' has operators, but no variables. Interesting...\n",
+					item->filename, item->startline, item->endline, item->u1.str);
+			warns++;
+		}
+		check_expr2_input(item,item->u1.str);
+		check_pval(item->u2.statements, apps);
+		if (item->u3.else_statements) {
+			check_pval(item->u3.else_statements, apps);
+		}
+		break;
+			
+	case PV_SWITCH:
+		/* fields: item->u1.str        == the switch expression
+
+				   item->u2.statements == a pval list of statements in the switch, 
+				   							(will be case statements, most likely!)
+		*/
+		/* we can check the switch expression, see if it matches any of the app variables...
+           if it does, then, are all the possible cases accounted for? */
+		check_switch_expr(item, apps);
+		check_pval(item->u2.statements, apps);
+		break;
+			
+	case PV_EXTENSION:
+		/* fields: item->u1.str        == the extension name, label, whatever it's called
+
+				   item->u2.statements == a pval list of statements in the extension
+				   item->u3.hints      == a char * hint argument
+				   item->u4.regexten   == an int boolean. non-zero says that regexten was specified
+		*/
+		current_extension = item ;
+		
+		check_pval(item->u2.statements, apps);
+		break;
+			
+	case PV_IGNOREPAT:
+		/* fields: item->u1.str        == the ignorepat data
+		*/
+		break;
+			
+	case PV_GLOBALS:
+		/* fields: item->u1.statements     == pval list of statements, usually vardecs
+		*/
+		in_abstract_context = 0;
+		check_pval(item->u1.statements, apps);
+		break;
+	default:
+		break;
+	}
+}
+
+void check_pval(pval *item, struct argapp *apps)
+{
+	pval *i;
+
+	/* checks to do:
+	   1. Do goto's point to actual labels? 
+	   2. Do macro calls reference a macro?
+	   3. Does the number of macro args match the definition?
+	   4. Is a macro call missing its & at the front?
+	   5. Application calls-- we could check syntax for existing applications,
+	      but I need some some sort of universal description bnf for a general
+		  sort of method for checking arguments, in number, maybe even type, at least. 
+		  Don't want to hand code checks for hundreds of applications.
+	*/
+	
+	for (i=item; i; i=i->next) {
+		check_pval_item(i,apps);
+	}
+}
+
+void ael2_semantic_check(pval *item, int *arg_errs, int *arg_warns, int *arg_notes)
+{
+	
+#ifdef AAL_ARGCHECK
+	int argapp_errs =0;
+	char *rfilename;
+#endif
+	struct argapp *apps=0;
+
+#ifdef AAL_ARGCHECK
+	rfilename = alloca(10 + strlen(ast_config_AST_VAR_DIR));
+	sprintf(rfilename, "%s/applist", ast_config_AST_VAR_DIR);
+	
+	apps = argdesc_parse(rfilename, &argapp_errs); /* giveth */
+#endif
+	current_db = item;
+	errs = warns = notes = 0;
+
+	check_context_names();
+	check_pval(item, apps);
+
+#ifdef AAL_ARGCHECK
+	argdesc_destroy(apps);  /* taketh away */
+#endif
+	current_db = 0;
+
+	*arg_errs = errs;
+	*arg_warns = warns;
+	*arg_notes = notes;
+}
+
+/* =============================================================================================== */
+/* "CODE" GENERATOR -- Convert the AEL representation to asterisk extension language */
+/* =============================================================================================== */
+
+static int control_statement_count = 0;
+
+struct ael_priority *new_prio(void)
+{
+	struct ael_priority *x = (struct ael_priority *)calloc(sizeof(struct ael_priority),1);
+	return x;
+}
+
+struct ael_extension *new_exten(void)
+{
+	struct ael_extension *x = (struct ael_extension *)calloc(sizeof(struct ael_extension),1);
+	return x;
+}
+
+void linkprio(struct ael_extension *exten, struct ael_priority *prio)
+{
+	if (!exten->plist) {
+		exten->plist = prio;
+		exten->plist_last = prio;
+	} else {
+		exten->plist_last->next = prio;
+		exten->plist_last = prio;
+	}
+}
+
+void destroy_extensions(struct ael_extension *exten)
+{
+	struct ael_extension *ne, *nen;
+	for (ne=exten; ne; ne=nen) {
+		struct ael_priority *pe, *pen;
+		
+		if (ne->name)
+			free(ne->name);
+		
+		if (ne->hints)
+			free(ne->hints);
+		
+		for (pe=ne->plist; pe; pe=pen) {
+			pen = pe->next;
+			if (pe->app)
+				free(pe->app);
+			pe->app = 0;
+			if (pe->appargs)
+				free(pe->appargs);
+			pe->appargs = 0;
+			pe->origin = 0;
+			pe->goto_true = 0;
+			pe->goto_false = 0;
+			free(pe);
+		}
+		nen = ne->next_exten;
+		ne->next_exten = 0;
+		ne->plist =0;
+		ne->plist_last = 0;
+		ne->next_exten = 0;
+		ne->loop_break = 0;
+		ne->loop_continue = 0;
+		free(ne);
+	}
+}
+
+void linkexten(struct ael_extension *exten, struct ael_extension *add)
+{
+	add->next_exten = exten->next_exten; /* this will reverse the order. Big deal. */
+	exten->next_exten = add;
+}
+
+void gen_prios(struct ael_extension *exten, char *label, pval *statement, struct ael_extension *mother_exten )
+{
+	pval *p,*p2,*p3;
+	struct ael_priority *pr;
+	struct ael_priority *for_init, *for_test, *for_inc, *for_loop, *for_end;
+	struct ael_priority *while_test, *while_loop, *while_end;
+	struct ael_priority *switch_test, *switch_end, *fall_thru;
+	struct ael_priority *if_test, *if_end, *if_skip, *if_false;
+#ifdef OLD_RAND_ACTION
+	struct ael_priority *rand_test, *rand_end, *rand_skip;
+#endif
+	char buf1[2000];
+	char buf2[2000];
+	char *strp, *strp2;
+	char new_label[2000];
+	int default_exists;
+	struct ael_priority *loop_break_save;
+	struct ael_priority *loop_continue_save;
+	struct ael_extension *switch_case;
+	
+	for (p=statement; p; p=p->next) {
+		switch (p->type) {
+		case PV_VARDEC:
+			pr = new_prio();
+			pr->type = AEL_APPCALL;
+			snprintf(buf1,sizeof(buf1),"%s=$[%s]", p->u1.str, p->u2.val);
+			pr->app = strdup("Set");
+			pr->appargs = strdup(buf1);
+			pr->origin = p;
+			linkprio(exten, pr);
+			break;
+
+		case PV_GOTO:
+			pr = new_prio();
+			pr->type = AEL_APPCALL;
+			if (!p->u1.list->next) /* just one */ {
+				pr->app = strdup("Goto");
+				if (!mother_exten)
+					pr->appargs = strdup(p->u1.list->u1.str);
+				else {  /* for the case of simple within-extension gotos in case/pattern/default statement blocks: */ 
+					snprintf(buf1,sizeof(buf1),"%s|%s", mother_exten->name, p->u1.list->u1.str);
+					pr->appargs = strdup(buf1);
+				}
+				
+			} else if (p->u1.list->next && !p->u1.list->next->next) /* two */ {
+				snprintf(buf1,sizeof(buf1),"%s|%s", p->u1.list->u1.str, p->u1.list->next->u1.str);
+				pr->app = strdup("Goto");
+				pr->appargs = strdup(buf1);
+			} else if (p->u1.list->next && p->u1.list->next->next) {
+				snprintf(buf1,sizeof(buf1),"%s|%s|%s", p->u1.list->u1.str, 
+						p->u1.list->next->u1.str,
+						p->u1.list->next->next->u1.str);
+				pr->app = strdup("Goto");
+				pr->appargs = strdup(buf1);
+			}
+			pr->origin = p;
+			linkprio(exten, pr);
+			break;
+
+		case PV_LABEL:
+			pr = new_prio();
+			pr->type = AEL_LABEL;
+			pr->origin = p;
+			linkprio(exten, pr);
+			break;
+
+		case PV_FOR:
+			control_statement_count++;
+			loop_break_save = exten->loop_break; /* save them, then restore before leaving */
+			loop_continue_save = exten->loop_continue;
+			snprintf(new_label,sizeof(new_label),"for-%s-%d", label, control_statement_count);
+			for_init = new_prio();
+			for_inc = new_prio();
+			for_test = new_prio();
+			for_loop = new_prio();
+			for_end = new_prio();
+			for_init->type = AEL_APPCALL;
+			for_inc->type = AEL_APPCALL;
+			for_test->type = AEL_FOR_CONTROL;
+			for_test->goto_false = for_end;
+			for_loop->type = AEL_CONTROL1; /* simple goto */
+			for_end->type = AEL_APPCALL;
+			for_init->app = strdup("Set");
+			
+			strcpy(buf2,p->u1.for_init);
+			strp = strchr(buf2, '=');
+			strp2 = strchr(p->u1.for_init, '=');
+			if (strp) {
+				*(strp+1) = 0;
+				strcat(buf2,"$[");
+				strncat(buf2,strp2+1, sizeof(buf2)-strlen(strp2+1)-2);
+				strcat(buf2,"]");
+				for_init->appargs = strdup(buf2);
+			} else
+				for_init->appargs = strdup(p->u1.for_init);
+
+			for_inc->app = strdup("Set");
+
+			strcpy(buf2,p->u3.for_inc);
+			strp = strchr(buf2, '=');
+			strp2 = strchr(p->u3.for_inc, '=');
+			if (strp) {
+				*(strp+1) = 0;
+				strcat(buf2,"$[");
+				strncat(buf2,strp2+1, sizeof(buf2)-strlen(strp2+1)-2);
+				strcat(buf2,"]");
+				for_inc->appargs = strdup(buf2);
+			} else
+				for_inc->appargs = strdup(p->u3.for_inc);
+			snprintf(buf1,sizeof(buf1),"$[%s]",p->u2.for_test);
+			for_test->app = 0;
+			for_test->appargs = strdup(buf1);
+			for_loop->goto_true = for_test;
+			snprintf(buf1,sizeof(buf1),"Finish for-%s-%d", label, control_statement_count);
+			for_end->app = strdup("NoOp");
+			for_end->appargs = strdup(buf1);
+			/* link & load! */
+			linkprio(exten, for_init);
+			linkprio(exten, for_test);
+			
+			/* now, put the body of the for loop here */
+			exten->loop_break = for_end;
+			exten->loop_continue = for_test;
+			
+			gen_prios(exten, new_label, p->u4.for_statements, mother_exten); /* this will link in all the statements here */
+			
+			linkprio(exten, for_inc);
+			linkprio(exten, for_loop);
+			linkprio(exten, for_end);
+			
+			
+			exten->loop_break = loop_break_save;
+			exten->loop_continue = loop_continue_save;
+			for_loop->origin = p;
+			break;
+
+		case PV_WHILE:
+			control_statement_count++;
+			loop_break_save = exten->loop_break; /* save them, then restore before leaving */
+			loop_continue_save = exten->loop_continue;
+			snprintf(new_label,sizeof(new_label),"while-%s-%d", label, control_statement_count);
+			while_test = new_prio();
+			while_loop = new_prio();
+			while_end = new_prio();
+			while_test->type = AEL_FOR_CONTROL;
+			while_test->goto_false = while_end;
+			while_loop->type = AEL_CONTROL1; /* simple goto */
+			while_end->type = AEL_APPCALL;
+			snprintf(buf1,sizeof(buf1),"$[%s]",p->u1.str);
+			while_test->app = 0;
+			while_test->appargs = strdup(buf1);
+			while_loop->goto_true = while_test;
+			snprintf(buf1,sizeof(buf1),"Finish while-%s-%d", label, control_statement_count);
+			while_end->app = strdup("NoOp");
+			while_end->appargs = strdup(buf1);
+
+			linkprio(exten, while_test);
+			
+			/* now, put the body of the for loop here */
+			exten->loop_break = while_end;
+			exten->loop_continue = while_test;
+			
+			gen_prios(exten, new_label, p->u2.statements, mother_exten); /* this will link in all the while body statements here */
+
+			linkprio(exten, while_loop);
+			linkprio(exten, while_end);
+			
+			
+			exten->loop_break = loop_break_save;
+			exten->loop_continue = loop_continue_save;
+			while_loop->origin = p;
+			break;
+
+		case PV_SWITCH:
+			control_statement_count++;
+			loop_break_save = exten->loop_break; /* save them, then restore before leaving */
+			loop_continue_save = exten->loop_continue;
+			snprintf(new_label,sizeof(new_label),"sw-%s-%d", label, control_statement_count);
+
+			switch_test = new_prio();
+			switch_end = new_prio();
+			switch_test->type = AEL_APPCALL;
+			switch_end->type = AEL_APPCALL;
+			snprintf(buf1,sizeof(buf1),"sw-%d-%s|1",control_statement_count, p->u1.str);
+			switch_test->app = strdup("Goto");
+			switch_test->appargs = strdup(buf1);
+			snprintf(buf1,sizeof(buf1),"Finish switch-%s-%d", label, control_statement_count);
+			switch_end->app = strdup("NoOp");
+			switch_end->appargs = strdup(buf1);
+			switch_end->origin = p;
+			switch_end->exten = exten;
+
+			linkprio(exten, switch_test);
+			linkprio(exten, switch_end);
+			
+			exten->loop_break = switch_end;
+			exten->loop_continue = 0;
+			default_exists = 0;
+			
+			for (p2=p->u2.statements; p2; p2=p2->next) {
+				/* now, for each case/default put the body of the for loop here */
+				if (p2->type == PV_CASE) {
+					/* ok, generate a extension and link it in */
+					switch_case = new_exten();
+					/* the break/continue locations are inherited from parent */
+					switch_case->loop_break = exten->loop_break;
+					switch_case->loop_continue = exten->loop_continue;
+					
+					linkexten(exten,switch_case);
+					snprintf(buf1,sizeof(buf1),"sw-%d-%s", control_statement_count, p2->u1.str);
+					switch_case->name = strdup(buf1);
+					snprintf(new_label,sizeof(new_label),"sw-%s-%s-%d", label, p2->u1.str, control_statement_count);
+					
+					gen_prios(switch_case, new_label, p2->u2.statements, exten); /* this will link in all the case body statements here */
+
+					/* here is where we write code to "fall thru" to the next case... if there is one... */
+					for (p3=p2->u2.statements; p3; p3=p3->next) {
+						if (!p3->next)
+							break;
+					}
+					/* p3 now points the last statement... */
+					if (!p3 || ( p3->type != PV_GOTO && p3->type != PV_BREAK && p3->type != PV_RETURN) ) {
+						/* is there a following CASE/PATTERN/DEFAULT? */
+						if (p2->next && p2->next->type == PV_CASE) {
+							fall_thru = new_prio();
+							fall_thru->type = AEL_APPCALL;
+							fall_thru->app = strdup("Goto");
+							snprintf(buf1,sizeof(buf1),"sw-%d-%s|1",control_statement_count, p2->next->u1.str);
+							fall_thru->appargs = strdup(buf1);
+							linkprio(switch_case, fall_thru);
+						} else if (p2->next && p2->next->type == PV_PATTERN) {
+							fall_thru = new_prio();
+							fall_thru->type = AEL_APPCALL;
+							fall_thru->app = strdup("Goto");
+							snprintf(buf1,sizeof(buf1),"_sw-%d-%s|1",control_statement_count, p2->next->u1.str);
+							fall_thru->appargs = strdup(buf1);
+							linkprio(switch_case, fall_thru);
+						} else if (p2->next && p2->next->type == PV_DEFAULT) {
+							fall_thru = new_prio();
+							fall_thru->type = AEL_APPCALL;
+							fall_thru->app = strdup("Goto");
+							snprintf(buf1,sizeof(buf1),"_sw-%d-.|1",control_statement_count);
+							fall_thru->appargs = strdup(buf1);
+							linkprio(switch_case, fall_thru);
+						} else if (!p2->next) {
+							fall_thru = new_prio();
+							fall_thru->type = AEL_CONTROL1;
+							fall_thru->goto_true = switch_end;
+							fall_thru->app = strdup("Goto");
+							linkprio(switch_case, fall_thru);
+						}
+					}
+					if (switch_case->return_needed) {
+						char buf[2000];
+						struct ael_priority *np2 = new_prio();
+						np2->type = AEL_APPCALL;
+						np2->app = strdup("NoOp");
+						snprintf(buf,sizeof(buf),"End of Extension %s", switch_case->name);
+						np2->appargs = strdup(buf);
+						linkprio(switch_case, np2);
+						switch_case-> return_target = np2;
+					}
+				} else if (p2->type == PV_PATTERN) {
+					/* ok, generate a extension and link it in */
+					switch_case = new_exten();
+					/* the break/continue locations are inherited from parent */
+					switch_case->loop_break = exten->loop_break;
+					switch_case->loop_continue = exten->loop_continue;
+					
+					linkexten(exten,switch_case);
+					snprintf(buf1,sizeof(buf1),"_sw-%d-%s", control_statement_count, p2->u1.str);
+					switch_case->name = strdup(buf1);
+					snprintf(new_label,sizeof(new_label),"sw-%s-%s-%d", label, p2->u1.str, control_statement_count);
+					
+					gen_prios(switch_case, new_label, p2->u2.statements, exten); /* this will link in all the while body statements here */
+					/* here is where we write code to "fall thru" to the next case... if there is one... */
+					for (p3=p2->u2.statements; p3; p3=p3->next) {
+						if (!p3->next)
+							break;
+					}
+					/* p3 now points the last statement... */
+					if (!p3 || ( p3->type != PV_GOTO && p3->type != PV_BREAK && p3->type != PV_RETURN)) {
+						/* is there a following CASE/PATTERN/DEFAULT? */
+						if (p2->next && p2->next->type == PV_CASE) {
+							fall_thru = new_prio();
+							fall_thru->type = AEL_APPCALL;
+							fall_thru->app = strdup("Goto");
+							snprintf(buf1,sizeof(buf1),"sw-%d-%s|1",control_statement_count, p2->next->u1.str);
+							fall_thru->appargs = strdup(buf1);
+							linkprio(switch_case, fall_thru);
+						} else if (p2->next && p2->next->type == PV_PATTERN) {
+							fall_thru = new_prio();
+							fall_thru->type = AEL_APPCALL;
+							fall_thru->app = strdup("Goto");
+							snprintf(buf1,sizeof(buf1),"_sw-%d-%s|1",control_statement_count, p2->next->u1.str);
+							fall_thru->appargs = strdup(buf1);
+							linkprio(switch_case, fall_thru);
+						} else if (p2->next && p2->next->type == PV_DEFAULT) {
+							fall_thru = new_prio();
+							fall_thru->type = AEL_APPCALL;
+							fall_thru->app = strdup("Goto");
+							snprintf(buf1,sizeof(buf1),"_sw-%d-.|1",control_statement_count);
+							fall_thru->appargs = strdup(buf1);
+							linkprio(switch_case, fall_thru);
+						} else if (!p2->next) {
+							fall_thru = new_prio();
+							fall_thru->type = AEL_CONTROL1;
+							fall_thru->goto_true = switch_end;
+							fall_thru->app = strdup("Goto");
+							linkprio(switch_case, fall_thru);
+						}
+					}
+					if (switch_case->return_needed) {
+						char buf[2000];
+						struct ael_priority *np2 = new_prio();
+						np2->type = AEL_APPCALL;
+						np2->app = strdup("NoOp");
+						snprintf(buf,sizeof(buf),"End of Extension %s", switch_case->name);
+						np2->appargs = strdup(buf);
+						linkprio(switch_case, np2);
+						switch_case-> return_target = np2;
+					}
+				} else if (p2->type == PV_DEFAULT) {
+					default_exists++;
+					/* ok, generate a extension and link it in */
+					switch_case = new_exten();
+					/* the break/continue locations are inherited from parent */
+					switch_case->loop_break = exten->loop_break;
+					switch_case->loop_continue = exten->loop_continue;
+					linkexten(exten,switch_case);
+					snprintf(buf1,sizeof(buf1),"_sw-%d-.", control_statement_count);
+					switch_case->name = strdup(buf1);
+					
+					snprintf(new_label,sizeof(new_label),"sw-%s-default-%d", label, control_statement_count);
+					
+					gen_prios(switch_case, new_label, p2->u2.statements, exten); /* this will link in all the while body statements here */
+					
+					/* here is where we write code to "fall thru" to the next case... if there is one... */
+					for (p3=p2->u2.statements; p3; p3=p3->next) {
+						if (!p3->next)
+							break;
+					}
+					/* p3 now points the last statement... */
+					if (!p3 || (p3->type != PV_GOTO && p3->type != PV_BREAK && p3->type != PV_RETURN)) {
+						/* is there a following CASE/PATTERN/DEFAULT? */
+						if (p2->next && p2->next->type == PV_CASE) {
+							fall_thru = new_prio();
+							fall_thru->type = AEL_APPCALL;
+							fall_thru->app = strdup("Goto");
+							snprintf(buf1,sizeof(buf1),"sw-%d-%s|1",control_statement_count, p2->next->u1.str);
+							fall_thru->appargs = strdup(buf1);
+							linkprio(switch_case, fall_thru);
+						} else if (p2->next && p2->next->type == PV_PATTERN) {
+							fall_thru = new_prio();
+							fall_thru->type = AEL_APPCALL;
+							fall_thru->app = strdup("Goto");
+							snprintf(buf1,sizeof(buf1),"_sw-%d-%s|1",control_statement_count, p2->next->u1.str);
+							fall_thru->appargs = strdup(buf1);
+							linkprio(switch_case, fall_thru);
+						} else if (p2->next && p2->next->type == PV_DEFAULT) {
+							fall_thru = new_prio();
+							fall_thru->type = AEL_APPCALL;
+							fall_thru->app = strdup("Goto");
+							snprintf(buf1,sizeof(buf1),"_sw-%d-.|1",control_statement_count);
+							fall_thru->appargs = strdup(buf1);
+							linkprio(switch_case, fall_thru);
+						} else if (!p2->next) {
+							fall_thru = new_prio();
+							fall_thru->type = AEL_CONTROL1;
+							fall_thru->goto_true = switch_end;
+							fall_thru->app = strdup("Goto");
+							linkprio(switch_case, fall_thru);
+						}
+					}
+					if (switch_case->return_needed) {
+						char buf[2000];
+						struct ael_priority *np2 = new_prio();
+						np2->type = AEL_APPCALL;
+						np2->app = strdup("NoOp");
+						snprintf(buf,sizeof(buf),"End of Extension %s", switch_case->name);
+						np2->appargs = strdup(buf);
+						linkprio(switch_case, np2);
+						switch_case-> return_target = np2;
+					}
+				} else {
+					/* what could it be??? */
+				}
+			}
+			
+			exten->loop_break = loop_break_save;
+			exten->loop_continue = loop_continue_save;
+			switch_test->origin = p;
+			switch_end->origin = p;
+			break;
+
+		case PV_MACRO_CALL:
+			pr = new_prio();
+			pr->type = AEL_APPCALL;
+			snprintf(buf1,sizeof(buf1),"%s", p->u1.str);
+			for (p2 = p->u2.arglist; p2; p2 = p2->next) {
+				strcat(buf1,"|");
+				strcat(buf1,p2->u1.str);
+			}
+			pr->app = strdup("Macro");
+			pr->appargs = strdup(buf1);
+			pr->origin = p;
+			linkprio(exten, pr);
+			break;
+
+		case PV_APPLICATION_CALL:
+			pr = new_prio();
+			pr->type = AEL_APPCALL;
+			buf1[0] = 0;
+			for (p2 = p->u2.arglist; p2; p2 = p2->next) {
+				if (p2 != p->u2.arglist )
+					strcat(buf1,"|");
+				strcat(buf1,p2->u1.str);
+			}
+			pr->app = strdup(p->u1.str);
+			pr->appargs = strdup(buf1);
+			pr->origin = p;
+			linkprio(exten, pr);
+			break;
+
+		case PV_BREAK:
+			pr = new_prio();
+			pr->type = AEL_CONTROL1; /* simple goto */
+			pr->goto_true = exten->loop_break;
+			pr->origin = p;
+			linkprio(exten, pr);
+			break;
+
+		case PV_RETURN: /* hmmmm */
+			pr = new_prio();
+			pr->type = AEL_RETURN; /* simple goto */
+			exten->return_needed++;
+			pr->app = strdup("Goto");
+			pr->appargs = strdup("");
+			pr->origin = p;
+			linkprio(exten, pr);
+			break;
+
+		case PV_CONTINUE:
+			pr = new_prio();
+			pr->type = AEL_CONTROL1; /* simple goto */
+			pr->goto_true = exten->loop_continue;
+			pr->origin = p;
+			linkprio(exten, pr);
+			break;
+
+#ifdef OLD_RAND_ACTION
+		case PV_RANDOM:
+			control_statement_count++;
+			snprintf(new_label,sizeof(new_label),"rand-%s-%d", label, control_statement_count);
+			rand_test = new_prio();
+			rand_test->type = AEL_RAND_CONTROL;
+			snprintf(buf1,sizeof(buf1),"$[%s]",
+					 p->u1.str );
+			rand_test->app = 0;
+			rand_test->appargs = strdup(buf1);
+			rand_test->origin = p;
+			
+			rand_end = new_prio();
+			rand_end->type = AEL_APPCALL;
+			snprintf(buf1,sizeof(buf1),"Finish rand-%s-%d", label, control_statement_count);
+			rand_end->app = strdup("NoOp");
+			rand_end->appargs = strdup(buf1);
+			
+			rand_skip = new_prio();
+			rand_skip->type = AEL_CONTROL1; /* simple goto */
+			rand_skip->goto_true = rand_end;
+			rand_skip->origin  = p;
+
+			rand_test->goto_true = rand_skip; /* +1, really */
 
-static struct stringlink *split_params(char *token, const char *filename, int lineno)
-{
-	char *params;
-	struct stringlink *paramv;
-	params = token;
-	while(*params && (*params > 32) && (*params != '(')) params++;
-	if (*params) {
-		if (*params != '(') {
-			*params = '\0';
-			params++;
-			params = ast_skip_blanks(params);
-		}
-		if (!*params)
-			params = NULL;
-	} else params = NULL;
-	paramv = param_parse(params, token, filename, lineno);
-	if (params)
-		*params = '\0';
-	return paramv;
-}
+			linkprio(exten, rand_test);
+			
+			if (p->u3.else_statements) {
+				gen_prios(exten, new_label, p->u3.else_statements, mother_exten); /* this will link in all the else statements here */
+			}
+			
+			linkprio(exten, rand_skip);
+			
+			gen_prios(exten, new_label, p->u2.statements, mother_exten); /* this will link in all the "true" statements here */
 
-static const char *get_case(char *s, char **restout, int *pattern)
-{
-	char *newcase=NULL;
-	char *rest=NULL;
-	if (!strncasecmp(s, "case", 4) && s[4] && ((s[4] < 33) || (s[4] == ':'))) {
-		newcase = s + 4;
-		newcase = ast_skip_blanks(newcase);
-		rest = newcase;
-		*pattern = 0;
-	} else if (!strncasecmp(s, "pattern", 7) && s[7] && ((s[7] < 33) || (s[7] == ':'))) {
-		newcase = s + 8;
-		newcase = ast_skip_blanks(newcase);
-		rest = newcase;
-		*pattern = 1;
-	} else if (!strncasecmp(s, "default", 7) && ((s[7] < 33) || (s[7] == ':'))) {
-		newcase = ".";
-		rest = s + 7;
-		rest = ast_skip_blanks(rest);
-		*pattern = 1;
-	}
+			linkprio(exten, rand_end);
+			
+			break;
+#endif			
 
-	if (rest) {
-		while (*rest && (*rest > 32) && (*rest != ':')) rest++;
-		if (*rest) {
-			*rest = 0;
-			rest++;
-			while (*rest && ((*rest == ':') || (*rest < 33))) rest++;
-			*restout = rest;
-		} else {
-			*restout = "";
-		}
-	} else
-		*restout = s;
-	if (aeldebug & DEBUG_TOKENS)
-		ast_verbose("GETCASE: newcase is '%s', rest = '%s'\n", newcase, *restout);
-	return newcase;
-}
+		case PV_IFTIME:
+			control_statement_count++;
+			snprintf(new_label,sizeof(new_label),"iftime-%s-%d", label, control_statement_count);
+			
+			if_test = new_prio();
+			if_test->type = AEL_IFTIME_CONTROL;
+			snprintf(buf1,sizeof(buf1),"%s|%s|%s|%s",
+					 p->u1.list->u1.str, 
+					 p->u1.list->next->u1.str, 
+					 p->u1.list->next->next->u1.str, 
+					 p->u1.list->next->next->next->u1.str);
+			if_test->app = 0;
+			if_test->appargs = strdup(buf1);
+			if_test->origin = p;
 
-static void fillin_free(struct fillin *fillin)
-{
-	struct fillin *cur, *next;
-	cur =  fillin;
-	while(cur) {
-		next = cur->next;
-		free(cur);
-		cur = next;
-	}
-}
+			if_end = new_prio();
+			if_end->type = AEL_APPCALL;
+			snprintf(buf1,sizeof(buf1),"Finish iftime-%s-%d", label, control_statement_count);
+			if_end->app = strdup("NoOp");
+			if_end->appargs = strdup(buf1);
+
+			if (p->u3.else_statements) {
+				if_skip = new_prio();
+				if_skip->type = AEL_CONTROL1; /* simple goto */
+				if_skip->goto_true = if_end;
+				if_skip->origin  = p;
 
-static void fillin_process(struct ast_context *con, struct fillin *fillin, const char *filename, int lineno, const char *breakexten, int breakprio, const char *contexten, int contprio)
-{
-	struct fillin *cur;
-	char *app;
-	char mdata[AST_MAX_EXTENSION + 20];
-	cur = fillin;
-	while(cur) {
-		if (cur->type == FILLIN_BREAK) {
-			if (breakexten && breakprio) {
-				app = "Goto";
-				snprintf(mdata, sizeof(mdata), "%s|%d", breakexten, breakprio);
 			} else {
-				app = "NoOp";
-				snprintf(mdata, sizeof(mdata), "Invalid break");
-				ast_log(LOG_NOTICE, "Ignoring inappropriate break around line %d of %s\n", lineno, filename);
+				if_skip = 0;
+
+				if_test->goto_false = if_end;
 			}
-			if (ast_add_extension2(con, 0, cur->exten, cur->priority, NULL, NULL, app, strdup(mdata), FREE, registrar))
-				ast_log(LOG_WARNING, "Unable to add step at priority '%d' of break '%s'\n", cur->priority, cur->exten);
-		} else if (cur->type == FILLIN_CONTINUE) {
-			if (contexten && contprio) {
-				app = "Goto";
-				snprintf(mdata, sizeof(mdata), "%s|%d", contexten, contprio);
+
+			if_false = new_prio();
+			if_false->type = AEL_CONTROL1;
+			if (p->u3.else_statements) {
+				if_false->goto_true = if_skip; /* +1 */
 			} else {
-				app = "NoOp";
-				snprintf(mdata, sizeof(mdata), "Invalid continue");
-				ast_log(LOG_NOTICE, "Ignoring inappropriate continue around line %d of %s\n", lineno, filename);
+				if_false->goto_true = if_end;
 			}
-			if (ast_add_extension2(con, 0, cur->exten, cur->priority, NULL, NULL, app, strdup(mdata), FREE, registrar))
-				ast_log(LOG_WARNING, "Unable to add step at priority '%d' of continue '%s'\n", cur->priority, cur->exten);
-		} else {
-			ast_log(LOG_WARNING, "Whoa, unknown fillin type '%d'\n", cur->type);
-		}
-		cur = cur->next;
-	}
-}
+			
+			/* link & load! */
+			linkprio(exten, if_test);
+			linkprio(exten, if_false);
+			
+			/* now, put the body of the if here */
+			
+			gen_prios(exten, new_label, p->u2.statements, mother_exten); /* this will link in all the statements here */
+			
+			if (p->u3.else_statements) {
+				linkprio(exten, if_skip);
+				gen_prios(exten, new_label, p->u3.else_statements, mother_exten); /* this will link in all the statements here */
 
-static int match_assignment(char *variable, char **value)
-{
-	char *c;
-	char *ws;
-	int inpar = 0;
-	c = variable;
-	
-	while (*c) {
-		if(*c == ')' && (inpar > 0)) {
-			inpar--;
-		} else if(*c == '(' && (inpar >= 0)) {
-			inpar++;
-		} else if(*c == '=' && (inpar == 0)) {
+			}
+			
+			linkprio(exten, if_end);
+			
 			break;
-		}
-		c++;
-	} 
-	ws = c;
-	c = ast_skip_blanks(c);
-	if (*c == '=') {
-		*ws = '\0';
-		*c = '\0';
-		c++;
-		c = ast_skip_blanks(c);
-		*value = c;
-		return 1;
-	}
-	return 0;
-}
 
-static int matches_label(char *data, char **rest)
-{
-	char last = 0;
-	char *start = data;
-	while (*data > 32) {
-		last = *data;
-		data++;
-	}
-	if (last != ':') {
-		data = ast_skip_blanks(data);
-		last = *data;
-		data++;
-	}
-	if (last == ':') {
-		*rest = data;
-		/* Go back and trim up the label */
-		while(*start && ((*start > 32) && (*start != ':'))) start++;
-		*start = '\0';
-		return 1;
-	}
-	return 0;
-}
+		case PV_RANDOM:
+		case PV_IF:
+			control_statement_count++;
+			snprintf(new_label,sizeof(new_label),"if-%s-%d", label, control_statement_count);
+			
+			if_test = new_prio();
+			if_end = new_prio();
+			if_test->type = AEL_IF_CONTROL;
+			if_end->type = AEL_APPCALL;
+			if ( p->type == PV_RANDOM )
+				snprintf(buf1,sizeof(buf1),"$[${RAND(0,99)} < (%s)]",p->u1.str);
+			else
+				snprintf(buf1,sizeof(buf1),"$[%s]",p->u1.str);
+			if_test->app = 0;
+			if_test->appargs = strdup(buf1);
+			snprintf(buf1,sizeof(buf1),"Finish if-%s-%d", label, control_statement_count);
+			if_end->app = strdup("NoOp");
+			if_end->appargs = strdup(buf1);
+			if_test->origin = p;
+			
+			if (p->u3.else_statements) {
+				if_skip = new_prio();
+				if_skip->type = AEL_CONTROL1; /* simple goto */
+				if_skip->goto_true = if_end;
+				if_test->goto_false = if_skip;;
+			} else {
+				if_skip = 0;
+				if_test->goto_false = if_end;;
+			}
+			
+			/* link & load! */
+			linkprio(exten, if_test);
+			
+			/* now, put the body of the if here */
+			
+			gen_prios(exten, new_label, p->u2.statements, mother_exten); /* this will link in all the statements here */
+			
+			if (p->u3.else_statements) {
+				linkprio(exten, if_skip);
+				gen_prios(exten, new_label, p->u3.else_statements, mother_exten); /* this will link in all the statements here */
 
-static char *argument_end(char *str)
-{
-	int level=0;
-	while(*++str) {
-		switch(*str) {
-		case '(':
-			level++;
+			}
+			
+			linkprio(exten, if_end);
+			
 			break;
-		case ')':
-			if(level)
-				level--;
-			else
-				return str;
+
+		case PV_STATEMENTBLOCK:
+			gen_prios(exten, label, p->u1.list, mother_exten ); /* recurse into the block */
+			break;
+
+		case PV_CATCH:
+			control_statement_count++;
+			/* generate an extension with name of catch, put all catch stats
+			   into this exten! */
+			switch_case = new_exten();
+			linkexten(exten,switch_case);
+			switch_case->name = strdup(p->u1.str);
+			snprintf(new_label,sizeof(new_label),"catch-%s-%d",p->u1.str, control_statement_count);
+			
+			gen_prios(switch_case, new_label, p->u2.statements,mother_exten); /* this will link in all the catch body statements here */
+			if (switch_case->return_needed) {
+				char buf[2000];
+				struct ael_priority *np2 = new_prio();
+				np2->type = AEL_APPCALL;
+				np2->app = strdup("NoOp");
+				snprintf(buf,sizeof(buf),"End of Extension %s", switch_case->name);
+				np2->appargs = strdup(buf);
+				linkprio(switch_case, np2);
+				switch_case-> return_target = np2;
+			}
+
 			break;
 		default:
 			break;
 		}
 	}
-	return NULL;
 }
 
-static int build_step(const char *what, const char *name, const char *filename, int lineno, struct ast_context *con, char *exten, int *pos, char *data, struct fillin **fillout, char **label);
-static int __build_step(const char *what, const char *name, const char *filename, int lineno, struct ast_context *con, char *exten, int *pos, char *data, struct fillin **fillout, char **label)
+void set_priorities(struct ael_extension *exten)
 {
-	char *app;
-	char *args;
-	char *c;
-	char *margs=NULL;
-	char *oargs;
-	char *rest;
-	const char *curcase, *newcase;
-	struct stringlink *swargs, *cur;
-	int cpos;
-	int mlen;
-	int pattern = 0;
-	struct fillin *fillin;
-	
-	data = ast_skip_blanks(data);
-	if (matches_label(data, &c)) {
-		*label = data;
-		data = c;
-		data = ast_skip_blanks(data);
-	}
-	if (ast_strlen_zero(data))
-		return 0;
-	if (matches_keyword(data, "switch")) {
-		fillin = NULL;
-		/* Switch */
-		args = data + strlen("switch");
-		while ((*args < 33) && (*args != '(')) args++;
-		if ((*args == '(') && (c = argument_end(args))) {
-			args++;
-			*c = '\0';
-			c++;
-			if (aeldebug & DEBUG_TOKENS)
-				ast_verbose("--SWITCH on : %s\n", args);
-			mlen = strlen(exten) + 128 + strlen(args) + strlen(name);
-			margs = alloca(mlen);
-			app = "Goto";
-			sprintf(margs, "sw-%d-%s|1", *pos, args);
-			ast_process_quotes_and_slashes(margs, ',', '|');
-			oargs = args;
-			args = margs;
-			if (ast_add_extension2(con, 0, exten, *pos, *label, NULL, app, strdup(args), FREE, registrar))
-				ast_log(LOG_WARNING, "Unable to add step at priority '%d' of %s '%s'\n", *pos, what, name);
-			else {
-				*label = NULL;
-				(*pos)++;
-			}
-			app = "NoOp";
-			sprintf(margs, "Finish switch-%d", *pos - 1);
-			if (ast_add_extension2(con, 0, exten, *pos, *label, NULL, app, strdup(args), FREE, registrar))
-				ast_log(LOG_WARNING, "Unable to add step at priority '%d' of %s '%s'\n", *pos, what, name);
-			else {
-				*label = NULL;
-				(*pos)++;
-			}
-			c = ast_skip_blanks(c);
-			if (aeldebug & DEBUG_TOKENS)
-				ast_verbose("ARG Parsing '%s'\n", c);
-			swargs = arg_parse(c, filename, lineno);
-			cur = swargs;
-			curcase = NULL;
-			while(cur) {
-				if ((newcase = get_case(cur->data, &rest, &pattern))) {
-					if (aeldebug & DEBUG_TOKENS)
-						ast_verbose("--NEWCASE: '%s'!\n", newcase);
-					if (curcase) {
-						/* Handle fall through */
-						char tmp[strlen(newcase) + strlen(name) + 40];
-						sprintf(tmp, "sw-%d-%s|%d", *pos - 2, newcase, 1);
-						ast_add_extension2(con, 0, margs, cpos, NULL, NULL, "Goto", strdup(tmp), FREE, registrar);
-					}
-					curcase = newcase;
-					cpos = 1;
-					if (pattern)
-						snprintf(margs, mlen, "_sw-%d-%s", *pos - 2, curcase);
-					else
-						snprintf(margs, mlen, "sw-%d-%s", *pos - 2, curcase);
-					if (!strcasecmp(rest, "break")) {
-						char tmp[strlen(exten) + 10];
-						sprintf(tmp, "%s|%d", exten, *pos - 1);
-						ast_add_extension2(con, 0, exten, cpos, *label, NULL, "Goto", strdup(tmp), FREE, registrar);
-						curcase = NULL;
-						*label = NULL;
-					} else
-						build_step("switch", margs, filename, lineno, con, margs, &cpos, rest, &fillin, label);
-				} else if (curcase) {
-					if (aeldebug & DEBUG_TOKENS)
-						ast_verbose("Building statement from '%s'\n", rest);
-					if (!strcasecmp(rest, "break")) {
-						char tmp[strlen(exten) + 10];
-						sprintf(tmp, "%s|%d", exten, *pos - 1);
-						ast_add_extension2(con, 0, margs, cpos, *label, NULL, "Goto", strdup(tmp), FREE, registrar);
-						curcase = NULL;
-						*label = NULL;
-					} else
-						build_step("switch", margs, filename, lineno, con, margs, &cpos, rest, &fillin, label);
-				} else 
-					ast_log(LOG_WARNING, "Unreachable code in switch at about line %d of %s\n", lineno, filename);
-				if (aeldebug & DEBUG_TOKENS)
-					ast_verbose("--SWARG: %s\n", cur->data);
-				cur = cur->next;
-			}
-			/* Can't do anything with these */
-			fillin_process(con, fillin, filename, lineno, NULL, 0, NULL, 0);
-			fillin_free(fillin);
-			arg_free(swargs);
-		} else
-			ast_log(LOG_WARNING, "Syntax error in switch declaration in %s around line %d!\n", filename, lineno); 
-			
-	} else if (matches_keyword(data, "if")) {
-		/* If... */
-		args = data + strlen("if");
-		while ((*args < 33) && (*args != '(')) args++;
-		if ((*args == '(') && (c = argument_end(args))) {
-			int ifblock;
-			int ifstart;
-			int elsestart;
-			int ifend;
-			int ifskip;
-			char *elses;
-			char *iflabel;
-			args++;
-			*c = '\0';
-			c++;
-			c = ast_skip_blanks(c);
-			if (aeldebug & DEBUG_TOKENS)
-				ast_verbose("--IF on : '%s' : '%s'\n", args, c);
-			mlen = strlen(exten) + 128 + strlen(args) + strlen(name);
-			margs = alloca(mlen);
-			/* Remember where the ifblock starts, and skip over */
-			ifblock = (*pos)++;
-			iflabel = *label;
-			*label = NULL;
-			/* Remember where the start of the ifblock is */
-			ifstart = *pos;
-			snprintf(margs, mlen, "if-%s-%d", name, ifblock);
-			/* Now process the block of the if */
-			if (aeldebug & DEBUG_TOKENS)
-				ast_verbose("Searching for elses in '%s'\n", c);
-			elses = grab_else(c, filename, lineno);
-			build_step("if", margs, filename, lineno, con, exten, pos, c, fillout, label);
-			if (elses) {
-				/* Reserve a goto to exit the if */
-				ifskip = *pos;
-				(*pos)++;
-				elsestart = *pos;
-				build_step("else", margs, filename, lineno, con, exten, pos, elses, fillout, label);
-			} else {
-				elsestart = *pos;
-				ifskip = 0;
-			}
-			ifend = *pos;
-			(*pos)++;
-			app = "NoOp";
-			snprintf(margs, mlen, "Finish if-%s-%d", name, ifblock);
-			if (ast_add_extension2(con, 0, exten, ifend, *label, NULL, app, strdup(margs), FREE, registrar))
-				ast_log(LOG_WARNING, "Unable to add step at priority '%d' of %s '%s'\n", *pos, what, name);
-			*label = NULL;
-			app = "GotoIf";
-			snprintf(margs, mlen, "$[ %s ]?%d:%d", args, ifstart, elsestart);
-			if (ast_add_extension2(con, 0, exten, ifblock, iflabel, NULL, app, strdup(margs), FREE, registrar))
-				ast_log(LOG_WARNING, "Unable to add step at priority '%d' of %s '%s'\n", *pos, what, name);
-			if (ifskip) {
-				/* Skip as appropriate around else clause */
-				snprintf(margs, mlen, "%d", ifend);
-				if (ast_add_extension2(con, 0, exten, ifskip, NULL, NULL, "Goto", strdup(margs), FREE, registrar))
-					ast_log(LOG_WARNING, "Unable to add step at priority '%d' of %s '%s'\n", *pos, what, name);
-			}
-		} else
-			ast_log(LOG_WARNING, "Syntax error in if declaration in %s around line %d!\n", filename, lineno); 
-	} else if (matches_keyword(data, "while")) {
-		/* While... */
-		fillin = NULL;
-		args = data + strlen("while");
-		while ((*args < 33) && (*args != '(')) args++;
-		if ((*args == '(') && (c = argument_end(args))) {
-			int whileblock;
-			int whilestart;
-			int whileend;
-			char *whilelabel;
-			args++;
-			*c = '\0';
-			c++;
-			c = ast_skip_blanks(c);
-			if (aeldebug & DEBUG_TOKENS)
-				ast_verbose("--WHILE on : '%s' : '%s'\n", args, c);
-			mlen = strlen(exten) + 128 + strlen(args) + strlen(name);
-			margs = alloca(mlen);
-			/* Remember where to put the conditional, and keep its position */
-			whilestart = (*pos);
-			whilelabel = *label;
-			*label = NULL;
-			(*pos)++;
-			/* Remember where the whileblock starts */
-			whileblock = (*pos);
-			snprintf(margs, mlen, "while-%s-%d", name, whilestart);
-			build_step("while", margs, filename, lineno, con, exten, pos, c, &fillin, label);
-			/* Close the loop */
-			app = "Goto";
-			snprintf(margs, mlen, "%d", whilestart);
-			if (ast_add_extension2(con, 0, exten, (*pos)++, *label, NULL, app, strdup(margs), FREE, registrar))
-				ast_log(LOG_WARNING, "Unable to add step at priority '%d' of %s '%s'\n", *pos, what, name);
-			*label = NULL;
-			whileend = (*pos);
-			/* Place trailer */
-			app = "NoOp";
-			snprintf(margs, mlen, "Finish while-%s-%d", name, whilestart);
-			if (ast_add_extension2(con, 0, exten, (*pos)++, *label, NULL, app, strdup(margs), FREE, registrar))
-				ast_log(LOG_WARNING, "Unable to add step at priority '%d' of %s '%s'\n", *pos, what, name);
-			*label = NULL;
-			app = "GotoIf";
-			snprintf(margs, mlen, "$[ %s ]?%d:%d", args, whileblock, whileend);
-			if (ast_add_extension2(con, 0, exten, whilestart, whilelabel, NULL, app, strdup(margs), FREE, registrar))
-				ast_log(LOG_WARNING, "Unable to add step at priority '%d' of %s '%s'\n", *pos, what, name);
-			fillin_process(con, fillin, filename, lineno, exten, whileend, exten, whilestart);
-			fillin_free(fillin);
-		} else
-			ast_log(LOG_WARNING, "Syntax error in while declaration in %s around line %d!\n", filename, lineno); 
-	} else if (matches_keyword(data, "jump")) {
-		char *p;
-		/* Jump... */
-		fillin = NULL;
-		args = data + strlen("jump");
-		args = ast_skip_blanks(args);
-		if (aeldebug & DEBUG_TOKENS)
-			ast_verbose("--JUMP to : '%s'\n", args);
-		p = strchr(args, ',');
-		if (p) {
-			*p = '\0';
-			p++;
-		} else
-			p = "1";
-		c = strchr(args, '@');
-		if (c) {
-			*c = '\0';
-			c++;
-		}
-		mlen = strlen(exten) + 128 + strlen(args) + strlen(name) + (c ? strlen(c) : 0);
-		margs = alloca(mlen);
-		if (c) 
-			snprintf(margs, mlen, "%s|%s|%s", c,args, p);
+	int i;
+	struct ael_priority *pr;
+	do {
+		if (exten->regexten)
+			i=2;
 		else
-			snprintf(margs, mlen, "%s|%s", args, p);
-		app = "Goto";
-		if (ast_add_extension2(con, 0, exten, (*pos)++, *label, NULL, app, strdup(margs), FREE, registrar))
-			ast_log(LOG_WARNING, "Unable to add step at priority '%d' of %s '%s'\n", *pos, what, name);
-		*label = NULL;
-	} else if (matches_keyword(data, "goto")) {
-		/* Jump... */
-		fillin = NULL;
-		args = data + strlen("goto");
-		args = ast_skip_blanks(args);
-		if (aeldebug & DEBUG_TOKENS)
-			ast_verbose("--GOTO to : '%s'\n", args);
-		app = "Goto";
-		if (args[0] == '(' && args[strlen(args) - 1] == ')') {
-			args[0] = '\0';
-			args++;
-			args[strlen(args) - 1] = '\0';
-		}
-		if (ast_add_extension2(con, 0, exten, (*pos)++, *label, NULL, app, strdup(args), FREE, registrar))
-			ast_log(LOG_WARNING, "Unable to add step at priority '%d' of %s '%s'\n", *pos, what, name);
-		*label = NULL;
-	} else if (matches_keyword(data, "for")) {
-		/* While... */
-		fillin = NULL;
-		args = data + strlen("for");
-		while ((*args < 33) && (*args != '(')) args++;
-		if ((*args == '(') && (c = argument_end(args))) {
-			int forblock;
-			int forprep;
-			int forstart;
-			int forend;
-			struct stringlink *fields;
-			char *tmp;
-			char *forlabel = NULL;
-			args++;
-			*c = '\0';
-			c++;
-			c = ast_skip_blanks(c);
-			/* Parse arguments first */
-			tmp = alloca(strlen(args) + 10);
-			if (tmp) {
-				snprintf(tmp, strlen(args) + 10, "{%s;}", args);
-				fields = arg_parse(tmp, filename, lineno);
-			} else
-				fields = NULL;
-			if (fields && fields->next && fields->next->next) {
-				if (aeldebug & DEBUG_TOKENS)
-					ast_verbose("--FOR ('%s' ; '%s' ; '%s') : '%s'\n", fields->data, fields->next->data, fields->next->next->data, c);
-				mlen = strlen(exten) + 128 + strlen(args) + strlen(name);
-				margs = alloca(mlen);
-				forprep = *pos;
-				snprintf(margs, mlen, "for-%s-%d", name, forprep);
-				fillin = NULL;
-				build_step("while", margs, filename, lineno, con, exten, pos, fields->data, &fillin, label);
-				/* Remember where to put the conditional, and keep its position */
-				forstart = (*pos);
-				forlabel = *label;
-				(*pos)++;
-				*label = NULL;
-				/* Remember where the whileblock starts */
-				forblock = (*pos);
-				build_step("for", margs, filename, lineno, con, exten, pos, c, &fillin, label);
-				build_step("for", margs, filename, lineno, con, exten, pos, fields->next->next->data, &fillin, label);
-				/* Close the loop */
-				app = "Goto";
-				snprintf(margs, mlen, "%d", forstart);
-				if (ast_add_extension2(con, 0, exten, (*pos)++, *label, NULL, app, strdup(margs), FREE, registrar))
-					ast_log(LOG_WARNING, "Unable to add step at priority '%d' of %s '%s'\n", *pos, what, name);
-				*label = NULL;
-				forend = (*pos);
-				/* Place trailer */
-				app = "NoOp";
-				snprintf(margs, mlen, "Finish for-%s-%d", name, forprep);
-				if (ast_add_extension2(con, 0, exten, (*pos)++, *label, NULL, app, strdup(margs), FREE, registrar))
-					ast_log(LOG_WARNING, "Unable to add step at priority '%d' of %s '%s'\n", *pos, what, name);
-				*label = NULL;
-				app = "GotoIf";
-				snprintf(margs, mlen, "$[ %s ]?%d:%d", fields->next->data, forblock, forend);
-				if (ast_add_extension2(con, 0, exten, forstart, forlabel, NULL, app, strdup(margs), FREE, registrar))
-					ast_log(LOG_WARNING, "Unable to add step at priority '%d' of %s '%s'\n", forstart, what, name);
-				fillin_process(con, fillin, filename, lineno, exten, forend, exten, forstart);
-				fillin_free(fillin);
-			} else
-				ast_log(LOG_NOTICE, "Improper for declaration in %s around line %d!\n", filename, lineno); 
-			arg_free(fields);
-		} else
-			ast_log(LOG_WARNING, "Syntax error in for declaration in %s around line %d!\n", filename, lineno); 
-			
-	} else if (!strcasecmp(data, "break") || !strcasecmp(data, "continue")) {
-		struct fillin *fi;
-		fi = malloc(sizeof(struct fillin));
-		if (fi) {
-			memset(fi, 0, sizeof(struct fillin));
-			if (!strcasecmp(data, "break"))
-				fi->type = FILLIN_BREAK;
-			else
-				fi->type = FILLIN_CONTINUE;
-			ast_copy_string(fi->exten, exten, sizeof(fi->exten));
-			fi->priority = (*pos)++;
-			fi->next = *fillout;
-			*fillout = fi;
-		}
-	} else if (match_assignment(data, &rest)) {
-		if (aeldebug & DEBUG_TOKENS)
-			ast_verbose("ASSIGN  '%s' = '%s'\n", data, rest);
-		mlen = strlen(rest) + strlen(data) + 20;
-		margs = alloca(mlen);
-		snprintf(margs, mlen, "%s=$[ %s ]", data, rest);
-		app = "Set";
-		if (ast_add_extension2(con, 0, exten, *pos, *label, NULL, app, strdup(margs), FREE, registrar))
-			ast_log(LOG_WARNING, "Unable to add assignment at priority '%d' of %s '%s'\n", *pos, what, name);
-		else {
-			*label = NULL;
-			(*pos)++;
-		}
-	} else {
-		app = data;
-		args = app;
-		while (*args && (*args > 32) && (*args != '(')) args++;
-			if (*args != '(') {
-			while(*args && (*args != '(')) { *args = '\0'; args++; };
-		}
-		if (*args == '(') {
-			*args = '\0';
-			args++;
-			/* Got arguments, trim trailing ')' */
-			c = args + strlen(args) - 1;
-			while((c >= args) && (*c < 33) && (*c != ')')) { *c = '\0'; c--; };
-			if ((c >= args) && (*c == ')')) *c = '\0';
-		} else
-			args = "";
-		ast_process_quotes_and_slashes(args, ',', '|');
-		if (app[0] == '&') {
-			app++;
-			margs = alloca(strlen(args) + strlen(app) + 10);
-			sprintf(margs, "%s|%s", app, args);
-			args = margs;
-			app = "Macro";
-		}
-		if (aeldebug & DEBUG_TOKENS)
-			ast_verbose("-- APP: '%s', ARGS: '%s'\n", app, args);
-		if (ast_add_extension2(con, 0, exten, *pos, *label, NULL, app, strdup(args), FREE, registrar))
-			ast_log(LOG_WARNING, "Unable to add step at priority '%d' of %s '%s'\n", *pos, what, name);
-		else {
-			(*pos)++;
-			*label = NULL;
+			i=1;
+		
+		for (pr=exten->plist; pr; pr=pr->next) {
+			pr->priority_num = i;
+			
+			if (!pr->origin || (pr->origin && pr->origin->type != PV_LABEL) ) /* Labels don't show up in the dialplan,
+												  but we want them to point to the right
+												  priority, which would be the next line
+												  after the label; */
+				i++;
 		}
-	}
-	return 0;
-}
-
-static int build_step(const char *what, const char *name, const char *filename, int lineno, struct ast_context *con, char *exten, int *pos, char *data, struct fillin **fillout, char **label)
-{
-	struct stringlink *args, *cur;
-	int res=0;
-	struct fillin *fillin=NULL;
-	int dropfill = 0;
-	char *labelin = NULL;
-	if (!fillout) {
-		fillout = &fillin;
-		dropfill = 1;
-	}
-	if (!label) {
-		label = &labelin;
-	};
-	args = arg_parse(data, filename, lineno);
-	cur = args;
-	while(cur) {
-		res |= __build_step(what, name, filename, lineno, con, exten, pos, cur->data, fillout, label);
-		cur = cur->next;
-	}
-	arg_free(args);
-	if (dropfill) {
-		fillin_process(con, fillin, filename, lineno, NULL, 0, NULL, 0);
-		fillin_free(fillin);
-	}
-	return res;
+		
+		exten = exten->next_exten;
+	} while ( exten );
 }
 
-static int parse_catch(char *data, char **catch, char **rest)
+void add_extensions(struct ael_extension *exten, struct ast_context *context)
 {
-	/* Skip the word 'catch' */
-	data += 5;
-	data = ast_skip_blanks(data);
-	/* Here's the extension */
-	*catch = data;
-	if (!*data)
-		return 0;
-	while (*data && (*data > 32)) data++;
-	if (!*data)
-		return 0;
-	/* Trim any trailing spaces */
-	*data = '\0';
-	data++;
-	data = ast_skip_blanks(data);
-	if (!*data)
-		return 0;
-	*rest = data;
-	return 1;
-}
+	struct ael_priority *pr;
+	char *label=0;
+	do {
+		struct ael_priority *last = 0;
+		
+		if (exten->hints) {
+			if (ast_add_extension2(context, 0 /*no replace*/, exten->name, PRIORITY_HINT, NULL, NULL, 
+								  exten->hints, NULL, FREE, registrar)) {
+				ast_log(LOG_WARNING, "Unable to add step at priority 'hint' of extension '%s'\n",
+						exten->name);
+			}
+			
+		}
+		
+		for (pr=exten->plist; pr; pr=pr->next) {
+			char app[2000];
+			char appargs[2000];
 
-static void handle_macro(struct ast_context **local_contexts, struct stringlink *vars, const char *filename, int lineno)
-{
-	struct stringlink *argv;
-	struct stringlink *paramv;
-	struct stringlink *cur;
-	struct ast_context *con;
-	struct fillin *fillin;
-	char *catch, *rest;
-	char name[256];
-	int pos;
-	int cpos;
-
-	if (aeldebug & DEBUG_MACROS)
-		ast_verbose("Root macro def is '%s'\n", vars->data);
-	argv = split_token(vars->data, filename, lineno);
-	paramv = split_params(vars->data, filename, lineno);
-	if (aeldebug & DEBUG_MACROS) 
-		ast_verbose("Found macro '%s'\n", vars->data);
-	snprintf(name, sizeof(name), "macro-%s", vars->data);
-	con = ast_context_create(local_contexts, name, registrar);
-	if (con) {
-		pos = 1;
-		cur = paramv;
-		while(cur) {
-			if (aeldebug & DEBUG_MACROS)
-				ast_verbose("  PARAM => '%s'\n", cur->data);
-			snprintf(name, sizeof(name), "%s=${ARG%d}", cur->data, pos);
-			if (ast_add_extension2(con, 0, "s", pos, NULL, NULL, "Set", strdup(name), FREE, registrar))
-				ast_log(LOG_WARNING, "Unable to add step at priority '%d' of macro '%s'\n", pos, vars->data);
+			/* before we can add the extension, we need to prep the app/appargs;
+			   the CONTROL types need to be done after the priority numbers are calculated.
+			*/
+			if (pr->type == AEL_LABEL) /* don't try to put labels in the dialplan! */ {
+				last = pr;
+				continue;
+			}
+			
+			if (pr->app)
+				strcpy(app, pr->app);
 			else
-				pos++;
-			cur = cur->next;
-		}
-		cur = argv;
-		while(cur) {
-			if (aeldebug & DEBUG_MACROS)
-				ast_verbose("  STEP => '%s'\n", cur->data);
-			if (matches_keyword(cur->data, "catch")) {
-				if (aeldebug & DEBUG_MACROS)
-					ast_verbose("--CATCH: '%s'\n", cur->data);
-				if (parse_catch(cur->data, &catch, &rest)) {
-					cpos = 1;
-					build_step("catch", catch, filename, lineno, con, catch, &cpos, rest, NULL, NULL);
+				app[0] = 0;
+			if (pr->appargs )
+				strcpy(appargs, pr->appargs);
+			else
+				appargs[0] = 0;
+			switch( pr->type ) {
+			case AEL_APPCALL:
+				/* easy case. Everything is all set up */
+				break;
+				
+			case AEL_CONTROL1: /* FOR loop, WHILE loop, BREAK, CONTINUE, IF, IFTIME */
+				/* simple, unconditional goto. */
+				strcpy(app,"Goto");
+				if (pr->goto_true->origin && pr->goto_true->origin->type == PV_SWITCH ) {
+					snprintf(appargs,sizeof(appargs),"%s|%d", pr->goto_true->exten->name, pr->goto_true->priority_num);
+				} else if (pr->goto_true->origin && pr->goto_true->origin->type == PV_IFTIME && pr->goto_true->origin->u3.else_statements ) {
+					snprintf(appargs,sizeof(appargs),"%d", pr->goto_true->priority_num+1);
 				} else
-					ast_log(LOG_NOTICE, "Parse error for catch at about line %d of %s\n", lineno, filename);
-			} else {
-				fillin = NULL;
-				build_step("macro", vars->data, filename, lineno, con, "s", &pos, cur->data, NULL, NULL);
+					snprintf(appargs,sizeof(appargs),"%d", pr->goto_true->priority_num);
+				break;
+				
+			case AEL_FOR_CONTROL:  /* WHILE loop test, FOR loop test */
+				strcpy(app,"GotoIf");
+				snprintf(appargs,sizeof(appargs),"%s?%d:%d", pr->appargs, pr->priority_num+1, pr->goto_false->priority_num);
+				break;
+				
+			case AEL_IF_CONTROL:
+				strcpy(app,"GotoIf");
+				if (pr->origin->u3.else_statements )
+					snprintf(appargs,sizeof(appargs),"%s?%d:%d", pr->appargs, pr->priority_num+1, pr->goto_false->priority_num+1);
+				else
+					snprintf(appargs,sizeof(appargs),"%s?%d:%d", pr->appargs, pr->priority_num+1, pr->goto_false->priority_num);
+				break;
+
+			case AEL_RAND_CONTROL:
+				strcpy(app,"Random");
+				snprintf(appargs,sizeof(appargs),"%s:%d", pr->appargs, pr->goto_true->priority_num+1);
+				break;
+
+			case AEL_IFTIME_CONTROL:
+				strcpy(app,"GotoIfTime");
+				snprintf(appargs,sizeof(appargs),"%s?%d", pr->appargs, pr->priority_num+2);
+				break;
+
+			case AEL_RETURN:
+				strcpy(app,"Goto");
+				snprintf(appargs,sizeof(appargs), "%d", exten->return_target->priority_num);
+				break;
+				
+			default:
+				break;
 			}
-			cur = cur->next;
+			if (last && last->type == AEL_LABEL ) {
+				label = last->origin->u1.str;
+			}
+			else
+				label = 0;
+			
+			
+			if (ast_add_extension2(context, 0 /*no replace*/, exten->name, pr->priority_num, (label?label:NULL), NULL, 
+								  app, strdup(appargs), FREE, registrar)) {
+				ast_log(LOG_WARNING, "Unable to add step at priority '%d' of extension '%s'\n", pr->priority_num, 
+						exten->name);
+			}
+			last = pr;
 		}
-	} else
-		ast_log(LOG_WARNING, "Unable to create context '%s'\n", name);
-	arg_free(paramv);
-	arg_free(argv);
-	if (vars->next)
-		ast_log(LOG_NOTICE, "Ignoring excess tokens in macro definition around line %d of %s!\n", lineno, filename);
+		exten = exten->next_exten;
+	} while ( exten );
 }
 
-static int matches_extension(char *exten, char **extout)
+
+void ast_compile_ael2(struct ast_context **local_contexts, struct pval *root)
 {
-	char *c;
-	*extout = NULL;
-	c = exten;
-	while(*c && (*c > 32)) c++;
-	if (*c) {
-		*c = '\0';
-		c++;
-		c = ast_skip_blanks(c);
-		if (*c) {
-			if (*c == '=') {
-				*c = '\0';
-				c++;
-				if (*c == '>')
-					c++;
-				c = ast_skip_blanks(c);
-				*extout = c;
-				return 1;
+	pval *p,*p2;
+	struct ast_context *context;
+	char buf[2000];
+	struct ael_extension *exten;
+	
+	for (p=root; p; p=p->next ) {
+		pval *lp;
+		int argc;
+		
+		switch (p->type) {
+		case PV_MACRO:
+			strcpy(buf,"macro-");
+			strcat(buf,p->u1.str);
+			context = ast_context_create(local_contexts, buf, registrar);
+			
+			exten = new_exten();
+			exten->name = strdup("s");
+			argc = 1;
+			for (lp=p->u2.arglist; lp; lp=lp->next) {
+				/* for each arg, set up a "Set" command */
+				struct ael_priority *np2 = new_prio();
+				np2->type = AEL_APPCALL;
+				np2->app = strdup("Set");
+				snprintf(buf,sizeof(buf),"%s=${ARG%d}", lp->u1.str, argc++);
+				np2->appargs = strdup(buf);
+				linkprio(exten, np2);
 			}
-		}
-	}
-	return 0;
-}
+			
+			/* CONTAINS APPCALLS, CATCH, just like extensions... */
+			gen_prios(exten, p->u1.str, p->u3.macro_statements, 0 );
+			if (exten->return_needed) {
+				struct ael_priority *np2 = new_prio();
+				np2->type = AEL_APPCALL;
+				np2->app = strdup("NoOp");
+				snprintf(buf,sizeof(buf),"End of Macro %s-%s",p->u1.str, exten->name);
+				np2->appargs = strdup(buf);
+				linkprio(exten, np2);
+				exten-> return_target = np2;
+			}
+			
+			set_priorities(exten);
+			add_extensions(exten, context);
+			destroy_extensions(exten);
+			break;
+			
+		case PV_GLOBALS:
+			/* just VARDEC elements */
+			for (p2=p->u1.list; p2; p2=p2->next) {
+				char buf2[2000];
+				snprintf(buf2,sizeof(buf2),"%s=%s", p2->u1.str, p2->u2.val);
+				pbx_builtin_setvar(NULL, buf2);
+			}
+			break;
+			
+		case PV_CONTEXT:
+			context = ast_context_create(local_contexts, p->u1.str, registrar);
 
-static void parse_keyword(char *s, char **o)
-{
-	char *c;
-	c = s;
-	while((*c) && (*c > 32)) c++;
-	if (*c) {
-		*c = '\0';
-		c++;
-		c = ast_skip_blanks(c);
-		*o = c;
-	} else
-		*o = NULL;
-}
+			/* contexts contain: ignorepat, includes, switches, eswitches, extensions,  */
+			for (p2=p->u2.statements; p2; p2=p2->next) {
+				pval *p3;
+				
+				switch (p2->type) {
+				case PV_EXTENSION:
+					exten = new_exten();
+					exten->name = strdup(p2->u1.str);
+					if ( p2->u3.hints )
+						exten->hints = strdup(p2->u3.hints);
+					exten->regexten = p2->u4.regexten;
+					gen_prios(exten, p->u1.str, p2->u2.statements, 0 );
+					if (exten->return_needed) {
+						struct ael_priority *np2 = new_prio();
+						np2->type = AEL_APPCALL;
+						np2->app = strdup("NoOp");
+						snprintf(buf,sizeof(buf),"End of Extension %s", exten->name);
+						np2->appargs = strdup(buf);
+						linkprio(exten, np2);
+						exten-> return_target = np2;
+					}
+					/* is the last priority in the extension a label? Then add a trailing no-op */
+					if ( exten->plist_last->type == AEL_LABEL ) {
+						struct ael_priority *np2 = new_prio();
+						np2->type = AEL_APPCALL;
+						np2->app = strdup("NoOp");
+						snprintf(buf,sizeof(buf),"A NoOp to follow a trailing label %s", exten->plist_last->origin->u1.str);
+						np2->appargs = strdup(buf);
+						linkprio(exten, np2);
+					}
 
-static void handle_context(struct ast_context **local_contexts, struct stringlink *vars, const char *filename, int lineno)
-{
-	struct stringlink *argv;
-	struct stringlink *cur2;
-	struct stringlink *argv2;
-	struct stringlink *cur;
-	struct ast_context *con;
-	char *rest;
-	char *c;
-	char name[256];
-	int pos;
-
-	if (aeldebug & DEBUG_CONTEXTS)
-		ast_verbose("Root context def is '%s'\n", vars->data);
-	argv = split_token(vars->data, filename, lineno);
-	if (aeldebug & DEBUG_CONTEXTS) 
-		ast_verbose("Found context '%s'\n", vars->data);
-	snprintf(name, sizeof(name), "%s", vars->data);
-	con = ast_context_create(local_contexts, name, registrar);
-	if (con) {
-		cur = argv;
-		while(cur) {
-			if (matches_keyword(cur->data, "includes")) {
-				if (aeldebug & DEBUG_CONTEXTS)
-					ast_verbose("--INCLUDES: '%s'\n", cur->data);
-				parse_keyword(cur->data, &rest);
-				if (rest) {
-					argv2 = arg_parse(rest, filename, lineno);
-					cur2 = argv2;
-					while(cur2) {
-						ast_context_add_include2(con, cur2->data, registrar);
-						cur2 = cur2->next;
+					set_priorities(exten);
+					add_extensions(exten, context);
+					destroy_extensions(exten);
+					break;
+					
+				case PV_IGNOREPAT:
+					ast_context_add_ignorepat2(context, p2->u1.str, registrar);
+					break;
+					
+				case PV_INCLUDES:
+					for (p3 = p2->u1.list; p3 ;p3=p3->next) {
+						if ( p3->u2.arglist ) {
+							snprintf(buf,sizeof(buf), "%s|%s|%s|%s|%s", 
+									 p3->u1.str,
+									 p3->u2.arglist->u1.str,
+									 p3->u2.arglist->next->u1.str,
+									 p3->u2.arglist->next->next->u1.str,
+									 p3->u2.arglist->next->next->next->u1.str);
+							ast_context_add_include2(context, buf, registrar);
+						} else
+							ast_context_add_include2(context, p3->u1.str, registrar);
 					}
-					arg_free(argv2);
-				}
-			} else if (matches_keyword(cur->data, "ignorepat")) {
-				if (aeldebug & DEBUG_CONTEXTS)
-					ast_verbose("--IGNOREPAT: '%s'\n", cur->data);
-				parse_keyword(cur->data, &rest);
-				if (rest) {
-					argv2 = arg_parse(rest, filename, lineno);
-					cur2 = argv2;
-					while(cur2) {
-						ast_context_add_ignorepat2(con, cur2->data, registrar);
-						cur2 = cur2->next;
+					break;
+					
+				case PV_SWITCHES:
+					for (p3 = p2->u1.list; p3 ;p3=p3->next) {
+						char *c = strchr(p3->u1.str, '/');
+						if (c) {
+							*c = '\0';
+							c++;
+						} else
+							c = "";
+
+						ast_context_add_switch2(context, p3->u1.str, c, 0, registrar);
 					}
-					arg_free(argv2);
-				}
-			} else if (matches_keyword(cur->data, "switches") || matches_keyword(cur->data, "eswitches")) {
-				if (aeldebug & DEBUG_CONTEXTS)
-					ast_verbose("--[E]SWITCH: '%s'\n", cur->data);
-				parse_keyword(cur->data, &rest);
-				if (rest) {
-					argv2 = arg_parse(rest, filename, lineno);
-					cur2 = argv2;
-					while(cur2) {
-						c = strchr(cur2->data, '/');
+					break;
+
+				case PV_ESWITCHES:
+					for (p3 = p2->u1.list; p3 ;p3=p3->next) {
+						char *c = strchr(p3->u1.str, '/');
 						if (c) {
 							*c = '\0';
 							c++;
 						} else
 							c = "";
-						ast_context_add_switch2(con, cur2->data, c, (cur->data[0] == 'e'), registrar);
-						cur2 = cur2->next;
+
+						ast_context_add_switch2(context, p3->u1.str, c, 1, registrar);
 					}
-					arg_free(argv2);
+					break;
+				default:
+					break;
 				}
-			} else if (matches_extension(cur->data, &rest)) {
-				if (aeldebug & DEBUG_CONTEXTS)
-					ast_verbose("Extension: '%s' => '%s'\n", cur->data, rest);
-				pos = 1;
-				build_step("extension", cur->data, filename, lineno, con, cur->data, &pos, rest, NULL, NULL);
 			}
-			cur = cur->next;
-		}
-	} else
-			ast_log(LOG_WARNING, "Unable to create context '%s'\n", name);
-	arg_free(argv);
-	if (vars->next)
-		ast_log(LOG_NOTICE, "Ignoring excess tokens in macro definition around line %d of %s!\n", lineno, filename);
-}
-
-static int handle_root_token(struct ast_context **local_contexts, char *token, int level, const char *filename, int lineno)
-{
-	struct stringlink *argv, *cur;
-	argv = split_token(token, filename, lineno);
-	if (aeldebug & DEBUG_TOKENS) {
-		ast_verbose("Found root token '%s' at level %d (%s:%d)!\n", token, level, filename, lineno);
-		cur = argv;
-		while(cur) {
-			ast_verbose("   ARG => '%s'\n", cur->data);
-			cur = cur->next;
+			
+			break;
+			
+		default:
+			/* huh? what? */
+			break;
+			
 		}
 	}
-	if (!strcasecmp(token, "globals")) {
-		handle_globals(argv);
-	} else if (!strcasecmp(token, "macro")) {
-		handle_macro(local_contexts, argv, filename, lineno);
-	} else if (!strcasecmp(token, "context")) {
-		handle_context(local_contexts, argv, filename, lineno);
-	} else {
-		ast_log(LOG_NOTICE, "Unknown root token '%s'\n", token);
-	}
-	arg_free(argv);
-	return 0;
 }
 
+/* interface stuff */
 
-static int ast_ael_compile(struct ast_context **local_contexts, const char *filename)
+static int pbx_load_module(void)
 {
+	int errs, sem_err, sem_warn, sem_note;
 	char *rfilename;
-	char *buf, *tbuf;
-	int bufsiz;
-	FILE *f;
-	char *c;
-	char *token;
-	int lineno=0;
+	struct ast_context *local_contexts=NULL, *con;
+	struct pval *parse_tree;
 
-	if (filename[0] == '/')
-		rfilename = (char *)filename;
+	ast_log(LOG_NOTICE, "Starting AEL load process.\n");
+	if (config[0] == '/')
+		rfilename = (char *)config;
 	else {
-		rfilename = alloca(strlen(filename) + strlen(ast_config_AST_CONFIG_DIR) + 2);
-		sprintf(rfilename, "%s/%s", ast_config_AST_CONFIG_DIR, filename);
+		rfilename = alloca(strlen(config) + strlen(ast_config_AST_CONFIG_DIR) + 2);
+		sprintf(rfilename, "%s/%s", ast_config_AST_CONFIG_DIR, config);
 	}
+	ast_log(LOG_NOTICE, "AEL load process: calculated config file name '%s'.\n", rfilename);
 	
-	f = fopen(rfilename, "r");
-	if (!f) {
-		ast_log(LOG_WARNING, "Unable to open '%s': %s\n", rfilename, strerror(errno));
-		return -1;
-	}
-	buf = malloc(4096);
-	if (!buf) {
-		ast_log(LOG_WARNING, "Out of memory!\n");
-		fclose(f);
-		return -1;
+	parse_tree = ael2_parse(rfilename, &errs);
+	ast_log(LOG_NOTICE, "AEL load process: parsed config file name '%s'.\n", rfilename);
+	ael2_semantic_check(parse_tree, &sem_err, &sem_warn, &sem_note);
+	if (errs == 0 && sem_err == 0) {
+		ast_log(LOG_NOTICE, "AEL load process: checked config file name '%s'.\n", rfilename);
+		ast_compile_ael2(&local_contexts, parse_tree);
+		ast_log(LOG_NOTICE, "AEL load process: compiled config file name '%s'.\n", rfilename);
+		
+		ast_merge_contexts_and_delete(&local_contexts, registrar);
+		ast_log(LOG_NOTICE, "AEL load process: merged config file name '%s'.\n", rfilename);
+		for (con = ast_walk_contexts(NULL); con; con = ast_walk_contexts(con))
+			ast_context_verify_includes(con);
+		ast_log(LOG_NOTICE, "AEL load process: verified config file name '%s'.\n", rfilename);
+	} else {
+		ast_log(LOG_ERROR, "Sorry, but %d syntax errors and %d semantic errors were detected. It doesn't make sense to compile.\n", errs, sem_err);
 	}
-	buf[0] = 0;
-	bufsiz = 4096;
-	while(!feof(f)) {
-		if (bufsiz - strlen(buf) < 2048) {
-			bufsiz += 4096;
-			tbuf = realloc(buf, bufsiz);
-			if (tbuf) {
-				buf = tbuf;
-			} else {
-				free(buf);
-				ast_log(LOG_WARNING, "Out of memory!\n");
-				fclose(f);
-			}
-		}
-		if (fgets(buf + strlen(buf), bufsiz - strlen(buf), f)) {
-			lineno++;
-			while(*buf && buf[strlen(buf) - 1] < 33)
-				buf[strlen(buf) - 1] = '\0';
-			c = strstr(buf, "//");
-			if (c)
-				*c = '\0';
-			if (*buf) {
-				if (aeldebug & DEBUG_READ)
-					ast_verbose("Newly composed line '%s'\n", buf);
-				while((token = grab_token(buf, filename, lineno))) {
-					handle_root_token(local_contexts, token, 0, filename, lineno);
-					free(token);
-				}
-			}
-		}
-	};
-	free(buf);
-	fclose(f);
-	return 0;
-}
-
-static int pbx_load_module(void)
-{
-	struct ast_context *local_contexts=NULL, *con;
-	ast_ael_compile(&local_contexts, config);
-	ast_merge_contexts_and_delete(&local_contexts, registrar);
-	for (con = ast_walk_contexts(NULL); con; con = ast_walk_contexts(con))
-		ast_context_verify_includes(con);
-
+	destroy_pval(parse_tree); /* free up the memory */
+	
 	return 0;
 }
 
 /* CLI interface */
-static int ael_debug_read(int fd, int argc, char *argv[])
+static int ael2_debug_read(int fd, int argc, char *argv[])
 {
 	aeldebug |= DEBUG_READ;
 	return 0;
 }
 
-static int ael_debug_tokens(int fd, int argc, char *argv[])
+static int ael2_debug_tokens(int fd, int argc, char *argv[])
 {
 	aeldebug |= DEBUG_TOKENS;
 	return 0;
 }
 
-static int ael_debug_macros(int fd, int argc, char *argv[])
+static int ael2_debug_macros(int fd, int argc, char *argv[])
 {
 	aeldebug |= DEBUG_MACROS;
 	return 0;
 }
 
-static int ael_debug_contexts(int fd, int argc, char *argv[])
+static int ael2_debug_contexts(int fd, int argc, char *argv[])
 {
 	aeldebug |= DEBUG_CONTEXTS;
 	return 0;
 }
 
-static int ael_no_debug(int fd, int argc, char *argv[])
+static int ael2_no_debug(int fd, int argc, char *argv[])
 {
 	aeldebug = 0;
 	return 0;
 }
 
-static int ael_reload(int fd, int argc, char *argv[])
+static int ael2_reload(int fd, int argc, char *argv[])
 {
 	ast_context_destroy(NULL, registrar);
 	return (pbx_load_module());
 }
 
-static struct ast_cli_entry  ael_cli[] = {
-	{ { "ael", "reload", NULL }, ael_reload, "Reload AEL configuration"},
-	{ { "ael", "debug", "read", NULL }, ael_debug_read, "Enable AEL read debug"},
-	{ { "ael", "debug", "tokens", NULL }, ael_debug_tokens, "Enable AEL tokens debug"},
-	{ { "ael", "debug", "macros", NULL }, ael_debug_macros, "Enable AEL macros debug"},
-	{ { "ael", "debug", "contexts", NULL }, ael_debug_contexts, "Enable AEL contexts debug"},
-	{ { "ael", "no", "debug", NULL }, ael_no_debug, "Disable AEL debug messages"},
+static struct ast_cli_entry  ael2_cli[] = {
+	{ { "ael2", "reload", NULL }, ael2_reload, "Reload AEL configuration"},
+	{ { "ael2", "debug", "read", NULL }, ael2_debug_read, "Enable AEL read debug (does nothing)"},
+	{ { "ael2", "debug", "tokens", NULL }, ael2_debug_tokens, "Enable AEL tokens debug (does nothing)"},
+	{ { "ael2", "debug", "macros", NULL }, ael2_debug_macros, "Enable AEL macros debug (does nothing)"},
+	{ { "ael2", "debug", "contexts", NULL }, ael2_debug_contexts, "Enable AEL contexts debug (does nothing)"},
+	{ { "ael2", "no", "debug", NULL }, ael2_no_debug, "Disable AEL debug messages"},
 };
 
 /*
@@ -1250,14 +3507,14 @@ static struct ast_cli_entry  ael_cli[] = {
 static int unload_module(void *mod)
 {
 	ast_context_destroy(NULL, registrar);
-	ast_cli_unregister_multiple(ael_cli, sizeof(ael_cli)/ sizeof(ael_cli[0]));
+	ast_cli_unregister_multiple(ael2_cli, sizeof(ael2_cli)/ sizeof(ael2_cli[0]));
 	return 0;
 }
 
 
 static int load_module(void *mod)
 {
-	ast_cli_register_multiple(ael_cli, sizeof(ael_cli)/ sizeof(ael_cli[0]));
+	ast_cli_register_multiple(ael2_cli, sizeof(ael2_cli)/ sizeof(ael2_cli[0]));
 	return (pbx_load_module());
 }
 
@@ -1269,7 +3526,7 @@ static int reload(void *mod)
 
 static const char *description(void)
 {
-	return "Asterisk Extension Language Compiler";
+	return dtext;
 }
 
 static const char *key(void)
@@ -1278,3 +3535,354 @@ static const char *key(void)
 }
 
 STD_MOD(MOD_1 | NO_USECOUNT, reload, NULL, NULL);
+
+/* DESTROY the PVAL tree ============================================================================ */
+
+
+
+void destroy_pval_item(pval *item)
+{
+	if (item->filename)
+		free(item->filename);
+	
+	switch (item->type) {
+	case PV_WORD:
+		/* fields: item->u1.str == string associated with this (word). */
+		if (item->u1.str )
+			free(item->u1.str);
+		if ( item->u2.arglist )
+			destroy_pval(item->u2.arglist);
+		break;
+		
+	case PV_MACRO:
+		/* fields: item->u1.str     == name of macro
+		           item->u2.arglist == pval list of PV_WORD arguments of macro, as given by user
+				   item->u2.arglist->u1.str  == argument
+				   item->u2.arglist->next   == next arg
+
+				   item->u3.macro_statements == pval list of statements in macro body.
+		*/
+		destroy_pval(item->u2.arglist);
+		if (item->u1.str )
+			free(item->u1.str);
+		destroy_pval(item->u3.macro_statements);
+		break;
+			
+	case PV_CONTEXT:
+		/* fields: item->u1.str     == name of context
+		           item->u2.statements == pval list of statements in context body
+				   item->u3.abstract == int 1 if an abstract keyword were present
+		*/
+		if (item->u1.str)
+			free(item->u1.str);
+		destroy_pval(item->u2.statements);
+		break;
+			
+	case PV_MACRO_CALL:
+		/* fields: item->u1.str     == name of macro to call
+		           item->u2.arglist == pval list of PV_WORD arguments of macro call, as given by user
+				   item->u2.arglist->u1.str  == argument
+				   item->u2.arglist->next   == next arg
+		*/
+		if (item->u1.str)
+			free(item->u1.str);
+		destroy_pval(item->u2.arglist);
+		break;
+			
+	case PV_APPLICATION_CALL:
+		/* fields: item->u1.str     == name of application to call
+		           item->u2.arglist == pval list of PV_WORD arguments of macro call, as given by user
+				   item->u2.arglist->u1.str  == argument
+				   item->u2.arglist->next   == next arg
+		*/
+		if (item->u1.str)
+			free(item->u1.str);
+		destroy_pval(item->u2.arglist);
+		break;
+			
+	case PV_CASE:
+		/* fields: item->u1.str     == value of case
+		           item->u2.statements == pval list of statements under the case
+		*/
+		if (item->u1.str)
+			free(item->u1.str);
+		destroy_pval(item->u2.statements);
+		break;
+			
+	case PV_PATTERN:
+		/* fields: item->u1.str     == value of case
+		           item->u2.statements == pval list of statements under the case
+		*/
+		if (item->u1.str)
+			free(item->u1.str);
+		destroy_pval(item->u2.statements);
+		break;
+			
+	case PV_DEFAULT:
+		/* fields: 
+		           item->u2.statements == pval list of statements under the case
+		*/
+		destroy_pval(item->u2.statements);
+		break;
+			
+	case PV_CATCH:
+		/* fields: item->u1.str     == name of extension to catch
+		           item->u2.statements == pval list of statements in context body
+		*/
+		if (item->u1.str)
+			free(item->u1.str);
+		destroy_pval(item->u2.statements);
+		break;
+			
+	case PV_SWITCHES:
+		/* fields: item->u1.list     == pval list of PV_WORD elements, one per entry in the list
+		*/
+		destroy_pval(item->u1.list);
+		break;
+			
+	case PV_ESWITCHES:
+		/* fields: item->u1.list     == pval list of PV_WORD elements, one per entry in the list
+		*/
+		destroy_pval(item->u1.list);
+		break;
+			
+	case PV_INCLUDES:
+		/* fields: item->u1.list     == pval list of PV_WORD elements, one per entry in the list
+		           item->u2.arglist  == pval list of 4 PV_WORD elements for time values
+		*/
+		destroy_pval(item->u1.list);
+		break;
+			
+	case PV_STATEMENTBLOCK:
+		/* fields: item->u1.list     == pval list of statements in block, one per entry in the list
+		*/
+		destroy_pval(item->u1.list);
+		break;
+			
+	case PV_VARDEC:
+		/* fields: item->u1.str     == variable name
+		           item->u2.val     == variable value to assign
+		*/
+		if (item->u1.str)
+			free(item->u1.str);
+		if (item->u2.val)
+			free(item->u2.val);
+		break;
+			
+	case PV_GOTO:
+		/* fields: item->u1.list     == pval list of PV_WORD target names, up to 3, in order as given by user.
+		           item->u1.list->u1.str  == where the data on a PV_WORD will always be.
+		*/
+		
+		destroy_pval(item->u1.list);
+		break;
+			
+	case PV_LABEL:
+		/* fields: item->u1.str     == label name
+		*/
+		if (item->u1.str)
+			free(item->u1.str);
+		break;
+			
+	case PV_FOR:
+		/* fields: item->u1.for_init     == a string containing the initalizer
+		           item->u2.for_test     == a string containing the loop test
+		           item->u3.for_inc      == a string containing the loop increment
+
+				   item->u4.for_statements == a pval list of statements in the for ()
+		*/
+		if (item->u1.for_init)
+			free(item->u1.for_init);
+		if (item->u2.for_test)
+			free(item->u2.for_test);
+		if (item->u3.for_inc)
+			free(item->u3.for_inc);
+		destroy_pval(item->u4.for_statements);
+		break;
+			
+	case PV_WHILE:
+		/* fields: item->u1.str        == the while conditional, as supplied by user
+
+				   item->u2.statements == a pval list of statements in the while ()
+		*/
+		if (item->u1.str)
+			free(item->u1.str);
+		destroy_pval(item->u2.statements);
+		break;
+			
+	case PV_BREAK:
+		/* fields: none
+		*/
+		break;
+			
+	case PV_RETURN:
+		/* fields: none
+		*/
+		break;
+			
+	case PV_CONTINUE:
+		/* fields: none
+		*/
+		break;
+			
+	case PV_IFTIME:
+		/* fields: item->u1.list        == the 4 time values, in PV_WORD structs, linked list
+
+				   item->u2.statements == a pval list of statements in the if ()
+				   item->u3.else_statements == a pval list of statements in the else
+											   (could be zero)
+		*/
+		destroy_pval(item->u1.list);
+		destroy_pval(item->u2.statements);
+		if (item->u3.else_statements) {
+			destroy_pval(item->u3.else_statements);
+		}
+		break;
+			
+	case PV_RANDOM:
+		/* fields: item->u1.str        == the random percentage, as supplied by user
+
+				   item->u2.statements == a pval list of statements in the true part ()
+				   item->u3.else_statements == a pval list of statements in the else
+											   (could be zero)
+		fall thru to If */
+	case PV_IF:
+		/* fields: item->u1.str        == the if conditional, as supplied by user
+
+				   item->u2.statements == a pval list of statements in the if ()
+				   item->u3.else_statements == a pval list of statements in the else
+											   (could be zero)
+		*/
+		if (item->u1.str)
+			free(item->u1.str);
+		destroy_pval(item->u2.statements);
+		if (item->u3.else_statements) {
+			destroy_pval(item->u3.else_statements);
+		}
+		break;
+			
+	case PV_SWITCH:
+		/* fields: item->u1.str        == the switch expression
+
+				   item->u2.statements == a pval list of statements in the switch, 
+				   							(will be case statements, most likely!)
+		*/
+		if (item->u1.str)
+			free(item->u1.str);
+		destroy_pval(item->u2.statements);
+		break;
+			
+	case PV_EXTENSION:
+		/* fields: item->u1.str        == the extension name, label, whatever it's called
+
+				   item->u2.statements == a pval list of statements in the extension
+				   item->u3.hints      == a char * hint argument
+				   item->u4.regexten   == an int boolean. non-zero says that regexten was specified
+		*/
+		if (item->u1.str)
+			free(item->u1.str);
+		if (item->u3.hints)
+			free(item->u3.hints);
+		destroy_pval(item->u2.statements);
+		break;
+			
+	case PV_IGNOREPAT:
+		/* fields: item->u1.str        == the ignorepat data
+		*/
+		if (item->u1.str)
+			free(item->u1.str);
+		break;
+			
+	case PV_GLOBALS:
+		/* fields: item->u1.statements     == pval list of statements, usually vardecs
+		*/
+		destroy_pval(item->u1.statements);
+		break;
+	}
+	free(item);
+}
+
+void destroy_pval(pval *item) 
+{
+	pval *i,*nxt;
+	
+	for (i=item; i; i=nxt) {
+		nxt = i->next;
+		
+		destroy_pval_item(i);
+	}
+}
+
+#ifdef AAL_ARGCHECK
+static char *ael_funclist[] =
+{
+	"AGENT",
+	"ARRAY",
+	"BASE64_DECODE",
+	"BASE64_ENCODE",
+	"CALLERID",
+	"CDR",
+	"CHANNEL",
+	"CHECKSIPDOMAIN",
+	"CHECK_MD5",
+	"CURL",
+	"CUT",
+	"DB",
+	"DB_EXISTS",
+	"DUNDILOOKUP",
+	"ENUMLOOKUP",
+	"ENV",
+	"EVAL",
+	"EXISTS",
+	"FIELDQTY",
+	"FILTER",
+	"GROUP",
+	"GROUP_COUNT",
+	"GROUP_LIST",
+	"GROUP_MATCH_COUNT",
+	"IAXPEER",
+	"IF",
+	"IFTIME",
+	"ISNULL",
+	"KEYPADHASH",
+	"LANGUAGE",
+	"LEN",
+	"MATH",
+	"MD5",
+	"MUSICCLASS",
+	"QUEUEAGENTCOUNT",
+	"QUEUE_MEMBER_COUNT",
+	"QUEUE_MEMBER_LIST",
+	"QUOTE",
+	"RAND",
+	"REGEX",
+	"SET",
+	"SHA1",
+	"SIPCHANINFO",
+	"SIPPEER",
+	"SIP_HEADER",
+	"SORT",
+	"STAT",
+	"STRFTIME",
+	"STRPTIME",
+	"TIMEOUT",
+	"TXTCIDNAME",
+	"URIDECODE",
+	"URIENCODE",
+	"VMCOUNT"
+};
+
+
+int ael_is_funcname(char *name)
+{
+	int s,t;
+	t = sizeof(ael_funclist)/sizeof(char*);
+	s = 0;
+	while ((s < t) && strcasecmp(name, ael_funclist[s])) 
+		s++;
+	if ( s < t )
+		return 1;
+	else
+		return 0;
+}
+#endif    
diff --git a/utils/Makefile b/utils/Makefile
index 57cbb6200d..d88beee832 100644
--- a/utils/Makefile
+++ b/utils/Makefile
@@ -66,6 +66,22 @@ ast_expr2f.o: ../ast_expr2f.c
 check_expr: check_expr.c ast_expr2.o ast_expr2f.o
 	$(CC) $(CFLAGS) -o $@ $^
 
+aelparse : ../pbx/ael/aelflex.o ../pbx/ael/aelbison.o ../pbx/pbx_ael.o ael_main.o ../ast_expr2f.o ../ast_expr2.o
+	$(CC) $(CFLAGS) -g -o aelparse ../pbx/ael/aelflex.o ../pbx/ael/aelbison.o ael_main.o ../pbx/pbx_ael.o ../ast_expr2f.o ../ast_expr2.o
+
+ael_main.o : ael_main.c ../include/asterisk/ael_structs.h
+	$(CC) $(CFLAGS) -c -g -o ael_main.o ael_main.c
+
+ael_main1.o : ael_main.c ../include/asterisk/ael_structs.h
+	$(CC) $(CFLAGS) -c -g  -o ael_main1.o ael_main.c
+
+testexpr2s: ../ast_expr2f.c ../ast_expr2.c ../ast_expr2.h
+	gcc -g -c -I../include -DSTANDALONE ../ast_expr2f.c -o ast_expr2f.o
+	gcc -g -c -I../include -DSTANDALONE ../ast_expr2.c -o ast_expr2.o
+	gcc -g -o testexpr2s ast_expr2f.o ast_expr2.o
+	rm ast_expr2.o ast_expr2f.o 
+	./testexpr2s expr2.testinput
+
 smsq.o: smsq.c
 	$(CC) $(CFLAGS) -include ../include/autoconfig.h -c -o $@ $<
 
diff --git a/utils/ael_main.c b/utils/ael_main.c
new file mode 100644
index 0000000000..ee6e815bdc
--- /dev/null
+++ b/utils/ael_main.c
@@ -0,0 +1,264 @@
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <locale.h>
+#include <ctype.h>
+#if !defined(SOLARIS) && !defined(__CYGWIN__)
+#include <err.h>
+#else
+#define quad_t int64_t
+#endif
+#include <errno.h>
+#include <regex.h>
+#include <limits.h>
+#include <asterisk/ast_expr.h>
+#include <asterisk/logger.h>
+#include <asterisk/module.h>
+#include <asterisk/channel.h>
+#include <asterisk/app.h>
+#include "asterisk/ael_structs.h"
+#define AST_CONFIG_MAX_PATH 255
+
+int conts=0, extens=0, priors=0;
+char last_exten[18000];
+char ast_config_AST_CONFIG_DIR[AST_CONFIG_MAX_PATH];
+char ast_config_AST_VAR_DIR[AST_CONFIG_MAX_PATH];
+
+void ast_cli_register_multiple(void);
+void ast_register_file_version(void);
+void ast_unregister_file_version(void);
+int ast_add_extension2(void *con,
+					   int replace, const char *extension, int priority, const char *label, const char *callerid,
+						const char *application, void *data, void (*datad)(void *),
+					   const char *registrar);
+void pbx_builtin_setvar(void *chan, void *data);
+void ast_context_create(void **extcontexts, const char *name, const char *registrar);
+void ast_context_add_ignorepat2(void *con, const char *value, const char *registrar);
+void ast_context_add_include2(void *con, const char *value, const char *registrar);
+void ast_context_add_switch2(void *con, const char *value, const char *data, int eval, const char *registrar);
+void ast_merge_contexts_and_delete(void);
+void ast_context_verify_includes(void);
+struct ast_context * ast_walk_contexts(void);
+void ast_cli_unregister_multiple(void);
+void ast_context_destroy(void);
+void ast_log(int level, const char *file, int line, const char *function, const char *fmt, ...);
+char *ast_process_quotes_and_slashes(char *start, char find, char replace_with);
+void ast_verbose(const char *fmt, ...);
+struct ast_app *pbx_findapp(const char *app);
+static int no_comp = 0;
+static int use_curr_dir = 0;
+
+
+struct ast_app *pbx_findapp(const char *app)
+{
+	return (struct ast_app*)1; /* so as not to trigger an error */
+}
+
+
+void ast_copy_string(char *dst, const char *src, size_t size)
+{
+        while (*src && size) {
+                *dst++ = *src++;
+                size--;
+        }
+        if (__builtin_expect(!size, 0))
+                dst--;
+        *dst = '\0';
+}
+
+void ast_cli_register_multiple(void)
+{
+	if(!no_comp)
+        printf("Executed ast_cli_register_multiple();\n");
+}
+
+void ast_register_file_version(void)
+{
+	if(!no_comp)
+	printf("Executed ast_register_file_version();\n");
+}
+
+void ast_unregister_file_version(void)
+{
+	if(!no_comp)
+	printf("Executed ast_unregister_file_version();\n");
+
+}
+int ast_add_extension2(void *con,
+						int replace, const char *extension, int priority, const char *label, const char *callerid,
+						const char *application, void *data, void (*datad)(void *),
+						const char *registrar)
+{
+	priors++;
+	if (strcmp(extension,last_exten) != 0) {
+		extens++;
+		strcpy(last_exten, extension);
+	}
+	if (!label) {
+		label = "(null)";
+	}
+	if (!callerid) {
+		callerid = "(null)";
+	}
+	if (!application) {
+		application = "(null)";
+	}
+	if(!no_comp)
+	printf("Executed ast_add_extension2(con, rep=%d, exten=%s, priority=%d, label=%s, callerid=%s, appl=%s, data=%s, FREE, registrar=%s);\n",
+		replace, extension, priority, label, callerid, application, (data?(char*)data:"(null)"), registrar);
+
+	/* since add_extension2 is responsible for the malloc'd data stuff */
+	if( data )
+		free(data);
+	return 0;
+}
+
+void pbx_builtin_setvar(void *chan, void *data)
+{
+	if(!no_comp)
+	printf("Executed pbx_builtin_setvar(chan, data=%s);\n", (char*)data);
+}
+	
+
+void ast_context_create(void **extcontexts, const char *name, const char *registrar)
+{
+	if(!no_comp)
+	printf("Executed ast_context_create(conts, name=%s, registrar=%s);\n", name, registrar);
+	conts++;
+}
+
+void ast_context_add_ignorepat2(void *con, const char *value, const char *registrar)
+{
+	if(!no_comp)
+	printf("Executed ast_context_add_ignorepat2(con, value=%s, registrar=%s);\n", value, registrar);
+}
+
+void ast_context_add_include2(void *con, const char *value, const char *registrar)
+{
+	if(!no_comp)
+	printf("Executed ast_context_add_include2(con, value=%s, registrar=%s);\n", value, registrar);
+}
+
+void ast_context_add_switch2(void *con, const char *value, const char *data, int eval, const char *registrar)
+{
+	if(!no_comp)
+	printf("Executed ast_context_add_switch2(con, value=%s, data=%s, eval=%d, registrar=%s);\n", value, data, eval, registrar);
+}
+
+void ast_merge_contexts_and_delete(void)
+{
+	if(!no_comp)
+	printf("Executed ast_merge_contexts_and_delete();\n");
+}
+
+void ast_context_verify_includes(void)
+{
+	if(!no_comp)
+	printf("Executed ast_context_verify_includes();\n");
+}
+
+struct ast_context * ast_walk_contexts(void)
+{
+	if(!no_comp)
+	printf("Executed ast_walk_contexts();\n");
+	return 0;
+}
+
+void ast_cli_unregister_multiple(void)
+{
+	if(!no_comp)
+	printf("Executed ast_cli_unregister_multiple();\n");
+}
+
+void ast_context_destroy(void)
+{
+	printf("Executed ast_context_destroy();\n");
+}
+
+void ast_log(int level, const char *file, int line, const char *function, const char *fmt, ...)
+{
+        va_list vars;
+        va_start(vars,fmt);
+
+        printf("LOG: lev:%d file:%s  line:%d func: %s  ",
+                   level, file, line, function);
+        vprintf(fmt, vars);
+        fflush(stdout);
+        va_end(vars);
+}
+
+void ast_verbose(const char *fmt, ...)
+{
+        va_list vars;
+        va_start(vars,fmt);
+
+        printf("VERBOSE: ");
+        vprintf(fmt, vars);
+        fflush(stdout);
+        va_end(vars);
+}
+
+char *ast_process_quotes_and_slashes(char *start, char find, char replace_with)
+{
+        char *dataPut = start;
+        int inEscape = 0;
+        int inQuotes = 0;
+
+        for (; *start; start++) {
+                if (inEscape) {
+                        *dataPut++ = *start;       /* Always goes verbatim */
+                        inEscape = 0;
+                } else {
+                        if (*start == '\\') {
+                                inEscape = 1;      /* Do not copy \ into the data */
+                        } else if (*start == '\'') {
+                                inQuotes = 1-inQuotes;   /* Do not copy ' into the data */
+                        } else {
+                                /* Replace , with |, unless in quotes */
+                                *dataPut++ = inQuotes ? *start : ((*start==find) ? replace_with : *start);
+                        }
+                }
+        }
+        if (start != dataPut)
+                *dataPut = 0;
+        return dataPut;
+}
+
+extern struct module_symbols mod_data;
+
+
+int main(int argc, char **argv)
+{
+	int i;
+	
+	for(i=1;i<argc;i++)
+	{
+		if( argv[i][0] == '-' && argv[i][1] == 'n' )
+			no_comp =1;
+		if( argv[i][0] == '-' && argv[i][1] == 'd' )
+			use_curr_dir =1;
+	}
+	
+		
+	if( !no_comp )
+		printf("\n(You can use the -n option if you aren't interested in seeing all the instructions generated by the compiler)\n\n");
+	if( !use_curr_dir )
+		printf("\n(You can use the -d option if you want to use the current working directory as the CONFIG_DIR. I will look in this dir for extensions.ael* and its included files)\n\n");
+	
+	if( use_curr_dir )
+	{
+		strcpy(ast_config_AST_CONFIG_DIR, ".");
+	}
+	else
+	{
+		strcpy(ast_config_AST_CONFIG_DIR, "/etc/asterisk");
+	}
+	strcpy(ast_config_AST_VAR_DIR, "/var/lib/asterisk");
+	
+	mod_data.load_module(0);
+	
+	ast_log(4, "ael2_parse", __LINE__, "main", "%d contexts, %d extensions, %d priorities\n", conts, extens, priors);
+	
+    return 0;
+}
diff --git a/utils/expr2.testinput b/utils/expr2.testinput
new file mode 100644
index 0000000000..948baaf94e
--- /dev/null
+++ b/utils/expr2.testinput
@@ -0,0 +1,92 @@
+2 + 2
+      2     +       2            
+
+2 - 4
+4 - 2
+-4 - -2
+4 + 2 * 8
+(4 + 2) * 8
+4 + (2 * 8)
+4 + (2 * 8) ? 3 :: 6
+4 + 8 / 2
+4 + 8 / 3
+(4+8) / 3
+4 + 8 % 3
+4 + 9 % 3
+(4+9) %3
+(4+8) %3
+(4+9) %3
+(4+8) %3
+(4+9) % 3
+(4+8) % 3
+(4+9) % 3
+(4+8) % 3
+(4+9)% 3
+(4+8)% 3
+(4+9)% 3
+(4+8)% 3
+4 & 4
+0 & 4
+0 & 0
+2 | 0
+2 | 4
+0 | 0
+!0 | 0
+!4 | 0
+4 | !0
+!4 | !0
+3 < 4
+4 < 3
+3 > 4
+4 > 3
+3 = 3
+3 = 4
+3 != 3
+3 != 4
+3 >= 4
+3 >= 3
+4 >= 3
+3 <= 4
+4 <= 3
+4 <= 4
+3 > 4 & 4 < 3
+4 > 3 & 3 < 4
+x = x
+y = x
+x != y
+x != x
+"Something interesting" =~ interesting
+"Something interesting" =~ Something
+"Something interesting" : Something
+"Something interesting" : interesting
+"Something interesting" =~ "interesting"
+"Something interesting" =~ "Something"
+"Something interesting" : "Something"
+"Something interesting" : "interesting"
+"Something interesting" =~ (interesting)
+"Something interesting" =~ (Something)
+"Something interesting" : (Something)
+"Something interesting" : (interesting)
+"Something interesting" =~ "\(interesting\)"
+"Something interesting" =~ "\(Something\)"
+"Something interesting" : "\(Something\)"
+"Something interesting" : "\(interesting\)"
+"011043567857575" : "011\(..\)"
+"9011043567857575" : "011\(..\)"
+"011043567857575" =~ "011\(..\)"
+"9011043567857575" =~ "011\(..\)"
+"Something interesting" =~ (interesting)
+"Something interesting" =~ (Something)
+"Something interesting" : (Something)
+"Something interesting" : (interesting)
+"Something interesting" =~ "(interesting)"
+"Something interesting" =~ "(Something)"
+"Something interesting" : "(Something)"
+"Something interesting" : "(interesting)"
+"011043567857575" : "011(..)"
+"9011043567857575" : "011(..)"
+"011043567857575" =~ "011(..)"
+"9011043567857575" =~ "011(..)"
+3
+something
+043
-- 
GitLab