emacs-elpa-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[elpa] master ab6f759: * externals-list: Convert wisi to :external


From: Stefan Monnier
Subject: [elpa] master ab6f759: * externals-list: Convert wisi to :external
Date: Sat, 28 Nov 2020 14:48:03 -0500 (EST)

branch: master
commit ab6f7599ecd637a08b59b247807a40d1ed6f5dc1
Author: Stefan Monnier <monnier@iro.umontreal.ca>
Commit: Stefan Monnier <monnier@iro.umontreal.ca>

    * externals-list: Convert wisi to :external
---
 externals-list                                     |    1 +
 packages/wisi/NEWS                                 |  303 --
 packages/wisi/README                               |   14 -
 packages/wisi/build-wisitoken-bnf-generate.sh      |    7 -
 packages/wisi/dir                                  |   19 -
 packages/wisi/emacs_wisi_common_parse.adb          |  508 ---
 packages/wisi/emacs_wisi_common_parse.ads          |  157 -
 packages/wisi/gen_emacs_wisi_lr_parse.adb          |   39 -
 packages/wisi/gen_emacs_wisi_lr_parse.ads          |   55 -
 packages/wisi/gen_emacs_wisi_lr_text_rep_parse.adb |   44 -
 packages/wisi/gen_emacs_wisi_lr_text_rep_parse.ads |   50 -
 packages/wisi/gen_emacs_wisi_packrat_parse.adb     |  180 -
 packages/wisi/gen_emacs_wisi_packrat_parse.ads     |   42 -
 packages/wisi/gen_run_wisi_libadalang_parse.adb    |  176 -
 packages/wisi/gen_run_wisi_libadalang_parse.ads    |   30 -
 packages/wisi/gen_run_wisi_lr_parse.adb            |   37 -
 packages/wisi/gen_run_wisi_lr_parse.ads            |   42 -
 packages/wisi/gen_run_wisi_lr_text_rep_parse.adb   |   44 -
 packages/wisi/gen_run_wisi_lr_text_rep_parse.ads   |   44 -
 packages/wisi/gen_run_wisi_packrat_parse.adb       |  241 --
 packages/wisi/gen_run_wisi_packrat_parse.ads       |   36 -
 packages/wisi/long_float_elementary_functions.ads  |   21 -
 packages/wisi/recover_stats.adb                    |  271 --
 packages/wisi/run_wisi_common_parse.adb            |  356 --
 packages/wisi/run_wisi_common_parse.ads            |   73 -
 ...da_containers-gen_doubly_linked_lists_image.adb |   50 -
 ...da_containers-gen_doubly_linked_lists_image.ads |   28 -
 packages/wisi/sal-ada_containers.ads               |   21 -
 packages/wisi/sal-gen_array_image.adb              |   34 -
 packages/wisi/sal-gen_array_image.ads              |   24 -
 packages/wisi/sal-gen_bounded_definite_queues.adb  |  103 -
 packages/wisi/sal-gen_bounded_definite_queues.ads  |  117 -
 ...l-gen_bounded_definite_stacks-gen_image_aux.adb |   42 -
 ...l-gen_bounded_definite_stacks-gen_image_aux.ads |   27 -
 packages/wisi/sal-gen_bounded_definite_stacks.adb  |   82 -
 packages/wisi/sal-gen_bounded_definite_stacks.ads  |  103 -
 .../sal-gen_bounded_definite_vectors-gen_image.adb |   40 -
 .../sal-gen_bounded_definite_vectors-gen_image.ads |   23 -
 ...-gen_bounded_definite_vectors-gen_image_aux.adb |   35 -
 ...-gen_bounded_definite_vectors-gen_image_aux.ads |   23 -
 .../sal-gen_bounded_definite_vectors-gen_refs.adb  |   35 -
 .../sal-gen_bounded_definite_vectors-gen_refs.ads  |   54 -
 packages/wisi/sal-gen_bounded_definite_vectors.adb |  120 -
 packages/wisi/sal-gen_bounded_definite_vectors.ads |  145 -
 ...unded_definite_vectors_sorted-gen_image_aux.adb |   35 -
 ...unded_definite_vectors_sorted-gen_image_aux.ads |   23 -
 ...en_bounded_definite_vectors_sorted-gen_refs.adb |   29 -
 ...en_bounded_definite_vectors_sorted-gen_refs.ads |   39 -
 .../sal-gen_bounded_definite_vectors_sorted.adb    |   96 -
 .../sal-gen_bounded_definite_vectors_sorted.ads    |  100 -
 .../wisi/sal-gen_definite_doubly_linked_lists.adb  |  317 --
 .../wisi/sal-gen_definite_doubly_linked_lists.ads  |  172 -
 ...finite_doubly_linked_lists_sorted-gen_image.adb |   47 -
 ...finite_doubly_linked_lists_sorted-gen_image.ads |   25 -
 ...sal-gen_definite_doubly_linked_lists_sorted.adb |  542 ---
 ...sal-gen_definite_doubly_linked_lists_sorted.ads |  190 -
 packages/wisi/sal-gen_graphs.adb                   |  719 ----
 packages/wisi/sal-gen_graphs.ads                   |  190 -
 .../sal-gen_indefinite_doubly_linked_lists.adb     |  211 -
 .../sal-gen_indefinite_doubly_linked_lists.ads     |  128 -
 packages/wisi/sal-gen_trimmed_image.adb            |   28 -
 packages/wisi/sal-gen_trimmed_image.ads            |   23 -
 ...-gen_unbounded_definite_min_heaps_fibonacci.adb |  354 --
 ...-gen_unbounded_definite_min_heaps_fibonacci.ads |  112 -
 ...gen_unbounded_definite_queues-gen_image_aux.adb |   35 -
 ...gen_unbounded_definite_queues-gen_image_aux.ads |   23 -
 .../wisi/sal-gen_unbounded_definite_queues.adb     |   97 -
 .../wisi/sal-gen_unbounded_definite_queues.ads     |  110 -
 .../sal-gen_unbounded_definite_red_black_trees.adb |  870 ----
 .../sal-gen_unbounded_definite_red_black_trees.ads |  198 -
 ...gen_unbounded_definite_stacks-gen_image_aux.adb |   42 -
 ...gen_unbounded_definite_stacks-gen_image_aux.ads |   27 -
 .../wisi/sal-gen_unbounded_definite_stacks.adb     |  219 -
 .../wisi/sal-gen_unbounded_definite_stacks.ads     |  158 -
 ...n_unbounded_definite_vectors-gen_comparable.adb |   73 -
 ...n_unbounded_definite_vectors-gen_comparable.ads |   30 -
 ...al-gen_unbounded_definite_vectors-gen_image.adb |   50 -
 ...al-gen_unbounded_definite_vectors-gen_image.ads |   24 -
 ...en_unbounded_definite_vectors-gen_image_aux.adb |   43 -
 ...en_unbounded_definite_vectors-gen_image_aux.ads |   28 -
 .../wisi/sal-gen_unbounded_definite_vectors.adb    |  585 ---
 .../wisi/sal-gen_unbounded_definite_vectors.ads    |  252 --
 .../sal-gen_unbounded_definite_vectors_sorted.adb  |  374 --
 .../sal-gen_unbounded_definite_vectors_sorted.ads  |  172 -
 .../wisi/sal-gen_unconstrained_array_image.adb     |   34 -
 .../wisi/sal-gen_unconstrained_array_image.ads     |   24 -
 .../wisi/sal-gen_unconstrained_array_image_aux.adb |   33 -
 .../wisi/sal-gen_unconstrained_array_image_aux.ads |   25 -
 packages/wisi/sal-generic_decimal_image.adb        |   48 -
 packages/wisi/sal-generic_decimal_image.ads        |   37 -
 packages/wisi/sal.adb                              |   32 -
 packages/wisi/sal.ads                              |   75 -
 packages/wisi/standard_common.gpr                  |  152 -
 packages/wisi/wisi-fringe.el                       |  152 -
 packages/wisi/wisi-parse-common.el                 |  403 --
 packages/wisi/wisi-prj.el                          | 1614 --------
 packages/wisi/wisi-process-parse.el                |  844 ----
 packages/wisi/wisi-run-indent-test.el              |  399 --
 packages/wisi/wisi-skel.el                         |  187 -
 packages/wisi/wisi-tests.el                        |  120 -
 packages/wisi/wisi.adb                             | 2434 -----------
 packages/wisi/wisi.ads                             |  769 ----
 packages/wisi/wisi.el                              | 1725 --------
 packages/wisi/wisi.gpr.gp                          |   64 -
 packages/wisi/wisi.info                            | 1294 ------
 packages/wisi/wisi.texi                            |  812 ----
 packages/wisi/wisitoken-bnf-generate.adb           |  634 ---
 packages/wisi/wisitoken-bnf-generate_grammar.adb   |   86 -
 packages/wisi/wisitoken-bnf-generate_packrat.adb   |  333 --
 packages/wisi/wisitoken-bnf-generate_utils.adb     |  724 ----
 packages/wisi/wisitoken-bnf-generate_utils.ads     |  174 -
 packages/wisi/wisitoken-bnf-output_ada.adb         |  512 ---
 packages/wisi/wisitoken-bnf-output_ada_common.adb  | 1392 -------
 packages/wisi/wisitoken-bnf-output_ada_common.ads  |   90 -
 packages/wisi/wisitoken-bnf-output_ada_emacs.adb   | 1916 ---------
 .../wisi/wisitoken-bnf-output_elisp_common.adb     |  212 -
 .../wisi/wisitoken-bnf-output_elisp_common.ads     |   54 -
 packages/wisi/wisitoken-bnf-utils.adb              |   45 -
 packages/wisi/wisitoken-bnf-utils.ads              |   29 -
 packages/wisi/wisitoken-bnf.adb                    |  355 --
 packages/wisi/wisitoken-bnf.ads                    |  358 --
 packages/wisi/wisitoken-followed_by.adb            |  207 -
 packages/wisi/wisitoken-gen_token_enum.adb         |  133 -
 packages/wisi/wisitoken-gen_token_enum.ads         |  122 -
 .../wisi/wisitoken-generate-lr-lalr_generate.adb   |  611 ---
 .../wisi/wisitoken-generate-lr-lalr_generate.ads   |   87 -
 .../wisi/wisitoken-generate-lr-lr1_generate.adb    |  343 --
 .../wisi/wisitoken-generate-lr-lr1_generate.ads    |   91 -
 packages/wisi/wisitoken-generate-lr.adb            | 1510 -------
 packages/wisi/wisitoken-generate-lr.ads            |  214 -
 packages/wisi/wisitoken-generate-lr1_items.adb     |  553 ---
 packages/wisi/wisitoken-generate-lr1_items.ads     |  335 --
 packages/wisi/wisitoken-generate-packrat.adb       |  247 --
 packages/wisi/wisitoken-generate-packrat.ads       |   75 -
 packages/wisi/wisitoken-generate.adb               |  665 ---
 packages/wisi/wisitoken-generate.ads               |  200 -
 packages/wisi/wisitoken-lexer-re2c.adb             |  307 --
 packages/wisi/wisitoken-lexer-re2c.ads             |  144 -
 packages/wisi/wisitoken-lexer-regexp.adb           |  259 --
 packages/wisi/wisitoken-lexer-regexp.ads           |  114 -
 packages/wisi/wisitoken-lexer.adb                  |   61 -
 packages/wisi/wisitoken-lexer.ads                  |  187 -
 .../wisitoken-parse-lr-mckenzie_recover-base.adb   |  451 --
 .../wisitoken-parse-lr-mckenzie_recover-base.ads   |  185 -
 ...wisitoken-parse-lr-mckenzie_recover-explore.adb | 1875 ---------
 ...wisitoken-parse-lr-mckenzie_recover-explore.ads |   28 -
 .../wisitoken-parse-lr-mckenzie_recover-parse.adb  |  327 --
 .../wisitoken-parse-lr-mckenzie_recover-parse.ads  |   83 -
 .../wisi/wisitoken-parse-lr-mckenzie_recover.adb   | 1306 ------
 .../wisi/wisitoken-parse-lr-mckenzie_recover.ads   |  310 --
 packages/wisi/wisitoken-parse-lr-parser.adb        | 1256 ------
 packages/wisi/wisitoken-parse-lr-parser.ads        |  162 -
 packages/wisi/wisitoken-parse-lr-parser_lists.adb  |  416 --
 packages/wisi/wisitoken-parse-lr-parser_lists.ads  |  274 --
 .../wisi/wisitoken-parse-lr-parser_no_recover.adb  |  574 ---
 .../wisi/wisitoken-parse-lr-parser_no_recover.ads  |   92 -
 packages/wisi/wisitoken-parse-lr.adb               |  767 ----
 packages/wisi/wisitoken-parse-lr.ads               |  698 ----
 .../wisi/wisitoken-parse-packrat-generated.adb     |   96 -
 .../wisi/wisitoken-parse-packrat-generated.ads     |   76 -
 .../wisi/wisitoken-parse-packrat-procedural.adb    |  267 --
 .../wisi/wisitoken-parse-packrat-procedural.ads    |   86 -
 packages/wisi/wisitoken-parse-packrat.adb          |   63 -
 packages/wisi/wisitoken-parse-packrat.ads          |   75 -
 packages/wisi/wisitoken-parse.adb                  |  108 -
 packages/wisi/wisitoken-parse.ads                  |   84 -
 packages/wisi/wisitoken-parse_table-mode.el        |   95 -
 packages/wisi/wisitoken-productions.adb            |   83 -
 packages/wisi/wisitoken-productions.ads            |   88 -
 packages/wisi/wisitoken-semantic_checks.adb        |  152 -
 packages/wisi/wisitoken-semantic_checks.ads        |  106 -
 packages/wisi/wisitoken-syntax_trees-lr_utils.adb  |  939 -----
 packages/wisi/wisitoken-syntax_trees-lr_utils.ads  |  475 ---
 packages/wisi/wisitoken-syntax_trees.adb           | 2111 ----------
 packages/wisi/wisitoken-syntax_trees.ads           |  805 ----
 packages/wisi/wisitoken-text_io_trace.adb          |  113 -
 packages/wisi/wisitoken-text_io_trace.ads          |   53 -
 packages/wisi/wisitoken-to_tree_sitter.adb         |  528 ---
 packages/wisi/wisitoken-user_guide.info            |  611 ---
 packages/wisi/wisitoken-wisi_ada.adb               |  160 -
 packages/wisi/wisitoken-wisi_ada.ads               |   81 -
 packages/wisi/wisitoken.adb                        |  367 --
 packages/wisi/wisitoken.ads                        |  508 ---
 packages/wisi/wisitoken_grammar_actions.adb        |  182 -
 packages/wisi/wisitoken_grammar_actions.ads        |  237 --
 packages/wisi/wisitoken_grammar_main.adb           |  662 ---
 packages/wisi/wisitoken_grammar_main.ads           |   34 -
 packages/wisi/wisitoken_grammar_re2c.c             | 4303 --------------------
 packages/wisi/wisitoken_grammar_re2c_c.ads         |   63 -
 packages/wisi/wisitoken_grammar_runtime.adb        | 3442 ----------------
 packages/wisi/wisitoken_grammar_runtime.ads        |  166 -
 191 files changed, 1 insertion(+), 61364 deletions(-)

diff --git a/externals-list b/externals-list
index 4fbb1b9..1e25d68 100644
--- a/externals-list
+++ b/externals-list
@@ -179,6 +179,7 @@
  ("webfeeder"          :external 
"https://gitlab.com/ambrevar/emacs-webfeeder.git";)
  ("websocket"          :external 
"https://github.com/ahyatt/emacs-websocket.git";)
  ("windower"           :external "https://gitlab.com/ambrevar/emacs-windower";)
+ ("wisi" :external nil)
  ("wisitoken-grammar-mode" :external nil)
  ("which-key"           :external "https://github.com/justbur/emacs-which-key";)
  ("wpuzzle" :external nil)
diff --git a/packages/wisi/NEWS b/packages/wisi/NEWS
deleted file mode 100644
index 621c257..0000000
--- a/packages/wisi/NEWS
+++ /dev/null
@@ -1,303 +0,0 @@
-GNU Emacs wisi NEWS -- history of user-visible changes.
-
-Copyright (C) 2014 - 2020 Free Software Foundation, Inc.
-
-Please send wisi bug reports to bug-gnu-emacs@gnu.org, with
-'wisi' in the subject. If possible, use M-x report-emacs-bug.
-
-
-* wisi 3.1.2
-4 Jun 2020
-
-** New dispatching function wisi-xref-completion-delim-regex for
-   setting completion delimiters; example use in gpr-query.el.
-
-** wisi-get-identifier (used by wisi-goto-spec/body and others) sets
-   completion delimiters using wisi-xref-completion-delim-regex.
-
-** A bug in wisi-before-change is fixed; it was missing many buffer
-   changes, causing the parser not to be run when it should be.
-
-* wisi 3.1.1
-14 May 2020
-
-** packaging bug fix
-
-* wisi 3.1.0
-11 May 2020
-
-** Add Wisitoken.Syntax_Trees.Insert_Token, to allow using inserted
-   virtual terminals tokens in indent. Several related changes to
-   allow treating virtual terminals on par with actual terminals.
-
-** New elisp generic functions: wisi-xref-completion-table, 
wisi-xref-completion-regexp, wisi-xref-completion-at-point-table
-
-** New elisp functions: wisi-filter-table, wisi-completion-at-point, 
wisi-skel-add-token-after
-
-** wisi-get-identifier uses wisi-xref-completion-table.
-
-** wisi-prj-identifier-at-point returns (IDENT START END)
-
-** In wisi.ads: augmented tokens are no stored only in the syntax
-   tree; new functions Get_Aug_Token_Const_1, Get_Aug_Token_Const,
-   Get_Aug_Token_Var provide access to them. Parse_Data_Type contains
-   a reference to the shared Terminals.
-
-* wisi 3.0.1
-30 Jan 2020
-
-** fix packaging bugs
-
-** improve xref integration
-
-* wisi 3.0.0
-19 Dec 2019
-
-** parser process protocol version 5
-
-** Add project.el integration. See wisi.info for more information.
-
-** Move autocase functions from ada-mode to wisi.
-
-** Replace most ada-mode function variables with dispatching on wisi-prj.
-
-** New commands `wisi-goto-containing-statement-start', 
`wisi-indent-containing-statement'.
-
-** Displayed parser errors are sorted in increasing error position.
-
-* wisi 2.2.1
-17 Aug 2019
-
-** parser process protocol version 4
-
-** fix packaging bugs
-
-* wisi 2.2.0
-13 Aug 2019
-
-** parser process protocol version 3
-
-** Support for the elisp parser and lexer is deleted; only the Ada
-   process parser is supported.
-
-** New user variable `wisi-indent-context-lines' specifies the minimum
-   number of lines before point to include in a parse for indenting a
-   single line. This gives better results when indenting in a nested
-   'if then else', for example. The default value is 0; you must
-   change it to see an effect.
-
-** Error correction is faster by approximately 30%;
-   %mckenzie_enqueue_limit can be raised accordingly.
-
-** %mckenzie_enqueue_limit is now applied to the total of all parsers
-    in recovery; previously, it was applied to each parser separately.
-    Applying to the total gives a more consistent maximum user wait
-    time for recovery, at the cost of not finding solutions when there
-    are many parsers involved. You may want to increase
-    %mckenzie_enqueue_limit for this as well.
-
-** In the process parser, `wisi-statement-start' now sets 'containing'
-   in all contained caches to the start token, if not set already;
-   previously it only did this if the token was mentioned in the
-   `wisi-statement-start' action. This makes `wisi-containing-action'
-   unnecessary.
-
-** `wisi-containing-action' is deleted.
-
-** An argument of `wisi-motion-action' that is a vector may now
-   provide only one token ID. That token ID is searched for in the
-   containing token region, and the motion token chain starting at the
-   first one found is included in the current right hand side motion
-   token chain.
-
-** The process parser supports a new parse command `wisi-refactor',
-   which returns a new message "Edit". It is intended for performing
-   syntax-guided refactoring of code statements.
-
-* wisi 2.1.1
-11 Jul 2019
-
-** parser process protocol version 3
-
-** User variable wisi-mckenzie-cost-limit is deleted; set
-   wisi-mckenzie-enqueue-limit instead, it gives better results.
-
-** `wisi-show-parse-errors' now shows errors in a dedicated window, so
-   it will not be resized or reused.
-
-** New grammar action `wisi-name-action'; sets a name that will be
-   fontified. This replaces the previous 'name' navigate class.
-
-** Support 'nil' as an indent argument; useful for the first token,
-   whose indent is typically unknown. Indent functions that do not
-   accumulate now only check for "nil", not "zero or nil".
-
-** New file wisi-xref.el provides a completion table built from tokens
-   marked by the new grammar action `wisi-name-action'.
-
-** The process parser checks the parser process protocol version, to
-   ensure the elisp code matches the process code.
-
-** The process parser supports passing data to a language-specific
-   elisp function, via the `language-action-table' field of the
-   `wisi-process--parser' struct.
-
-** New user option `wisi-parse-max-parallel' to set the number of
-   parallel parsers used; Java needs more than Ada.
-
-* wisi 2.1.0
-21 Mar 2019
-
-** parser process protocol version 2
-
-** Add support for partial parsing; useful in very large files. Files
-   larger than wisi-partial-parse-threshold (default 100_001) will be
-   parsed partially.
-
-** Miscellaneous speed-ups in the Ada code; 'pragma Inline', better use of Ada 
tasks.
-
-** Better error correction in the Ada process parser; insert minimimal
-  tokens to complete a statement/declaration before or after the error
-  point.
-
-* wisi 2.0.1
-8 Dec 2018
-
-** parser process protocol version 1
-
-** Assign copyright in Ada files to FSF
-
-** Update user guide, include it in elpa package
-
-* wisi 2.0.0
-17 Nov 2018
-
-** Change indentation engine to compute indent directly in parser actions.
-
-** Add error correcting external process parser.
-
-** Factor out wisi-elisp-lexer.el from wisi.el, and
-   ada-wisi-elisp-parse.el from ada-wisi.el. Move elisp grammar
-   actions from wisi.el to wisi-elisp-parse.el; they are not used with
-   the process parser.
-
-** Add support for error corrections in parser; 'wisi-repair-error'
-   can apply the corrections to the buffer text.
-
-** Display marks in fringe at location of errors detected by
-   background parser.
-
-** include sources for wisitoken parser runtime, parser generator.
-
-* wisi 1.1.6
-3 Oct 2017
-
-** wisi-forward-find-cache-token - new function.
-
-** New minor-mode parse_table-mode helps navigating parse table
-   listings output by 'wisi-generate -v 1'; useful when debugging
-   grammars.
-
-* wisi 1.1.5
-9 Jul 2017
-
-** wisi-indent-fallback allows setting the indent engine to use when
-   the wisi engine fails.
-
-** wisi-comment-indent now uses comment-column for comments following
-   code on the same line.
-
-** wisi-forward-statement-keyword tolerates end of buffer, and uses
-   either cache-next or cache-end.
-
-** forward-sexp-function is set to wisi-forward-sexp, which handles
-   parens, strings, and statements.
-
-* wisi 1.1.4
-31 Oct 2016
-
-** wisi-validate-cache takes optional error-on-fail arg.
-
-* wisi 1.1.3
-26 Jul 2016
-
-** improve use of quotes in doc strings.
-
-* wisi 1.1.2
-20 Jan 2016
-
-** wisi-compile no longer requires semantic.
-
-** wisi-parse slightly faster
-
-** minor bug fixes
-
-** wisi-extend-action now takes two args (first last)
-
-** wisi-face-action-1 optional arg no-override is replaced by 
override-no-error.
-
-* wisi 1.1.1
-10 Apr 2015
-
-** rename wisi-font-lock-size-threshold to wisi-size-threshold, use
-   for more things in ada-mode
-
-* wisi 1.1.0
-18 Nov 2014
-
-** change wisi-forward-token to not return text; simpler, faster
-
-** remove face from wisi-cache; set font-lock-face property directly.
-
-** add support for numeric literal tokens.
-
-** change wisi-*-action to take a vector of arguments; faster for
-   external parser, catches more errors.
-
-** add wisi-font-lock-size-threshold
-
-* wisi 1.0.6
-28 Sep 2014
-
-** add face to wisi-cache
-
-** wisi-before/after-change : improve checks for invalidate-cache
-
-** wisi-motion-action takes class with each token-id
-
-** new parse actions: wisi-extend-action, wisi-face-action
-
-** new functions: wisi-goto-statement-start, -end.
-
-** fix misc bugs
-
-* wisi 1.0.5
-12 Jul 2014
-
-** wisi-parse-max-parallel-current - new variable for debugging slow parsing 
issues
-
-** wisi-set-end - new algorithm giving significant speedup
-
-* wisi 1.0.4
-19 Apr 2014
-
-** add support for GNAT Ada bracket hex character notation
-
-* wisi 1.0.3
-16 Mar 2014
-
-** fix another packaging bug; forgot to add files to ELPA git!
-
-* wisi 1.0.2
-14 Mar 2014
-
-** Emacs 24.2 supported, via cl-lib in Gnu ELPA
-
-* wisi 1.0.1
-
-** minor fixes for byte compiler warnings
-
-* wisi 1.0
-Feb 2 2014
-
-** first release in ELPA
diff --git a/packages/wisi/README b/packages/wisi/README
deleted file mode 100644
index 5898d91..0000000
--- a/packages/wisi/README
+++ /dev/null
@@ -1,14 +0,0 @@
-Emacs wisi package 3.1.2
-
-The wisi package provides utilities for using generalized
-error-correcting LR parsers (in external processes) to do indentation,
-fontification, and navigation; and integration with Emacs package.el.
-See ada-mode for an example of its use.
-
-It also provides wisitoken-parse_table-mode, for navigating the
-diagnostic parse tables output by wisitoken-bnf-generate.
-
-The generated code is in Ada; it requires the AdaCore gnat compiler
-that you may not have installed. It is available in many packaging
-systems, or as a binary download from
-https://www.adacore.com/download.
diff --git a/packages/wisi/build-wisitoken-bnf-generate.sh 
b/packages/wisi/build-wisitoken-bnf-generate.sh
deleted file mode 100755
index faa4094..0000000
--- a/packages/wisi/build-wisitoken-bnf-generate.sh
+++ /dev/null
@@ -1,7 +0,0 @@
-# Build wisitoken-bnf-generate.exe, for generating code from grammar files.
-# 
-# Instead of using this, you should consider using the complete
-# wisitoken development tree; see
-# http://stephe-leake.org/ada/wisitoken.html
-
-gprbuild -p -j8 -P wisi.gpr wisitoken-bnf-generate
diff --git a/packages/wisi/dir b/packages/wisi/dir
deleted file mode 100644
index fbc9cbb..0000000
--- a/packages/wisi/dir
+++ /dev/null
@@ -1,19 +0,0 @@
-This is the file .../info/dir, which contains the
-topmost node of the Info hierarchy, called (dir)Top.
-The first time you invoke Info you start off looking at this node.
-
-File: dir,     Node: Top       This is the top of the INFO tree
-
-  This (the Directory node) gives a menu of major topics.
-  Typing "q" exits, "H" lists all Info commands, "d" returns here,
-  "h" gives a primer for first-timers,
-  "mEmacs<Return>" visits the Emacs manual, etc.
-
-  In Emacs, you can click mouse button 2 on a menu item or cross reference
-  to select it.
-
-* Menu:
-
-Parser generators
-* wisitoken-bnf-generate: (wisitoken-bnf-generate).
-                                Ada and Elisp parser generator
diff --git a/packages/wisi/emacs_wisi_common_parse.adb 
b/packages/wisi/emacs_wisi_common_parse.adb
deleted file mode 100644
index 59d20e5..0000000
--- a/packages/wisi/emacs_wisi_common_parse.adb
+++ /dev/null
@@ -1,508 +0,0 @@
---  Abstract :
---
---  See spec.
---
---  Copyright (C) 2018 - 2020 Free Software Foundation, Inc.
---
---  This program is free software; you can redistribute it and/or
---  modify it under terms of the GNU General Public License as
---  published by the Free Software Foundation; either version 3, 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
---  distributed with this program; see file COPYING. If not, write to
---  the Free Software Foundation, 51 Franklin Street, Suite 500, Boston,
---  MA 02110-1335, USA.
-
-pragma License (GPL);
-
-with Ada.Command_Line;
-with Ada.Directories;
-with Ada.Exceptions;
-with Ada.Strings.Fixed;
-with Ada.Text_IO;
-with GNAT.OS_Lib;
-with SAL;
-with System.Multiprocessors;
-with System.Storage_Elements;
-with WisiToken.Lexer;
-package body Emacs_Wisi_Common_Parse is
-
-   procedure Usage (Name : in String)
-   is
-      use Ada.Text_IO;
-   begin
-      Put_Line ("usage: " & Name & "[--recover-log <file-name>]");
-      Put_Line ("enters a loop waiting for commands:");
-      Put_Line ("Prompt is '" & Prompt & "'");
-      Put_Line ("commands are case sensitive");
-      Put_Line ("See wisi-process-parse.el *--send-parse, *--send-noop for 
arguments.");
-   end Usage;
-
-   procedure Read_Input (A : System.Address; N : Integer)
-   is
-      use System.Storage_Elements;
-
-      B         : System.Address := A;
-      Remaining : Integer        := N;
-      Read      : Integer;
-   begin
-      --  We use GNAT.OS_Lib because it does not buffer input, so it runs
-      --  under Emacs nicely; GNAT Text_IO does not return text until
-      --  some fairly large buffer is filled.
-      --
-      --  With GNAT GPL 2016, GNAT.OS_Lib.Read does _not_ wait for all N
-      --  bytes or EOF; it returns as soon as it gets some bytes.
-      loop
-         Read := GNAT.OS_Lib.Read (GNAT.OS_Lib.Standin, B, Remaining);
-         if Read = 0 then
-            --  Pipe closed; probably parent Emacs crashed. Force exit.
-            raise SAL.Programmer_Error with "input pipe closed";
-         end if;
-         Remaining := Remaining - Read;
-         exit when Remaining <= 0;
-         B := B + Storage_Offset (Read);
-      end loop;
-   end Read_Input;
-
-   function Get_Command_Length return Integer
-   is
-      Temp : aliased String (1 .. 3) := (others => ' '); -- initialize for 
error message
-   begin
-      Read_Input (Temp'Address, Temp'Length);
-      return Integer'Value (Temp);
-   exception
-   when Constraint_Error =>
-      --  From Integer'Value
-      raise Protocol_Error with "invalid command byte count; '" & Temp & "'";
-   end Get_Command_Length;
-
-   function Get_String
-     (Source : in     String;
-      Last   : in out Integer)
-     return String
-   is
-      use Ada.Strings.Fixed;
-      First : constant Integer := Index
-        (Source  => Source,
-         Pattern => """",
-         From    => Last + 1);
-   begin
-      Last := Index
-        (Source  => Source,
-         Pattern => """",
-         From    => First + 1);
-
-      if First = 0 or Last = 0 then
-         raise Protocol_Error with "no '""' found for string";
-      end if;
-
-      return Source (First + 1 .. Last - 1);
-   end Get_String;
-
-   function Get_Integer
-     (Source : in     String;
-      Last   : in out Integer)
-     return Integer
-   is
-      use Ada.Strings.Fixed;
-      First : constant Integer := Last + 2; -- final char of previous item, 
space
-   begin
-      Last := Index
-        (Source  => Source,
-         Pattern => " ",
-         From    => First);
-
-      if Last = 0 then
-         Last := Source'Last;
-      else
-         Last := Last - 1;
-      end if;
-
-      return Integer'Value (Source (First .. Last));
-   exception
-   when others =>
-      Ada.Text_IO.Put_Line ("bad integer '" & Source (First .. Source'Last) & 
"'");
-      raise;
-   end Get_Integer;
-
-   function Get_Process_Start_Params return Process_Start_Params
-   is
-      use Ada.Command_Line;
-      procedure Put_Usage
-      is
-         use Ada.Text_IO;
-      begin
-         Put_Line (Standard_Error, "process start args:");
-         Put_Line (Standard_Error, "--help : put this help");
-         Put_Line (Standard_Error, "--recover-log <file_name> : log recover 
actions to file");
-      end Put_Usage;
-
-      Next_Arg : Integer := 1;
-   begin
-      return Result : Process_Start_Params do
-         loop
-            exit when Next_Arg > Argument_Count;
-
-            if Next_Arg <= Argument_Count and then Argument (Next_Arg) = 
"--help" then
-               Put_Usage;
-               raise Finish;
-
-            elsif Next_Arg + 1 <= Argument_Count and then Argument (Next_Arg) 
= "--recover-log" then
-               Result.Recover_Log_File_Name := 
Ada.Strings.Unbounded.To_Unbounded_String (Argument (Next_Arg + 1));
-               Next_Arg := Next_Arg + 2;
-            end if;
-         end loop;
-      end return;
-   end Get_Process_Start_Params;
-
-   function Get_Parse_Params (Command_Line : in String; Last : in out Integer) 
return Parse_Params
-   is
-      use WisiToken;
-   begin
-      return Result : Parse_Params do
-         --  We don't use an aggregate, to enforce execution order.
-         --  Match wisi-process-parse.el wisi-process--send-parse
-
-         Result.Post_Parse_Action    := Wisi.Post_Parse_Action_Type'Val 
(Get_Integer (Command_Line, Last));
-         Result.Source_File_Name     := +Get_String (Command_Line, Last);
-         Result.Begin_Byte_Pos       := Get_Integer (Command_Line, Last);
-
-         --  Emacs end is after last char.
-         Result.End_Byte_Pos         := Get_Integer (Command_Line, Last) - 1;
-
-         Result.Goal_Byte_Pos        := Get_Integer (Command_Line, Last);
-         Result.Begin_Char_Pos       := WisiToken.Buffer_Pos (Get_Integer 
(Command_Line, Last));
-         Result.Begin_Line           := WisiToken.Line_Number_Type 
(Get_Integer (Command_Line, Last));
-         Result.End_Line             := WisiToken.Line_Number_Type 
(Get_Integer (Command_Line, Last));
-         Result.Begin_Indent         := Get_Integer (Command_Line, Last);
-         Result.Partial_Parse_Active := 1 = Get_Integer (Command_Line, Last);
-         Result.Debug_Mode           := 1 = Get_Integer (Command_Line, Last);
-         Result.Parse_Verbosity      := Get_Integer (Command_Line, Last);
-         Result.McKenzie_Verbosity   := Get_Integer (Command_Line, Last);
-         Result.Action_Verbosity     := Get_Integer (Command_Line, Last);
-         Result.McKenzie_Disable     := Get_Integer (Command_Line, Last);
-         Result.Task_Count           := Get_Integer (Command_Line, Last);
-         Result.Check_Limit          := Get_Integer (Command_Line, Last);
-         Result.Enqueue_Limit        := Get_Integer (Command_Line, Last);
-         Result.Max_Parallel         := Get_Integer (Command_Line, Last);
-         Result.Byte_Count           := Get_Integer (Command_Line, Last);
-      end return;
-   end Get_Parse_Params;
-
-   function Get_Refactor_Params (Command_Line : in String; Last : in out 
Integer) return Refactor_Params
-   is
-      use WisiToken;
-   begin
-      return Result : Refactor_Params do
-         --  We don't use an aggregate, to enforce execution order.
-         --  Match wisi-process-parse.el wisi-process--send-refactor
-
-         Result.Refactor_Action    := Get_Integer (Command_Line, Last);
-         Result.Source_File_Name   := +Get_String (Command_Line, Last);
-         Result.Parse_Region.First := WisiToken.Buffer_Pos (Get_Integer 
(Command_Line, Last));
-         Result.Parse_Region.Last  := WisiToken.Buffer_Pos (Get_Integer 
(Command_Line, Last) - 1);
-
-         Result.Edit_Begin           := WisiToken.Buffer_Pos (Get_Integer 
(Command_Line, Last));
-         Result.Parse_Begin_Char_Pos := WisiToken.Buffer_Pos (Get_Integer 
(Command_Line, Last));
-         Result.Parse_Begin_Line     := WisiToken.Line_Number_Type 
(Get_Integer (Command_Line, Last));
-         Result.Parse_End_Line       := WisiToken.Line_Number_Type 
(Get_Integer (Command_Line, Last));
-         Result.Parse_Begin_Indent   := Get_Integer (Command_Line, Last);
-         Result.Debug_Mode           := 1 = Get_Integer (Command_Line, Last);
-         Result.Parse_Verbosity      := Get_Integer (Command_Line, Last);
-         Result.Action_Verbosity     := Get_Integer (Command_Line, Last);
-         Result.Max_Parallel         := Get_Integer (Command_Line, Last);
-         Result.Byte_Count           := Get_Integer (Command_Line, Last);
-      end return;
-   end Get_Refactor_Params;
-
-   procedure Process_Stream
-     (Name                      : in     String;
-      Language_Protocol_Version : in     String;
-      Partial_Parse_Active      : in out Boolean;
-      Params                    : in     Process_Start_Params;
-      Parser                    : in out WisiToken.Parse.LR.Parser.Parser;
-      Parse_Data                : in out Wisi.Parse_Data_Type'Class;
-      Descriptor                : in     WisiToken.Descriptor)
-   is
-      use Ada.Text_IO;
-      use WisiToken; -- "+", "-" Unbounded_string
-
-      procedure Cleanup
-      is begin
-         if Is_Open (Parser.Recover_Log_File) then
-            Close (Parser.Recover_Log_File);
-         end if;
-      end Cleanup;
-
-   begin
-      declare
-         use Ada.Directories;
-         use Ada.Strings.Unbounded;
-      begin
-         if Length (Params.Recover_Log_File_Name) > 0 then
-            Put_Line (";; logging to '" & (-Params.Recover_Log_File_Name) & 
"'");
-            --  to Current_Output, visible from Emacs
-
-            if Exists (-Params.Recover_Log_File_Name) then
-               Open (Parser.Recover_Log_File, Append_File, 
-Params.Recover_Log_File_Name);
-            else
-               Create (Parser.Recover_Log_File, Out_File, 
-Params.Recover_Log_File_Name);
-            end if;
-         end if;
-      end;
-
-      Parser.Trace.Set_Prefix (";; "); -- so debug messages don't confuse 
Emacs.
-
-      Put_Line
-        (Name & " protocol: process version " & Protocol_Version & " language 
version " & Language_Protocol_Version);
-
-      --  Read commands and tokens from standard_input via GNAT.OS_Lib,
-      --  send results to standard_output.
-      loop
-         Put (Prompt); Flush;
-         declare
-            Command_Length : constant Integer := Get_Command_Length;
-            Command_Line   : aliased String (1 .. Command_Length);
-            Last           : Integer;
-
-            function Match (Target : in String) return Boolean
-            is begin
-               Last := Command_Line'First + Target'Length - 1;
-               return Last <= Command_Line'Last and then Command_Line 
(Command_Line'First .. Last) = Target;
-            end Match;
-         begin
-            Read_Input (Command_Line'Address, Command_Length);
-
-            Put_Line (";; " & Command_Line);
-
-            if Match ("parse") then
-               --  Args: see wisi-process-parse.el 
wisi-process-parse--send-parse
-               --  Input: <source text>
-               --  Response:
-               --  [response elisp vector]...
-               --  [elisp error form]...
-               --  prompt
-               declare
-                  Params : constant Parse_Params := Get_Parse_Params 
(Command_Line, Last);
-                  Buffer : Ada.Strings.Unbounded.String_Access;
-
-                  procedure Clean_Up
-                  is
-                     use all type SAL.Base_Peek_Type;
-                  begin
-                     Parser.Lexer.Discard_Rest_Of_Input;
-                     if Parser.Parsers.Count > 0 then
-                        Parse_Data.Put
-                          (Parser.Lexer.Errors,
-                           Parser.Parsers.First.State_Ref.Errors,
-                           Parser.Parsers.First.State_Ref.Tree);
-                     end if;
-                     Ada.Strings.Unbounded.Free (Buffer);
-                  end Clean_Up;
-
-               begin
-                  Trace_Parse    := Params.Parse_Verbosity;
-                  Trace_McKenzie := Params.McKenzie_Verbosity;
-                  Trace_Action   := Params.Action_Verbosity;
-                  Debug_Mode     := Params.Debug_Mode;
-
-                  Partial_Parse_Active        := Params.Partial_Parse_Active;
-                  Parser.Partial_Parse_Active := Params.Partial_Parse_Active;
-
-                  if WisiToken.Parse.LR.McKenzie_Defaulted (Parser.Table.all) 
then
-                     --  There is no McKenzie information; don't override that.
-                     null;
-                  elsif Params.McKenzie_Disable = -1 then
-                     --  Use default
-                     Parser.Enable_McKenzie_Recover := True;
-                  else
-                     Parser.Enable_McKenzie_Recover := Params.McKenzie_Disable 
= 0;
-                  end if;
-
-                  Parse_Data.Initialize
-                    (Post_Parse_Action => Params.Post_Parse_Action,
-                     Lexer             => Parser.Lexer,
-                     Descriptor        => Descriptor'Unrestricted_Access,
-                     Base_Terminals    => Parser.Terminals'Unrestricted_Access,
-                     Begin_Line        => Params.Begin_Line,
-                     End_Line          => Params.End_Line,
-                     Begin_Indent      => Params.Begin_Indent,
-                     Params            => Command_Line (Last + 2 .. 
Command_Line'Last));
-
-                  if Params.Task_Count > 0 then
-                     Parser.Table.McKenzie_Param.Task_Count := 
System.Multiprocessors.CPU_Range (Params.Task_Count);
-                  end if;
-                  if Params.Check_Limit > 0 then
-                     Parser.Table.McKenzie_Param.Check_Limit := 
Base_Token_Index (Params.Check_Limit);
-                  end if;
-                  if Params.Enqueue_Limit > 0 then
-                     Parser.Table.McKenzie_Param.Enqueue_Limit := 
Params.Enqueue_Limit;
-                  end if;
-
-                  if Params.Max_Parallel > 0 then
-                     Parser.Max_Parallel := SAL.Base_Peek_Type 
(Params.Max_Parallel);
-                  end if;
-
-                  Buffer := new String (Params.Begin_Byte_Pos .. 
Params.End_Byte_Pos);
-
-                  Read_Input (Buffer (Params.Begin_Byte_Pos)'Address, 
Params.Byte_Count);
-
-                  Parser.Lexer.Reset_With_String_Access
-                    (Buffer, Params.Source_File_Name, Params.Begin_Char_Pos, 
Params.Begin_Line);
-
-                  --  Parser.Line_Begin_Token First, Last set by Lex_All
-                  begin
-                     Parser.Parse;
-                  exception
-                  when WisiToken.Partial_Parse =>
-                     null;
-                  end;
-                  Parser.Execute_Actions;
-                  Parse_Data.Put (Parser);
-                  Clean_Up;
-
-               exception
-               when Syntax_Error =>
-                  Clean_Up;
-                  Put_Line ("(parse_error)");
-
-               when E : Parse_Error =>
-                  Clean_Up;
-                  Put_Line ("(parse_error """ & 
Ada.Exceptions.Exception_Message (E) & """)");
-
-               when E : Fatal_Error =>
-                  Clean_Up;
-                  Put_Line ("(error """ & Ada.Exceptions.Exception_Message (E) 
& """)");
-               end;
-
-            elsif Match ("refactor") then
-               --  Args: see wisi-process-parse.el 
wisi-process-parse--send-refactor
-               --  Input: <source text>
-               --  Response:
-               --  [edit elisp vector]...
-               --  prompt
-               declare
-                  Params : constant Refactor_Params := Get_Refactor_Params 
(Command_Line, Last);
-                  Buffer : Ada.Strings.Unbounded.String_Access;
-
-                  procedure Clean_Up
-                  is
-                     use all type SAL.Base_Peek_Type;
-                  begin
-                     Parser.Lexer.Discard_Rest_Of_Input;
-                     if Parser.Parsers.Count > 0 then
-                        Parse_Data.Put
-                          (Parser.Lexer.Errors,
-                           Parser.Parsers.First.State_Ref.Errors,
-                           Parser.Parsers.First.State_Ref.Tree);
-                     end if;
-                     Ada.Strings.Unbounded.Free (Buffer);
-                  end Clean_Up;
-
-               begin
-                  Trace_Parse  := Params.Parse_Verbosity;
-                  Trace_Action := Params.Action_Verbosity;
-                  Debug_Mode   := Params.Debug_Mode;
-
-                  Partial_Parse_Active := True;
-
-                  Parse_Data.Initialize
-                    (Post_Parse_Action => Wisi.Navigate, -- mostly ignored
-                     Lexer             => Parser.Lexer,
-                     Descriptor        => Descriptor'Unrestricted_Access,
-                     Base_Terminals    => Parser.Terminals'Unrestricted_Access,
-                     Begin_Line        => Params.Parse_Begin_Line,
-                     End_Line          => Params.Parse_End_Line,
-                     Begin_Indent      => Params.Parse_Begin_Indent,
-                     Params            => "");
-
-                  if Params.Max_Parallel > 0 then
-                     Parser.Max_Parallel := SAL.Base_Peek_Type 
(Params.Max_Parallel);
-                  end if;
-
-                  Buffer := new String (Integer (Params.Parse_Region.First) .. 
Integer (Params.Parse_Region.Last));
-
-                  Read_Input (Buffer (Buffer'First)'Address, 
Params.Byte_Count);
-
-                  Parser.Lexer.Reset_With_String_Access
-                    (Buffer, Params.Source_File_Name, 
Params.Parse_Begin_Char_Pos, Params.Parse_Begin_Line);
-                  begin
-                     Parser.Parse;
-                  exception
-                  when WisiToken.Partial_Parse =>
-                     null;
-                  end;
-                  Parser.Execute_Actions;
-                  Parse_Data.Refactor (Parser.Parsers.First_State_Ref.Tree, 
Params.Refactor_Action, Params.Edit_Begin);
-                  Clean_Up;
-
-               exception
-               when Syntax_Error =>
-                  Clean_Up;
-                  Put_Line ("(parse_error ""refactor " & 
Params.Parse_Region.First'Image &
-                              Params.Parse_Region.Last'Image & ": syntax 
error"")");
-
-               when E : Parse_Error =>
-                  Clean_Up;
-                  Put_Line ("(parse_error ""refactor " & 
Params.Parse_Region.First'Image &
-                              Params.Parse_Region.Last'Image & ": " & 
Ada.Exceptions.Exception_Message (E) & """)");
-
-               when E : others => -- includes Fatal_Error
-                  Clean_Up;
-                  Put_Line ("(error """ & Ada.Exceptions.Exception_Message (E) 
& """)");
-               end;
-
-            elsif Match ("noop") then
-               --  Args: <source byte count>
-               --  Input: <source text>
-               --  Response: prompt
-               declare
-                  Byte_Count  : constant Integer                             
:= Get_Integer (Command_Line, Last);
-                  Buffer      : constant Ada.Strings.Unbounded.String_Access 
:= new String (1 .. Byte_Count);
-                  Token       : Base_Token;
-                  Lexer_Error : Boolean;
-                  pragma Unreferenced (Lexer_Error);
-               begin
-                  Token.ID := Invalid_Token_ID;
-                  Read_Input (Buffer (1)'Address, Byte_Count);
-
-                  Parser.Lexer.Reset_With_String_Access (Buffer, +"");
-                  loop
-                     exit when Token.ID = Parser.Trace.Descriptor.EOI_ID;
-                     Lexer_Error := Parser.Lexer.Find_Next (Token);
-                  end loop;
-               exception
-               when Syntax_Error =>
-                  Parser.Lexer.Discard_Rest_Of_Input;
-               end;
-
-            elsif Match ("quit") then
-               exit;
-
-            else
-               Put_Line ("(error ""bad command: '" & Command_Line & "'"")");
-            end if;
-         exception
-         when E : Protocol_Error =>
-            --  don't exit the loop; allow debugging bad elisp
-            Put_Line ("(error ""protocol error "": " & 
Ada.Exceptions.Exception_Message (E) & """)");
-         end;
-      end loop;
-      Cleanup;
-   exception
-   when Finish =>
-      null;
-
-   when E : others =>
-      Cleanup;
-      Ada.Command_Line.Set_Exit_Status (Ada.Command_Line.Failure);
-      New_Line (2);
-      Put_Line
-        ("(error ""unhandled exception: " & Ada.Exceptions.Exception_Name (E) 
& ": " &
-           Ada.Exceptions.Exception_Message (E) & """)");
-   end Process_Stream;
-
-end Emacs_Wisi_Common_Parse;
diff --git a/packages/wisi/emacs_wisi_common_parse.ads 
b/packages/wisi/emacs_wisi_common_parse.ads
deleted file mode 100644
index e646eba..0000000
--- a/packages/wisi/emacs_wisi_common_parse.ads
+++ /dev/null
@@ -1,157 +0,0 @@
---  Abstract :
---
---  Common utilities for Gen_Emacs_Wisi_*_Parse
---
---  Copyright (C) 2018 - 2019 Free Software Foundation, Inc.
---
---  This program is free software; you can redistribute it and/or
---  modify it under terms of the GNU General Public License as
---  published by the Free Software Foundation; either version 3, 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
---  distributed with this program; see file COPYING. If not, write to
---  the Free Software Foundation, 51 Franklin Street, Suite 500, Boston,
---  MA 02110-1335, USA.
-
-pragma License (GPL);
-
-with Ada.Strings.Unbounded;
-with System;
-with Wisi;
-with WisiToken.Parse.LR.Parser;
-package Emacs_Wisi_Common_Parse is
-
-   Protocol_Version : constant String := "5";
-   --  Protocol_Version defines the data sent between elisp and the
-   --  background process, except for the language-specific parameters,
-   --  which are defined by the Language_Protocol_Version parameter to
-   --  Parse_Stream, below.
-   --
-   --  This value must match wisi-process-parse.el
-   --  wisi-process-parse-protocol-version.
-   --
-   --  See wisi-process-parse.el functions, and this package body, for
-   --  the implementation of the protocol.
-   --
-   --  Only changes once per wisi release. Increment as soon as required,
-   --  record new version in NEWS-wisi.text.
-
-   Prompt : constant String := ";;> ";
-
-   Protocol_Error : exception;
-   Finish         : exception;
-
-   procedure Usage (Name : in String);
-
-   procedure Read_Input (A : System.Address; N : Integer);
-
-   function Get_Command_Length return Integer;
-
-   function Get_String
-     (Source : in     String;
-      Last   : in out Integer)
-     return String;
-
-   function Get_Integer
-     (Source : in     String;
-      Last   : in out Integer)
-     return Integer;
-
-   type Process_Start_Params is record
-      Recover_Log_File_Name : Ada.Strings.Unbounded.Unbounded_String;
-      --  log enabled if non-empty.
-   end record;
-
-   function Get_Process_Start_Params return Process_Start_Params;
-   --  Get from Ada.Command_Line. Handles --help by outputing help,
-   --  raising Finish.
-
-   procedure Process_Stream
-     (Name                      : in     String;
-      Language_Protocol_Version : in     String;
-      Partial_Parse_Active      : in out Boolean;
-      Params                    : in     Process_Start_Params;
-      Parser                    : in out WisiToken.Parse.LR.Parser.Parser;
-      Parse_Data                : in out Wisi.Parse_Data_Type'Class;
-      Descriptor                : in     WisiToken.Descriptor);
-
-   ----------
-   --  Parse command
-
-   type Parse_Params is record
-      Post_Parse_Action : Wisi.Post_Parse_Action_Type;
-      Source_File_Name  : Ada.Strings.Unbounded.Unbounded_String;
-
-      Begin_Byte_Pos : Integer;
-      --  Source file byte position of first char sent; start parse here.
-
-      End_Byte_Pos : Integer;
-      --  Byte position of last char sent.
-
-      Goal_Byte_Pos : Integer;
-      --  Byte position of end of desired parse region; terminate parse at
-      --  or after here.
-
-      Begin_Char_Pos : WisiToken.Buffer_Pos;
-      --  Char position of first char sent.
-
-      Begin_Line : WisiToken.Line_Number_Type;
-      End_Line   : WisiToken.Line_Number_Type;
-      --  Line number of line containing Begin_Byte_Pos, End_Byte_Pos
-
-      Begin_Indent : Integer;
-      --  Indentation of Line_Begin
-
-      Partial_Parse_Active : Boolean;
-      Debug_Mode           : Boolean;
-      Parse_Verbosity      : Integer;
-      McKenzie_Verbosity   : Integer;
-      Action_Verbosity     : Integer;
-      McKenzie_Disable     : Integer;
-      Task_Count           : Integer;
-      Check_Limit          : Integer;
-      Enqueue_Limit        : Integer;
-      Max_Parallel         : Integer;
-      Byte_Count           : Integer;
-      --  Count of bytes of source file sent.
-   end record;
-
-   function Get_Parse_Params (Command_Line : in String; Last : in out Integer) 
return Parse_Params;
-
-   ----------
-   --  Refactor command
-
-   type Refactor_Params is record
-      Refactor_Action  : Positive; -- Language-specific
-      Source_File_Name : Ada.Strings.Unbounded.Unbounded_String;
-
-      Parse_Region : WisiToken.Buffer_Region;
-      --  Source file byte region to parse.
-
-      Edit_Begin : WisiToken.Buffer_Pos;
-      --  Source file byte position at start of expression to refactor.
-
-      Parse_Begin_Char_Pos : WisiToken.Buffer_Pos;
-      --  Char position of first char sent.
-
-      Parse_Begin_Line : WisiToken.Line_Number_Type;
-      Parse_End_Line   : WisiToken.Line_Number_Type;
-      --  Line numbers of lines containing Parse_Begin_Byte_Pos, 
Parse_End_Byte_Pos
-
-      Parse_Begin_Indent : Integer;
-      --  Indentation of Parse_Begin_Line
-
-      Debug_Mode       : Boolean;
-      Parse_Verbosity  : Integer;
-      Action_Verbosity : Integer;
-      Max_Parallel     : Integer;
-      Byte_Count       : Integer;
-      --  Count of bytes of source file sent.
-   end record;
-
-   function Get_Refactor_Params (Command_Line : in String; Last : in out 
Integer) return Refactor_Params;
-
-end Emacs_Wisi_Common_Parse;
diff --git a/packages/wisi/gen_emacs_wisi_lr_parse.adb 
b/packages/wisi/gen_emacs_wisi_lr_parse.adb
deleted file mode 100644
index 0f81868..0000000
--- a/packages/wisi/gen_emacs_wisi_lr_parse.adb
+++ /dev/null
@@ -1,39 +0,0 @@
---  Abstract :
---
---  See spec.
---
---  Copyright (C) 2014, 2017 - 2020 All Rights Reserved.
---
---  This program is free software; you can redistribute it and/or
---  modify it under terms of the GNU General Public License as
---  published by the Free Software Foundation; either version 3, 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
---  distributed with this program; see file COPYING. If not, write to
---  the Free Software Foundation, 51 Franklin Street, Suite 500, Boston,
---  MA 02110-1335, USA.
-
-pragma License (GPL);
-
-with Emacs_Wisi_Common_Parse; use Emacs_Wisi_Common_Parse;
-with WisiToken.Parse.LR.Parser;
-with WisiToken.Text_IO_Trace;
-procedure Gen_Emacs_Wisi_LR_Parse
-is
-   Trace      : aliased WisiToken.Text_IO_Trace.Trace 
(Descriptor'Unrestricted_Access);
-   Parser     : WisiToken.Parse.LR.Parser.Parser;
-   Parse_Data : aliased Parse_Data_Type (Parser.Terminals'Access, 
Parser.Line_Begin_Token'Access);
-
-   Params : constant Process_Start_Params := Get_Process_Start_Params;
-begin
-   Create_Parser
-     (Parser, Language_Fixes, Language_Matching_Begin_Tokens, 
Language_String_ID_Set,
-      Trace'Unrestricted_Access,
-      Parse_Data'Unchecked_Access);
-
-   Process_Stream (Name, Language_Protocol_Version, Partial_Parse_Active, 
Params, Parser, Parse_Data, Descriptor);
-
-end Gen_Emacs_Wisi_LR_Parse;
diff --git a/packages/wisi/gen_emacs_wisi_lr_parse.ads 
b/packages/wisi/gen_emacs_wisi_lr_parse.ads
deleted file mode 100644
index 02eac21..0000000
--- a/packages/wisi/gen_emacs_wisi_lr_parse.ads
+++ /dev/null
@@ -1,55 +0,0 @@
---  Abstract :
---
---  Generic Emacs background process; parse token stream, return
---  parser actions.
---
---  See gen_run_wisi_parse.ads for a standalone version.
---
---  References :
---
---  [1] On the elisp side, the inter-process protocol is defined in
---  wisi-process-parse.el, functions wisi-process-parse--send-parse
---  and wisi-process-parse--execute.
---
---  [2] On the Ada side, it is defined here, and in
---  wisitoken-wisi_runtime.adb
---
---  Copyright (C) 2017 - 2019 Free Software Foundation, Inc.
---
---  This program is free software; you can redistribute it and/or
---  modify it under terms of the GNU General Public License as
---  published by the Free Software Foundation; either version 3, 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
---  distributed with this program; see file COPYING. If not, write to
---  the Free Software Foundation, 51 Franklin Street, Suite 500, Boston,
---  MA 02110-1335, USA.
-
-pragma License (GPL);
-
-with WisiToken.Parse.LR.Parser;
-with WisiToken.Syntax_Trees;
-with Wisi;
-generic
-   type Parse_Data_Type  is new Wisi.Parse_Data_Type with private;
-
-   Name                           : in String; --  for Usage, error messages.
-   Language_Protocol_Version      : in String; --  Defines language-specific 
parse parameters.
-   Descriptor                     : in WisiToken.Descriptor;
-   Partial_Parse_Active           : in out Boolean;
-   Language_Fixes                 : in 
WisiToken.Parse.LR.Parser.Language_Fixes_Access;
-   Language_Matching_Begin_Tokens : in 
WisiToken.Parse.LR.Parser.Language_Matching_Begin_Tokens_Access;
-   Language_String_ID_Set         : in 
WisiToken.Parse.LR.Parser.Language_String_ID_Set_Access;
-
-   with procedure Create_Parser
-     (Parser                         :    out          
WisiToken.Parse.LR.Parser.Parser;
-      Language_Fixes                 : in              
WisiToken.Parse.LR.Parser.Language_Fixes_Access;
-      Language_Matching_Begin_Tokens : in              
WisiToken.Parse.LR.Parser.Language_Matching_Begin_Tokens_Access;
-      Language_String_ID_Set         : in              
WisiToken.Parse.LR.Parser.Language_String_ID_Set_Access;
-      Trace                          : not null access WisiToken.Trace'Class;
-      User_Data                      : in              
WisiToken.Syntax_Trees.User_Data_Access);
-
-procedure Gen_Emacs_Wisi_LR_Parse;
diff --git a/packages/wisi/gen_emacs_wisi_lr_text_rep_parse.adb 
b/packages/wisi/gen_emacs_wisi_lr_text_rep_parse.adb
deleted file mode 100644
index 31f1052..0000000
--- a/packages/wisi/gen_emacs_wisi_lr_text_rep_parse.adb
+++ /dev/null
@@ -1,44 +0,0 @@
---  Abstract :
---
---  See spec.
---
---  Copyright (C) 2014, 2017 - 2020 All Rights Reserved.
---
---  This program is free software; you can redistribute it and/or
---  modify it under terms of the GNU General Public License as
---  published by the Free Software Foundation; either version 3, 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
---  distributed with this program; see file COPYING. If not, write to
---  the Free Software Foundation, 51 Franklin Street, Suite 500, Boston,
---  MA 02110-1335, USA.
-
-pragma License (GPL);
-
-with Ada.Command_Line;
-with Ada.Directories;
-with Emacs_Wisi_Common_Parse; use Emacs_Wisi_Common_Parse;
-
-with WisiToken.Text_IO_Trace;
-procedure Gen_Emacs_Wisi_LR_Text_Rep_Parse
-is
-   use WisiToken; -- "+", "-" Unbounded_string
-
-   Trace      : aliased WisiToken.Text_IO_Trace.Trace 
(Descriptor'Unrestricted_Access);
-   Parser     : WisiToken.Parse.LR.Parser.Parser;
-   Parse_Data : aliased Parse_Data_Type (Parser.Terminals'Access, 
Parser.Line_Begin_Token'Access);
-
-   Params : constant Process_Start_Params := Get_Process_Start_Params;
-begin
-   Create_Parser
-     (Parser, Language_Fixes, Language_Matching_Begin_Tokens, 
Language_String_ID_Set,
-      Trace'Unrestricted_Access,
-      Parse_Data'Unchecked_Access,
-      Ada.Directories.Containing_Directory (Ada.Command_Line.Command_Name) & 
"/" & Text_Rep_File_Name);
-
-   Process_Stream (Name, Language_Protocol_Version, Partial_Parse_Active, 
Params, Parser, Parse_Data, Descriptor);
-
-end Gen_Emacs_Wisi_LR_Text_Rep_Parse;
diff --git a/packages/wisi/gen_emacs_wisi_lr_text_rep_parse.ads 
b/packages/wisi/gen_emacs_wisi_lr_text_rep_parse.ads
deleted file mode 100644
index f9ff468..0000000
--- a/packages/wisi/gen_emacs_wisi_lr_text_rep_parse.ads
+++ /dev/null
@@ -1,50 +0,0 @@
---  Abstract :
---
---  Generic Emacs background process; parse token stream, return
---  parser actions.
---
---  See gen_run_wisi_parse.ads for a standalone version.
---
---  References : see gen_emacs_wisi_lr_parse.ads
---
---  Copyright (C) 2017, 2018, 2019 Free Software Foundation, Inc.
---
---  This program is free software; you can redistribute it and/or
---  modify it under terms of the GNU General Public License as
---  published by the Free Software Foundation; either version 3, 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
---  distributed with this program; see file COPYING. If not, write to
---  the Free Software Foundation, 51 Franklin Street, Suite 500, Boston,
---  MA 02110-1335, USA.
-
-pragma License (GPL);
-
-with WisiToken.Parse.LR.Parser;
-with WisiToken.Syntax_Trees;
-with Wisi;
-generic
-   type Parse_Data_Type  is new Wisi.Parse_Data_Type with private;
-
-   Name                           : in String; --  for Usage, error messages. 
"_wisi_parse" will be appended
-   Language_Protocol_Version      : in String; --  Defines language-specific 
parse parameters.
-   Descriptor                     : in WisiToken.Descriptor;
-   Partial_Parse_Active           : in out Boolean;
-   Language_Fixes                 : in 
WisiToken.Parse.LR.Parser.Language_Fixes_Access;
-   Language_Matching_Begin_Tokens : in 
WisiToken.Parse.LR.Parser.Language_Matching_Begin_Tokens_Access;
-   Language_String_ID_Set         : in 
WisiToken.Parse.LR.Parser.Language_String_ID_Set_Access;
-   Text_Rep_File_Name             : in String;
-
-   with procedure Create_Parser
-     (Parser                         :    out          
WisiToken.Parse.LR.Parser.Parser;
-      Language_Fixes                 : in              
WisiToken.Parse.LR.Parser.Language_Fixes_Access;
-      Language_Matching_Begin_Tokens : in              
WisiToken.Parse.LR.Parser.Language_Matching_Begin_Tokens_Access;
-      Language_String_ID_Set         : in              
WisiToken.Parse.LR.Parser.Language_String_ID_Set_Access;
-      Trace                          : not null access WisiToken.Trace'Class;
-      User_Data                      : in              
WisiToken.Syntax_Trees.User_Data_Access;
-      Text_Rep_File_Name             : in              String);
-
-procedure Gen_Emacs_Wisi_LR_Text_Rep_Parse;
diff --git a/packages/wisi/gen_emacs_wisi_packrat_parse.adb 
b/packages/wisi/gen_emacs_wisi_packrat_parse.adb
deleted file mode 100644
index b4e95f6..0000000
--- a/packages/wisi/gen_emacs_wisi_packrat_parse.adb
+++ /dev/null
@@ -1,180 +0,0 @@
---  Abstract :
---
---  See spec.
---
---  Copyright (C) 2018 All Rights Reserved.
---
---  This program is free software; you can redistribute it and/or
---  modify it under terms of the GNU General Public License as
---  published by the Free Software Foundation; either version 3, 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
---  distributed with this program; see file COPYING. If not, write to
---  the Free Software Foundation, 51 Franklin Street, Suite 500, Boston,
---  MA 02110-1335, USA.
-
-pragma License (GPL);
-
-with Ada.Command_Line;
-with Ada.Exceptions;
-with Ada.Strings.Fixed;
-with Ada.Strings.Unbounded;
-with Ada.Text_IO; use Ada.Text_IO;
-with Emacs_Wisi_Common_Parse; use Emacs_Wisi_Common_Parse;
-with GNAT.OS_Lib;
-with GNAT.Traceback.Symbolic;
-with System.Storage_Elements;
-with WisiToken.Lexer;
-with WisiToken.Parse.Packrat;
-with WisiToken.Text_IO_Trace;
-procedure Gen_Emacs_Wisi_Parse_Packrat
-is
-   use WisiToken; -- "+", "-" Unbounded_string
-
-   Trace      : aliased WisiToken.Text_IO_Trace.Trace (Descriptor'Access);
-   Parser     : WisiToken.Parse.Packrat.Parser;
-   Parse_Data : aliased Parse_Data_Type (Parser.Line_Begin_Token'Access);
-
-begin
-   Create_Parser (Parser, Trace'Unrestricted_Access, 
Parse_Data'Unchecked_Access);
-
-   declare
-      use Ada.Command_Line;
-   begin
-      case Argument_Count is
-      when 0 =>
-         null;
-
-      when others =>
-         Usage (Name);
-         raise Programmer_Error with "invalid option count: " & Integer'Image 
(Argument_Count);
-      end case;
-   end;
-
-   Put_Line (Name & " " & Version & ", protocol version " & Protocol_Version);
-
-   --  Read commands and tokens from standard_input via GNAT.OS_Lib,
-   --  send results to standard_output.
-   loop
-      Put (Prompt); Flush;
-      declare
-         Command_Length : constant Integer := Get_Command_Length;
-         Command_Line   : aliased String (1 .. Command_Length);
-         Last           : Integer;
-
-         function Match (Target : in String) return Boolean
-         is begin
-            Last := Command_Line'First + Target'Length - 1;
-            return Last <= Command_Line'Last and then Command_Line 
(Command_Line'First .. Last) = Target;
-         end Match;
-      begin
-         Read_Input (Command_Line'Address, Command_Length);
-
-         Put_Line (";; " & Command_Line);
-
-         if Match ("parse") then
-            --  Args: see Usage
-            --  Input: <source text>
-            --  Response:
-            --  [response elisp vector]...
-            --  [elisp error form]...
-            --  prompt
-            declare
-               use Wisi;
-               Cl_Params : constant Command_Line_Params := Get_Cl_Params 
(Command_Line, Last);
-               Buffer    : Ada.Strings.Unbounded.String_Access;
-
-               procedure Clean_Up
-               is begin
-                  Parser.Lexer.Discard_Rest_Of_Input;
-                  Parser.Put_Errors (-Cl_Param.Source_File_Name);
-                  Ada.Strings.Unbounded.Free (Buffer);
-               end Clean_Up;
-
-            begin
-               --  Computing Line_Count in elisp allows parsing in parallel 
with
-               --  sending source text.
-
-               Trace_Parse    := Cl_Params.Parse_Verbosity;
-               Trace_McKenzie := Cl_Params.McKenzie_Verbosity;
-               Trace_Action   := Cl_Params.Action_Verbosity;
-               Debug_Mode     := Cl_Params.Debug_Mode;
-
-               Parse_Data.Initialize
-                 (Post_Parse_Action => Cl_Params.Post_Parse_Action,
-                  Descriptor        => Descriptor'Access,
-                  Source_File_Name  => -Cl_Params.Source_File_Name,
-                  Line_Count        => Cl_Params.Line_Count,
-                  Params            => Command_Line (Last + 2 .. 
Command_Line'Last));
-
-               Buffer := new String (1 .. Cl_Params.Byte_Count);
-               Read_Input (Buffer (1)'Address, Cl_Params.Byte_Count);
-
-               Parser.Lexer.Reset_With_String_Access (Buffer);
-               Parser.Parse;
-               Parser.Execute_Actions;
-               Put (Parse_Data);
-               Clean_Up;
-
-            exception
-            when Syntax_Error =>
-               Clean_Up;
-               Put_Line ("(parse_error)");
-
-            when E : Parse_Error =>
-               Clean_Up;
-               Put_Line ("(parse_error """ & Ada.Exceptions.Exception_Message 
(E) & """)");
-
-            when E : Fatal_Error =>
-               Clean_Up;
-               Put_Line ("(error """ & Ada.Exceptions.Exception_Message (E) & 
""")");
-            end;
-
-         elsif Match ("noop") then
-            --  Args: <source byte count>
-            --  Input: <source text>
-            --  Response: prompt
-            declare
-               Byte_Count  : constant Integer                             := 
Get_Integer (Command_Line, Last);
-               Buffer      : constant Ada.Strings.Unbounded.String_Access := 
new String (1 .. Byte_Count);
-               Token       : Base_Token;
-               Lexer_Error : Boolean;
-               pragma Unreferenced (Lexer_Error);
-            begin
-               Token.ID := Invalid_Token_ID;
-               Read_Input (Buffer (1)'Address, Byte_Count);
-
-               Parser.Lexer.Reset_With_String_Access (Buffer);
-               loop
-                  exit when Token.ID = Parser.Trace.Descriptor.EOF_ID;
-                  Lexer_Error := Parser.Lexer.Find_Next (Token);
-               end loop;
-            exception
-            when Syntax_Error =>
-               Parser.Lexer.Discard_Rest_Of_Input;
-            end;
-
-         elsif Match ("quit") then
-            exit;
-
-         else
-            Put_Line ("(error ""bad command: '" & Command_Line & "'"")");
-         end if;
-      exception
-      when E : Protocol_Error =>
-         --  don't exit the loop; allow debugging bad elisp
-         Put_Line ("(error ""protocol error "": " & 
Ada.Exceptions.Exception_Message (E) & """)");
-      end;
-   end loop;
-exception
-when E : others =>
-   Ada.Command_Line.Set_Exit_Status (Ada.Command_Line.Failure);
-   New_Line (2);
-   Put_Line
-     ("(error ""unhandled exception: " & Ada.Exceptions.Exception_Name (E) & 
": " &
-        Ada.Exceptions.Exception_Message (E) & """)");
-   Put_Line (GNAT.Traceback.Symbolic.Symbolic_Traceback (E));
-end Gen_Emacs_Wisi_Parse_Packrat;
diff --git a/packages/wisi/gen_emacs_wisi_packrat_parse.ads 
b/packages/wisi/gen_emacs_wisi_packrat_parse.ads
deleted file mode 100644
index 79c69ec..0000000
--- a/packages/wisi/gen_emacs_wisi_packrat_parse.ads
+++ /dev/null
@@ -1,42 +0,0 @@
---  Abstract :
---
---  Generic Emacs background process; packrat parse token stream,
---  return parser actions.
---
---  See gen_run_wisi_parse_packrat.ads for a standalone version.
---
---  References :
---
---  See gen_emacs_wisi_parse.ads
---
---  Copyright (C) 2018 Free Software Foundation, Inc.
---
---  This program is free software; you can redistribute it and/or
---  modify it under terms of the GNU General Public License as
---  published by the Free Software Foundation; either version 3, 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
---  distributed with this program; see file COPYING. If not, write to
---  the Free Software Foundation, 51 Franklin Street, Suite 500, Boston,
---  MA 02110-1335, USA.
-
-pragma License (GPL);
-
-with WisiToken.Parse.Packrat;
-with WisiToken.Syntax_Trees;
-with WisiToken.Wisi_Runtime;
-generic
-   type Parse_Data_Type  is new WisiToken.Wisi_Runtime.Parse_Data_Type with 
private;
-
-   Name       : in String; --  for Usage, error messages. 
"_wisi_parse_packrat" will be appended
-   Descriptor : in WisiToken.Descriptor;
-
-   with procedure Create_Parser
-     (Parser    :    out          WisiToken.Parse.Packrat.Parser;
-      Trace     : not null access WisiToken.Trace'Class;
-      User_Data : in              WisiToken.Syntax_Trees.User_Data_Access);
-
-procedure Gen_Emacs_Wisi_Parse_Packrat;
diff --git a/packages/wisi/gen_run_wisi_libadalang_parse.adb 
b/packages/wisi/gen_run_wisi_libadalang_parse.adb
deleted file mode 100644
index c154136..0000000
--- a/packages/wisi/gen_run_wisi_libadalang_parse.adb
+++ /dev/null
@@ -1,176 +0,0 @@
---  Abstract :
---
---  See spec.
---
---  Copyright (C) 2018 All Rights Reserved.
---
---  This program is free software; you can redistribute it and/or
---  modify it under terms of the GNU General Public License as
---  published by the Free Software Foundation; either version 3, 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
---  distributed with this program; see file COPYING. If not, write to
---  the Free Software Foundation, 51 Franklin Street, Suite 500, Boston,
---  MA 02110-1335, USA.
-
-pragma License (GPL);
-
-with Ada.Command_Line;
-with Ada.Exceptions;
-with Ada.Real_Time;
-with Ada.Strings.Unbounded;
-with Ada.Text_IO; use Ada.Text_IO;
-with GNAT.Traceback.Symbolic;
-with Wisi.Libadalang;
-with WisiToken.Text_IO_Trace;
-procedure Gen_Run_Wisi_Libadalang_Parse
-is
-   use WisiToken; -- Token_ID, "+", "-" Unbounded_string
-
-   Trace      : aliased WisiToken.Text_IO_Trace.Trace 
(Descriptor'Unrestricted_Access);
-   Parser     : Wisi.Libadalang.Parser;
-   Parse_Data : aliased Parse_Data_Type (Parser.Line_Begin_Token'Access);
-
-   procedure Put_Usage
-   is begin
-      Put_Line ("usage: <file_name> <parse_action> [options]");
-      Put_Line ("parse_action: {Navigate | Face | Indent}");
-      Put_Line ("options:");
-      Put_Line ("--verbosity n m : parse, action");
-      Put_Line ("--lang_params <language-specific params>");
-      Put_Line ("--repeat_count n : repeat parse count times, for profiling; 
default 1");
-      New_Line;
-   end Put_Usage;
-
-   Source_File_Name  : Ada.Strings.Unbounded.Unbounded_String;
-   Post_Parse_Action : Wisi.Post_Parse_Action_Type;
-   Lang_Params       : Ada.Strings.Unbounded.Unbounded_String;
-
-   Repeat_Count : Integer := 1;
-   Arg          : Integer;
-   Start        : Ada.Real_Time.Time;
-
-begin
-   declare
-      use Ada.Command_Line;
-   begin
-      if Argument_Count < 1 then
-         Put_Usage;
-         Set_Exit_Status (Failure);
-         return;
-      end if;
-
-      Source_File_Name  := +Ada.Command_Line.Argument (1);
-      Post_Parse_Action := Wisi.Post_Parse_Action_Type'Value 
(Ada.Command_Line.Argument (2));
-      Arg               := 3;
-
-      loop
-         exit when Arg > Argument_Count;
-
-         if Argument (Arg) = "--lang_params" then
-            Lang_Params := +Argument (Arg + 1);
-            Arg := Arg + 2;
-
-         elsif Argument (Arg) = "--repeat_count" then
-            Repeat_Count := Integer'Value (Argument (Arg + 1));
-            Arg := Arg + 2;
-
-         elsif Argument (Arg) = "--verbosity" then
-            WisiToken.Trace_Parse  := Integer'Value (Argument (Arg + 1));
-            WisiToken.Trace_Action := Integer'Value (Argument (Arg + 2));
-            Arg                    := Arg + 3;
-
-         else
-            Put_Line ("unrecognized option: '" & Argument (Arg) & "'");
-            Put_Usage;
-            return;
-         end if;
-      end loop;
-   end;
-
-   Parser.Trace            := Trace'Unrestricted_Access;
-   Parser.Lexer            := new Wisi.Libadalang.Lexer 
(Trace'Unrestricted_Access);
-   Parser.User_Data        := Parse_Data'Unrestricted_Access;
-   Parser.Source_File_Name := Source_File_Name;
-
-   Parser.Tree.Initialize (Shared_Tree => 
Parser.Base_Tree'Unrestricted_Access, Flush => True);
-
-   Parse_Data.Initialize
-     (Post_Parse_Action => Post_Parse_Action,
-      Descriptor        => Descriptor'Unrestricted_Access,
-      Source_File_Name  => -Source_File_Name,
-      Line_Count        => 1, --  FIXME: fix wisi_runtime to not need this!
-      Params            => -Lang_Params);
-
-   if Repeat_Count > 1 then
-      Start := Ada.Real_Time.Clock;
-   end if;
-
-   for I in 1 .. Repeat_Count loop
-      declare
-         procedure Clean_Up
-         is begin
-            if I = 1 then
-               null;
-               --  FIXME: Errors!
-               --  Parse_Data.Put
-               --    (Parser.Lexer.Errors,
-               --     Parser.Parsers.First.State_Ref.Errors,
-               --     Parser.Parsers.First.State_Ref.Tree);
-            end if;
-         end Clean_Up;
-
-      begin
-         Parse_Data.Reset;
-         Parser.Parse;
-         Parser.Execute_Actions;
-
-         if Repeat_Count = 1 then
-            Parse_Data.Put;
-
-            --  FIXME: put errors via parse_data.put
-            if Parser.Any_Errors then
-               Parser.Put_Errors;
-            end if;
-            --  Parse_Data.Put
-            --       (Parser.Lexer.Errors,
-            --        Parser.Parsers.First.State_Ref.Errors,
-            --        Parser.Parsers.First.State_Ref.Tree);
-         end if;
-      exception
-      when WisiToken.Syntax_Error =>
-         Clean_Up;
-         Put_Line ("(parse_error)");
-
-      when E : WisiToken.Parse_Error =>
-         Clean_Up;
-         Put_Line ("(parse_error """ & Ada.Exceptions.Exception_Message (E) & 
""")");
-
-      when E : WisiToken.Fatal_Error =>
-         Clean_Up;
-         Put_Line ("(error """ & Ada.Exceptions.Exception_Message (E) & """)");
-      end;
-   end loop;
-
-   if Repeat_Count > 1 then
-      declare
-         use Ada.Real_Time;
-         Finish : constant Time := Clock;
-      begin
-         Put_Line ("Total time:" & Duration'Image (To_Duration (Finish - 
Start)));
-         Put_Line ("per iteration:" & Duration'Image (To_Duration ((Finish - 
Start) / Repeat_Count)));
-      end;
-   end if;
-
-exception
-when E : others =>
-   Ada.Command_Line.Set_Exit_Status (Ada.Command_Line.Failure);
-   New_Line (2);
-   Put_Line
-     ("(error ""unhandled exception: " & Ada.Exceptions.Exception_Name (E) & 
": " &
-        Ada.Exceptions.Exception_Message (E) & """)");
-   Put_Line (GNAT.Traceback.Symbolic.Symbolic_Traceback (E));
-end Gen_Run_Wisi_Libadalang_Parse;
diff --git a/packages/wisi/gen_run_wisi_libadalang_parse.ads 
b/packages/wisi/gen_run_wisi_libadalang_parse.ads
deleted file mode 100644
index 356c67d..0000000
--- a/packages/wisi/gen_run_wisi_libadalang_parse.ads
+++ /dev/null
@@ -1,30 +0,0 @@
---  Abstract :
---
---  Run an Emacs libadalang parser as a standalone executable, for debugging.
---
---  See gen_emacs_wisi_libadalang_parse.ads for the Emacs background process.
---
---  Copyright (C) 2018 Free Software Foundation, Inc.
---
---  This program is free software; you can redistribute it and/or
---  modify it under terms of the GNU General Public License as
---  published by the Free Software Foundation; either version 3, 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
---  distributed with this program; see file COPYING. If not, write to
---  the Free Software Foundation, 51 Franklin Street, Suite 500, Boston,
---  MA 02110-1335, USA.
-
-pragma License (GPL);
-
-with Wisi;
-with WisiToken;
-generic
-   type Parse_Data_Type is new Wisi.Parse_Data_Type with private;
-
-   Descriptor : in WisiToken.Descriptor;
-
-procedure Gen_Run_Wisi_Libadalang_Parse;
diff --git a/packages/wisi/gen_run_wisi_lr_parse.adb 
b/packages/wisi/gen_run_wisi_lr_parse.adb
deleted file mode 100644
index 84498de..0000000
--- a/packages/wisi/gen_run_wisi_lr_parse.adb
+++ /dev/null
@@ -1,37 +0,0 @@
---  Abstract :
---
---  See spec.
---
---  Copyright (C) 2017 - 2020 All Rights Reserved.
---
---  This program is free software; you can redistribute it and/or
---  modify it under terms of the GNU General Public License as
---  published by the Free Software Foundation; either version 3, 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
---  distributed with this program; see file COPYING. If not, write to
---  the Free Software Foundation, 51 Franklin Street, Suite 500, Boston,
---  MA 02110-1335, USA.
-
-pragma License (GPL);
-
-with Run_Wisi_Common_Parse;
-with WisiToken.Text_IO_Trace;
-procedure Gen_Run_Wisi_LR_Parse
-is
-   Trace      : aliased WisiToken.Text_IO_Trace.Trace 
(Descriptor'Unrestricted_Access);
-   Parser     : WisiToken.Parse.LR.Parser.Parser;
-   Parse_Data : aliased Parse_Data_Type (Parser.Terminals'Access, 
Parser.Line_Begin_Token'Access);
-begin
-   --  Create parser first so Put_Usage has defaults from Parser.Table,
-   --  and Get_CL_Params can override them.
-   Create_Parser
-     (Parser, Language_Fixes, Language_Matching_Begin_Tokens, 
Language_String_ID_Set,
-      Trace'Unrestricted_Access, Parse_Data'Unchecked_Access);
-
-   Run_Wisi_Common_Parse.Parse_File (Parser, Parse_Data, Descriptor);
-
-end Gen_Run_Wisi_LR_Parse;
diff --git a/packages/wisi/gen_run_wisi_lr_parse.ads 
b/packages/wisi/gen_run_wisi_lr_parse.ads
deleted file mode 100644
index 34fbd3c..0000000
--- a/packages/wisi/gen_run_wisi_lr_parse.ads
+++ /dev/null
@@ -1,42 +0,0 @@
---  Abstract :
---
---  Run an Emacs LR parser as a standalone executable, for debugging.
---
---  See gen_emacs_wisi_lr_parse.ads for the Emacs background process.
---
---  Copyright (C) 2017, 2018, 2019 Free Software Foundation, Inc.
---
---  This program is free software; you can redistribute it and/or
---  modify it under terms of the GNU General Public License as
---  published by the Free Software Foundation; either version 3, 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
---  distributed with this program; see file COPYING. If not, write to
---  the Free Software Foundation, 51 Franklin Street, Suite 500, Boston,
---  MA 02110-1335, USA.
-
-pragma License (GPL);
-
-with WisiToken.Parse.LR.Parser;
-with WisiToken.Syntax_Trees;
-with Wisi;
-generic
-   type Parse_Data_Type is new Wisi.Parse_Data_Type with private;
-
-   Descriptor                     : in WisiToken.Descriptor;
-   Language_Fixes                 : in 
WisiToken.Parse.LR.Parser.Language_Fixes_Access;
-   Language_Matching_Begin_Tokens : in 
WisiToken.Parse.LR.Parser.Language_Matching_Begin_Tokens_Access;
-   Language_String_ID_Set         : in 
WisiToken.Parse.LR.Parser.Language_String_ID_Set_Access;
-
-   with procedure Create_Parser
-     (Parser                         :    out          
WisiToken.Parse.LR.Parser.Parser;
-      Language_Fixes                 : in              
WisiToken.Parse.LR.Parser.Language_Fixes_Access;
-      Language_Matching_Begin_Tokens : in              
WisiToken.Parse.LR.Parser.Language_Matching_Begin_Tokens_Access;
-      Language_String_ID_Set         : in              
WisiToken.Parse.LR.Parser.Language_String_ID_Set_Access;
-      Trace                          : not null access WisiToken.Trace'Class;
-      User_Data                      : in              
WisiToken.Syntax_Trees.User_Data_Access);
-
-procedure Gen_Run_Wisi_LR_Parse;
diff --git a/packages/wisi/gen_run_wisi_lr_text_rep_parse.adb 
b/packages/wisi/gen_run_wisi_lr_text_rep_parse.adb
deleted file mode 100644
index 45bc5e1..0000000
--- a/packages/wisi/gen_run_wisi_lr_text_rep_parse.adb
+++ /dev/null
@@ -1,44 +0,0 @@
---  Abstract :
---
---  See spec.
---
---  Copyright (C) 2017 - 2020 All Rights Reserved.
---
---  This program is free software; you can redistribute it and/or
---  modify it under terms of the GNU General Public License as
---  published by the Free Software Foundation; either version 3, 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
---  distributed with this program; see file COPYING. If not, write to
---  the Free Software Foundation, 51 Franklin Street, Suite 500, Boston,
---  MA 02110-1335, USA.
-
-pragma License (GPL);
-
-with Ada.Command_Line;
-with Ada.Directories;
-with Run_Wisi_Common_Parse;
-with WisiToken.Text_IO_Trace;
-procedure Gen_Run_Wisi_LR_Text_Rep_Parse
-is
-   Trace      : aliased WisiToken.Text_IO_Trace.Trace 
(Descriptor'Unrestricted_Access);
-   Parser     : WisiToken.Parse.LR.Parser.Parser;
-   Parse_Data : aliased Parse_Data_Type (Parser.Terminals'Access, 
Parser.Line_Begin_Token'Access);
-begin
-   --  Create parser first so Put_Usage has defaults from Parser.Table,
-   --  and Get_CL_Params can override them.
-   declare
-      use Ada.Command_Line;
-   begin
-      --  text_rep file is in same directory as exectuable.
-      Create_Parser
-        (Parser, Language_Fixes, Language_Matching_Begin_Tokens, 
Language_String_ID_Set,
-         Trace'Unrestricted_Access, Parse_Data'Unchecked_Access,
-         Ada.Directories.Containing_Directory (Command_Name) & "/" & 
Text_Rep_File_Name);
-
-      Run_Wisi_Common_Parse.Parse_File (Parser, Parse_Data, Descriptor);
-   end;
-end Gen_Run_Wisi_LR_Text_Rep_Parse;
diff --git a/packages/wisi/gen_run_wisi_lr_text_rep_parse.ads 
b/packages/wisi/gen_run_wisi_lr_text_rep_parse.ads
deleted file mode 100644
index dd45d16..0000000
--- a/packages/wisi/gen_run_wisi_lr_text_rep_parse.ads
+++ /dev/null
@@ -1,44 +0,0 @@
---  Abstract :
---
---  Run an Emacs LR text_rep parser as a standalone executable, for debugging.
---
---  See gen_emacs_wisi_*_parse.ads for the Emacs background process.
---
---  Copyright (C) 2018, 2019 Free Software Foundation, Inc.
---
---  This program is free software; you can redistribute it and/or
---  modify it under terms of the GNU General Public License as
---  published by the Free Software Foundation; either version 3, 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
---  distributed with this program; see file COPYING. If not, write to
---  the Free Software Foundation, 51 Franklin Street, Suite 500, Boston,
---  MA 02110-1335, USA.
-
-pragma License (GPL);
-
-with WisiToken.Parse.LR.Parser;
-with WisiToken.Syntax_Trees;
-with Wisi;
-generic
-   type Parse_Data_Type is new Wisi.Parse_Data_Type with private;
-
-   Descriptor                     : in WisiToken.Descriptor;
-   Language_Fixes                 : in 
WisiToken.Parse.LR.Parser.Language_Fixes_Access;
-   Language_Matching_Begin_Tokens : in 
WisiToken.Parse.LR.Parser.Language_Matching_Begin_Tokens_Access;
-   Language_String_ID_Set         : in 
WisiToken.Parse.LR.Parser.Language_String_ID_Set_Access;
-   Text_Rep_File_Name             : in String;
-
-   with procedure Create_Parser
-     (Parser                         :    out          
WisiToken.Parse.LR.Parser.Parser;
-      Language_Fixes                 : in              
WisiToken.Parse.LR.Parser.Language_Fixes_Access;
-      Language_Matching_Begin_Tokens : in              
WisiToken.Parse.LR.Parser.Language_Matching_Begin_Tokens_Access;
-      Language_String_ID_Set         : in              
WisiToken.Parse.LR.Parser.Language_String_ID_Set_Access;
-      Trace                          : not null access WisiToken.Trace'Class;
-      User_Data                      : in              
WisiToken.Syntax_Trees.User_Data_Access;
-      Text_Rep_File_Name             : in              String);
-
-procedure Gen_Run_Wisi_LR_Text_Rep_Parse;
diff --git a/packages/wisi/gen_run_wisi_packrat_parse.adb 
b/packages/wisi/gen_run_wisi_packrat_parse.adb
deleted file mode 100644
index fb3e900..0000000
--- a/packages/wisi/gen_run_wisi_packrat_parse.adb
+++ /dev/null
@@ -1,241 +0,0 @@
---  Abstract :
---
---  See spec.
---
---  Copyright (C) 2018 All Rights Reserved.
---
---  This program is free software; you can redistribute it and/or
---  modify it under terms of the GNU General Public License as
---  published by the Free Software Foundation; either version 3, 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
---  distributed with this program; see file COPYING. If not, write to
---  the Free Software Foundation, 51 Franklin Street, Suite 500, Boston,
---  MA 02110-1335, USA.
-
-pragma License (GPL);
-
-with Ada.Command_Line;
-with Ada.Exceptions;
-with Ada.IO_Exceptions;
-with Ada.Real_Time;
-with Ada.Strings.Unbounded;
-with Ada.Text_IO; use Ada.Text_IO;
-with GNAT.Traceback.Symbolic;
-with WisiToken.Lexer;
-with WisiToken.Text_IO_Trace;
-procedure Gen_Run_Wisi_Parse_Packrat
-is
-   use WisiToken; -- Token_ID, "+", "-" Unbounded_string
-
-   Trace      : aliased WisiToken.Text_IO_Trace.Trace (Descriptor'Access);
-   Parser     : WisiToken.Parse.Packrat.Parser;
-   Parse_Data : aliased Parse_Data_Type (Parser.Line_Begin_Token'Access);
-
-   procedure Put_Usage
-   is begin
-      Put_Line ("usage: " & Name & "_wisi_parse <file_name> <parse_action> 
[options]");
-      Put_Line ("parse_action: {Navigate | Face | Indent}");
-      Put_Line ("options:");
-      Put_Line ("--verbosity n m l:");
-      Put_Line ("   n: parser; m: mckenzie; l: action");
-      Put_Line ("   0 - only report parse errors");
-      Put_Line ("   1 - shows spawn/terminate parallel parsers, error recovery 
enter/exit");
-      Put_Line ("   2 - add each parser cycle, error recovery enqueue/check");
-      Put_Line ("   3 - parse stack in each cycle, error recovery parse 
actions");
-      Put_Line ("   4 - add lexer debug");
-      Put_Line ("--lang_params <language-specific params>");
-      Put_Line ("--lexer_only : only run lexer, for profiling");
-      Put_Line ("--repeat_count n : repeat parse count times, for profiling; 
default 1");
-      Put_Line ("--pause : when repeating, prompt for <enter> after each 
parse; allows seeing memory leaks");
-      New_Line;
-   end Put_Usage;
-
-   Source_File_Name  : Ada.Strings.Unbounded.Unbounded_String;
-   Post_Parse_Action : WisiToken.Wisi_Runtime.Post_Parse_Action_Type;
-
-   Line_Count   : WisiToken.Line_Number_Type := 1;
-   Lexer_Only   : Boolean                    := False;
-   Repeat_Count : Integer                    := 1;
-   Pause        : Boolean                    := False;
-   Arg          : Integer;
-   Lang_Params  : Ada.Strings.Unbounded.Unbounded_String;
-   Start        : Ada.Real_Time.Time;
-begin
-   Create_Parser (Parser, Trace'Unrestricted_Access, 
Parse_Data'Unchecked_Access);
-
-   declare
-      use Ada.Command_Line;
-   begin
-      if Argument_Count < 1 then
-         Put_Usage;
-         Set_Exit_Status (Failure);
-         return;
-      end if;
-
-      Source_File_Name  := +Ada.Command_Line.Argument (1);
-      Post_Parse_Action := WisiToken.Wisi_Runtime.Post_Parse_Action_Type'Value 
(Ada.Command_Line.Argument (2));
-      Arg               := 3;
-
-      loop
-         exit when Arg > Argument_Count;
-
-         if Argument (Arg) = "--verbosity" then
-            WisiToken.Trace_Parse    := Integer'Value (Argument (Arg + 1));
-            WisiToken.Trace_McKenzie := Integer'Value (Argument (Arg + 2));
-            WisiToken.Trace_Action   := Integer'Value (Argument (Arg + 3));
-            Arg                      := Arg + 4;
-
-         elsif Argument (Arg) = "--lang_params" then
-            Lang_Params := +Argument (Arg + 1);
-            Arg := Arg + 2;
-
-         elsif Argument (Arg) = "--lexer_only" then
-            Lexer_Only := True;
-            Arg := Arg + 1;
-
-         elsif Argument (Arg) = "--pause" then
-            Pause := True;
-            Arg := Arg + 1;
-
-         elsif Argument (Arg) = "--repeat_count" then
-            Repeat_Count := Integer'Value (Argument (Arg + 1));
-            Arg := Arg + 2;
-
-         else
-            Put_Line ("unrecognized option: '" & Argument (Arg) & "'");
-            Put_Usage;
-            return;
-         end if;
-      end loop;
-   end;
-
-   --  Do this after setting Trace_Parse so lexer verbosity is set
-   begin
-      Parser.Lexer.Reset_With_File (-Source_File_Name);
-   exception
-   when Ada.IO_Exceptions.Name_Error =>
-      Put_Line (Standard_Error, "'" & (-Source_File_Name) & "' cannot be 
opened");
-      return;
-   end;
-
-   --  See comment in wisi-wisi_runtime.ads for why we still need this.
-   declare
-      Token : Base_Token;
-      Lexer_Error : Boolean;
-      pragma Unreferenced (Lexer_Error);
-   begin
-      loop
-         begin
-            Lexer_Error := Parser.Lexer.Find_Next (Token);
-            exit when Token.ID = Descriptor.EOF_ID;
-         exception
-         when WisiToken.Syntax_Error =>
-            Parser.Lexer.Discard_Rest_Of_Input;
-            Parser.Put_Errors (-Source_File_Name);
-            Put_Line ("(lexer_error)");
-         end;
-      end loop;
-      Line_Count := Token.Line;
-   end;
-
-   if WisiToken.Trace_Action > WisiToken.Outline then
-      Put_Line ("line_count:" & Line_Number_Type'Image (Line_Count));
-   end if;
-
-   Parse_Data.Initialize
-     (Post_Parse_Action => Post_Parse_Action,
-      Descriptor        => Descriptor'Access,
-      Source_File_Name  => -Source_File_Name,
-      Line_Count        => Line_Count,
-      Params            => -Lang_Params);
-
-   if Repeat_Count > 1 then
-      Start := Ada.Real_Time.Clock;
-   end if;
-
-   for I in 1 .. Repeat_Count loop
-      declare
-         procedure Clean_Up
-         is begin
-            Parser.Lexer.Discard_Rest_Of_Input;
-            if Repeat_Count = 1 then
-               Parser.Put_Errors (-Source_File_Name);
-            end if;
-         end Clean_Up;
-
-      begin
-         Parse_Data.Reset;
-         Parser.Lexer.Reset;
-
-         if Lexer_Only then
-            declare
-               Token : Base_Token;
-               Lexer_Error : Boolean;
-               pragma Unreferenced (Lexer_Error);
-            begin
-               Parser.Lexer.Reset;
-               loop
-                  Lexer_Error := Parser.Lexer.Find_Next (Token);
-                  exit when Token.ID = Descriptor.EOF_ID;
-               end loop;
-               --  We don't handle errors here; that was done in the count 
lines loop
-               --  above.
-            end;
-         else
-            Parser.Parse;
-            Parser.Execute_Actions;
-
-            if Repeat_Count = 1 then
-               Parse_Data.Put;
-               Parser.Put_Errors (-Source_File_Name);
-            end if;
-         end if;
-      exception
-      when WisiToken.Syntax_Error =>
-         Clean_Up;
-         Put_Line ("(parse_error)");
-
-      when E : WisiToken.Parse_Error =>
-         Clean_Up;
-         Put_Line ("(parse_error """ & Ada.Exceptions.Exception_Message (E) & 
""")");
-
-      when E : WisiToken.Fatal_Error =>
-         Clean_Up;
-         Put_Line ("(error """ & Ada.Exceptions.Exception_Message (E) & """)");
-      end;
-
-      if Pause then
-         Put_Line ("Enter to continue:");
-         Flush (Standard_Output);
-         declare
-            Junk : constant String := Get_Line;
-            pragma Unreferenced (Junk);
-         begin
-            null;
-         end;
-      end if;
-   end loop;
-
-   if Repeat_Count > 1 then
-      declare
-         use Ada.Real_Time;
-         Finish : constant Time := Clock;
-      begin
-         Put_Line ("Total time:" & Duration'Image (To_Duration (Finish - 
Start)));
-         Put_Line ("per iteration:" & Duration'Image (To_Duration ((Finish - 
Start) / Repeat_Count)));
-      end;
-   end if;
-
-exception
-when E : others =>
-   Ada.Command_Line.Set_Exit_Status (Ada.Command_Line.Failure);
-   New_Line (2);
-   Put_Line
-     ("(error ""unhandled exception: " & Ada.Exceptions.Exception_Name (E) & 
": " &
-        Ada.Exceptions.Exception_Message (E) & """)");
-   Put_Line (GNAT.Traceback.Symbolic.Symbolic_Traceback (E));
-end Gen_Run_Wisi_Parse_Packrat;
diff --git a/packages/wisi/gen_run_wisi_packrat_parse.ads 
b/packages/wisi/gen_run_wisi_packrat_parse.ads
deleted file mode 100644
index 538da1d..0000000
--- a/packages/wisi/gen_run_wisi_packrat_parse.ads
+++ /dev/null
@@ -1,36 +0,0 @@
---  Abstract :
---
---  Run an Emacs packrate parser as a standalone executable, for debugging.
---
---  See gen_emacs_wisi_parse_packrat.ads for the Emacs background process.
---
---  Copyright (C) 2018 Free Software Foundation, Inc.
---
---  This program is free software; you can redistribute it and/or
---  modify it under terms of the GNU General Public License as
---  published by the Free Software Foundation; either version 3, 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
---  distributed with this program; see file COPYING. If not, write to
---  the Free Software Foundation, 51 Franklin Street, Suite 500, Boston,
---  MA 02110-1335, USA.
-
-pragma License (GPL);
-
-with WisiToken.Parse.Packrat;
-with WisiToken.Syntax_Trees;
-with WisiToken.Wisi_Runtime;
-generic
-   type Parse_Data_Type is new WisiToken.Wisi_Runtime.Parse_Data_Type with 
private;
-
-   Descriptor : in WisiToken.Descriptor;
-
-   with procedure Create_Parser
-     (Parser    :    out          WisiToken.Parse.Packrat.Parser;
-      Trace     : not null access WisiToken.Trace'Class;
-      User_Data : in              WisiToken.Syntax_Trees.User_Data_Access);
-
-procedure Gen_Run_Wisi_Parse_Packrat;
diff --git a/packages/wisi/long_float_elementary_functions.ads 
b/packages/wisi/long_float_elementary_functions.ads
deleted file mode 100644
index d5664b7..0000000
--- a/packages/wisi/long_float_elementary_functions.ads
+++ /dev/null
@@ -1,21 +0,0 @@
---  Abstract :
---
---  instantiation
---
---  Copyright (C) 2017 Free Software Foundation, Inc.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-with Ada.Numerics.Generic_Elementary_Functions;
-package Long_Float_Elementary_Functions is new 
Ada.Numerics.Generic_Elementary_Functions (Long_Float);
diff --git a/packages/wisi/recover_stats.adb b/packages/wisi/recover_stats.adb
deleted file mode 100644
index e1fed7b..0000000
--- a/packages/wisi/recover_stats.adb
+++ /dev/null
@@ -1,271 +0,0 @@
---  Abstract :
---
---  Summarize error recover log.
---
---  Copyright (C) 2019 - 2020 Stephen Leake All Rights Reserved.
---
---  This program is free software; you can redistribute it and/or
---  modify it under terms of the GNU General Public License as
---  published by the Free Software Foundation; either version 3, 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
---  distributed with this program; see file COPYING. If not, write to
---  the Free Software Foundation, 51 Franklin Street, Suite 500, Boston,
---  MA 02110-1335, USA.
-
-pragma License (GPL);
-
-with Ada.Command_Line;
-with Ada.Exceptions;
-with Ada.Long_Float_Text_IO;
-with Ada.Strings.Fixed; use Ada.Strings.Fixed;
-with Ada.Strings.Maps;
-with Ada.Text_IO; use Ada.Text_IO;
-with GNAT.Traceback.Symbolic;
-with SAL.Gen_Stats.Gen_Image;
-with SAL.Long_Float_Stats;
-with WisiToken.Parse.LR;
-procedure Recover_Stats
-is
-   subtype Strategies is WisiToken.Parse.LR.Strategies;
-
-   File : File_Type;
-
-   Delimiters : constant Ada.Strings.Maps.Character_Set := 
Ada.Strings.Maps.To_Set (",() ");
-   Number     : constant Ada.Strings.Maps.Character_Set := 
Ada.Strings.Maps.To_Set ("0123456789");
-
-   type Strategy_Counts is array (Strategies) of Natural;
-
-   type Recover_Label is (Full, Partial);
-
-   type Recover_Summary is record
-      Event_Count : Integer := 0;
-      --  1 per recover event (1 line in log file)
-
-      Enqueue_Stats : SAL.Long_Float_Stats.Stats_Type;
-      Check_Stats   : SAL.Long_Float_Stats.Stats_Type;
-
-      Strat_Counts_Total   : Strategy_Counts := (others => 0);
-      Strat_Counts_Present : Strategy_Counts := (others => 0);
-      --  1 per recover event if used
-
-      Recover_Count_Present : Integer := 0;
-      --  1 per parser in recover result
-
-      Recover_Count_Total : Integer := 0;
-      --  Sum of all strategy counts
-
-      Fail_Event_Count      : Integer := 0; -- for all reasons
-      Fail_Enqueue_Limit    : Integer := 0;
-      Fail_No_Configs_Left  : Integer := 0;
-      Fail_Programmer_Error : Integer := 0;
-      Fail_Other            : Integer := 0;
-   end record;
-
-   Summary : array (Recover_Label) of Recover_Summary;
-begin
-   Open (File, In_File, Ada.Command_Line.Argument (1));
-
-   loop
-      exit when End_Of_File (File);
-      declare
-         --  The recover log is written by code in
-         --  wisitoken-parse-lr-parser.adb Parse (search for Recover_Log).
-         --
-         --  A line has the syntax:
-         --  yyyy-mm-dd hh:mm:ss <partial> <success> pre_parser_count 
'<file_name>' (<parser_data>)...
-         --
-         --  where there is one (<parser_data) for each parser active after 
recover. <parser_data> is:
-         --
-         --  (<strategy_counts>) <enqueue_count> <check_count> <success>
-         --
-         --  Note that the per-parser success is always TRUE; it would not be
-         --  active if recover had failed.
-
-         Line  : constant String := Get_Line (File);
-         First : Integer         := Index (Line, " "); -- after date
-         Last  : Integer;
-
-         Label : Recover_Label := Full;
-
-         function Line_Eq (Item : in String) return Boolean
-         is begin
-            return Line (First .. First + Item'Length - 1) = Item;
-         end Line_Eq;
-
-         function Next_Integer return Integer
-         is begin
-            Find_Token
-              (Line, Number,
-               From  => Last + 1,
-               Test  => Ada.Strings.Inside,
-               First => First,
-               Last  => Last);
-            return Integer'Value (Line (First .. Last));
-         exception
-         when Constraint_Error =>
-            raise Constraint_Error with "bad integer '" & Line (First .. Last 
- 1) & "' " &
-              Ada.Text_IO.Count'Image (Ada.Text_IO.Line (File) - 1) & 
First'Image & Last'Image;
-         end Next_Integer;
-
-         function Next_Boolean return  Boolean
-         is begin
-            First := Last + 2;
-            Last  := -1 + Index (Line, Delimiters, First);
-            return Boolean'Value (Line (First .. Last));
-         end Next_Boolean;
-
-         function Read_Strat_Counts (Strategy_Found : out Boolean) return 
Strategy_Counts
-         is begin
-            Strategy_Found := False;
-            Last := Index (Line, "(", Last + 1);
-            return Result : Strategy_Counts do
-               for I in Strategies loop
-                  Result (I) := Next_Integer;
-                  if Result (I) > 0 then
-                     Strategy_Found := True;
-                  end if;
-               end loop;
-               Last := 1 + Index (Line, ")", Last + 1);
-            end return;
-         end Read_Strat_Counts;
-
-      begin
-         First := Index (Line, " ", First + 1); -- after time
-         Last  := Index (Line, " ", First + 1); -- after Partial_Parse_Active
-         if Boolean'Value (Line (First + 1 .. Last - 1)) then
-            Label := Partial;
-         end if;
-
-         Summary (Label).Event_Count := Summary (Label).Event_Count + 1;
-
-         First := Last + 1;
-         if Line (First .. First + 3) = "FAIL" then
-            Summary (Label).Fail_Event_Count := Summary 
(Label).Fail_Event_Count + 1;
-            First := First + 4;
-
-            if Line_Eq ("NO_CONFIGS_LEFT") then
-               Summary (Label).Fail_No_Configs_Left := Summary 
(Label).Fail_No_Configs_Left + 1;
-            elsif Line_Eq ("ENQUEUE_LIMIT") then
-               Summary (Label).Fail_Enqueue_Limit := Summary 
(Label).Fail_Enqueue_Limit + 1;
-            elsif Line_Eq ("PROGRAMMER_ERROR") then
-               Summary (Label).Fail_Programmer_Error := Summary 
(Label).Fail_Programmer_Error + 1;
-            else
-               Summary (Label).Fail_Other := Summary (Label).Fail_Other + 1;
-            end if;
-
-         else
-            --  Process per-parser data
-            Last := Index (Line, "(", Last + 1);
-            loop
-               exit when Line (Last + 1) = ')';
-               declare
-                  Strategy_Found : Boolean;
-                  Strat_Counts   : constant Strategy_Counts := 
Read_Strat_Counts (Strategy_Found);
-                  Enqueue_Count  : constant Integer         := Next_Integer;
-                  Check_Count    : constant Integer         := Next_Integer;
-                  Success        : constant Boolean         := Next_Boolean;
-                  pragma Unreferenced (Success);
-               begin
-                  Summary (Label).Recover_Count_Present := Summary 
(Label).Recover_Count_Present + 1;
-
-                  if not Strategy_Found then
-                     raise SAL.Programmer_Error;
-                  else
-                     Summary (Label).Enqueue_Stats.Accumulate (Long_Float 
(Enqueue_Count));
-                     Summary (Label).Check_Stats.Accumulate (Long_Float 
(Check_Count));
-                     for I in Strategies loop
-                        Summary (Label).Recover_Count_Total    :=
-                          Summary (Label).Recover_Count_Total + Strat_Counts 
(I);
-                        Summary (Label).Strat_Counts_Total (I) :=
-                          Summary (Label).Strat_Counts_Total (I) + 
Strat_Counts (I);
-                        if Strat_Counts (I) > 0 then
-                           Summary (Label).Strat_Counts_Present (I) := Summary 
(Label).Strat_Counts_Present (I) + 1;
-                        end if;
-                     end loop;
-                  end if;
-               end;
-            end loop;
-         end if;
-      end;
-   end loop;
-
-   declare
-      use Ada.Strings;
-
-      Label_Field     : String (1 .. 23); -- fits strategy and fail labels
-      Count_Field     : String (1 .. 8);
-      Percent_Field   : String (1 .. 4);
-      --  Shared by Put_If, Put_Percent
-
-      procedure Put_If
-        (Summary_Label : in Recover_Label;
-         Name          : in String;
-         Count         : in Integer;
-         Always        : in Boolean := False)
-      is
-         Percent_Present : constant Integer :=
-           Integer (100.0 * Float (Count) / Float (Summary 
(Summary_Label).Event_Count));
-      begin
-         if Count > 0 or Always then
-            Move (Name, Label_Field); Put (Label_Field & " => ");
-            Move (Count'Image, Count_Field, Justify => Right); Put 
(Count_Field);
-            Move (Percent_Present'Image & "%", Percent_Field, Justify => 
Right); Put_Line (Percent_Field);
-         end if;
-      end Put_If;
-
-      package Stats_Image is new SAL.Long_Float_Stats.Gen_Image
-        (Real_IO           => Ada.Long_Float_Text_IO,
-         Default_Mean_Fore => 7,
-         Default_Mean_Aft  => 0,
-         Default_Mean_Exp  => 0,
-         Default_Sd_Fore   => 7,
-         Default_Sd_Aft    => 1,
-         Default_Sd_Exp    => 0);
-
-      procedure Put_Percent (Summary_Label : in Recover_Label; Present, Total 
: in Integer; Name : in String)
-      is
-         Percent_Present : constant Integer :=
-           Integer (100.0 * Float (Present) / Float (Summary 
(Summary_Label).Recover_Count_Present));
-         Percent_Total   : constant Integer :=
-           Integer (100.0 * Float (Total) / Float (Summary 
(Summary_Label).Recover_Count_Total));
-      begin
-         Move (Name, Label_Field); Put (Label_Field);
-         Move (Present'Image, Count_Field, Justify => Right); Put 
(Count_Field);
-         Move (Percent_Present'Image & "%", Percent_Field, Justify => Right); 
Put (Percent_Field & " /");
-         Move (Total'Image, Count_Field, Justify => Right); Put (Count_Field);
-         Move (Percent_Total'Image & "%", Percent_Field, Justify => Right); 
Put_Line (Percent_Field);
-      end Put_Percent;
-
-   begin
-      for I in Recover_Label loop
-         Put_Line (I'Image);
-         Put_Line ("present/total:" & Summary (I).Event_Count'Image & " /" & 
Summary (I).Recover_Count_Total'Image);
-         if Summary (I).Event_Count > 0 then
-            Put_Line ("           mean        std. dev.    min     max");
-            Put_Line ("Enqueue: " & Stats_Image.Image (Summary 
(I).Enqueue_Stats.Display));
-            Put_Line ("Check:   " & Stats_Image.Image (Summary 
(I).Check_Stats.Display));
-            Put_If (I, "FAIL", Summary (I).Fail_Event_Count, Always => True);
-            Put_If (I, "FAIL_ENQUEUE_LIMIT", Summary (I).Fail_Enqueue_Limit);
-            Put_If (I, "FAIL_NO_CONFIGS_LEFT", Summary 
(I).Fail_No_Configs_Left);
-            Put_If (I, "FAIL_PROGRAMMER_ERROR", Summary 
(I).Fail_Programmer_Error);
-            Put_If (I, "FAIL_OTHER", Summary (I).Fail_Other);
-            for J in Strategies loop
-               Put_Percent
-                 (I,
-                  Summary (I).Strat_Counts_Present (J),
-                  Summary (I).Strat_Counts_Total (J),
-                  J'Image);
-            end loop;
-         end if;
-         New_Line;
-      end loop;
-   end;
-exception
-when E : others =>
-   Put_Line (Ada.Exceptions.Exception_Name (E) & ": " & 
Ada.Exceptions.Exception_Message (E));
-   Put_Line (GNAT.Traceback.Symbolic.Symbolic_Traceback (E));
-end Recover_Stats;
diff --git a/packages/wisi/run_wisi_common_parse.adb 
b/packages/wisi/run_wisi_common_parse.adb
deleted file mode 100644
index c79f2e7..0000000
--- a/packages/wisi/run_wisi_common_parse.adb
+++ /dev/null
@@ -1,356 +0,0 @@
---  Abstract :
---
---  See spec.
---
---  Copyright (C) 2018 - 2020 Free Software Foundation, Inc.
---
---  This program is free software; you can redistribute it and/or
---  modify it under terms of the GNU General Public License as
---  published by the Free Software Foundation; either version 3, 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
---  distributed with this program; see file COPYING. If not, write to
---  the Free Software Foundation, 51 Franklin Street, Suite 500, Boston,
---  MA 02110-1335, USA.
-
-pragma License (GPL);
-
-with Ada.Command_Line;
-with Ada.Exceptions;
-with Ada.IO_Exceptions;
-with Ada.Real_Time;
-with Ada.Text_IO;
-with SAL;
-with System.Multiprocessors;
-package body Run_Wisi_Common_Parse is
-
-   procedure Usage (Parser : in out WisiToken.Parse.LR.Parser.Parser)
-   is
-      use all type WisiToken.Parse.LR.Parse_Table_Ptr;
-      use Ada.Text_IO;
-   begin
-      Put_Line ("usage: parse <parse_action> <file_name> [partial parse 
params] [options]");
-      Put_Line ("   or: refactor <refactor_action> <file_name> <edit_begin> 
[options]");
-      Put_Line ("parse_action: {Navigate | Face | Indent}");
-      Put_Line ("partial parse params: begin_byte_pos end_byte_pos 
goal_byte_pos begin_char_pos begin_line" &
-                  " end_line begin_indent");
-      Put_Line ("options:");
-      Put_Line ("--verbosity n m l: (no 'm' for refactor)");
-      Put_Line ("   n: parser; m: mckenzie; l: action");
-      Put_Line ("   0 - only report parse errors");
-      Put_Line ("   1 - shows spawn/terminate parallel parsers, error recovery 
enter/exit");
-      Put_Line ("   2 - add each parser cycle, error recovery enqueue/check");
-      Put_Line ("   3 - parse stack in each cycle, error recovery parse 
actions");
-      Put_Line ("   4 - add lexer debug, dump syntax tree");
-      Put_Line ("--check_limit n  : set error recover token check limit" &
-                  (if Parser.Table = null then ""
-                   else "; default" & 
Parser.Table.McKenzie_Param.Check_Limit'Image));
-      Put_Line ("--check_delta n  : set error recover delta check limit" &
-                  (if Parser.Table = null then ""
-                   else "; default" & 
Parser.Table.McKenzie_Param.Check_Delta_Limit'Image));
-      Put_Line ("--enqueue_limit n  : set error recover token enqueue limit" &
-                  (if Parser.Table = null then ""
-                   else "; default" & 
Parser.Table.McKenzie_Param.Enqueue_Limit'Image));
-      Put_Line ("--max_parallel n  : set maximum count of parallel parsers 
(default" &
-                  WisiToken.Parse.LR.Parser.Default_Max_Parallel'Image & ")");
-      Put_Line ("--task_count n : worker tasks in error recovery");
-      Put_Line ("--disable_recover : disable error recovery; default enabled");
-      Put_Line ("--debug_mode : tracebacks from unhandled exceptions; default 
disabled");
-      Put_Line ("--lang_params <language-specific params>");
-      Put_Line ("--repeat_count n : repeat parse count times, for profiling; 
default 1");
-      New_Line;
-   end Usage;
-
-   function Get_CL_Params (Parser : in out WisiToken.Parse.LR.Parser.Parser) 
return Command_Line_Params
-   is
-      use Ada.Command_Line;
-      use WisiToken;
-      Arg     : Integer := 1;
-      Command : Command_Type;
-   begin
-      if Argument_Count < 1 then
-         Usage (Parser);
-         Set_Exit_Status (Failure);
-         raise Finish;
-
-      elsif Argument (Arg) = "--help" then
-         Usage (Parser);
-         raise Finish;
-
-      elsif Argument_Count < 2 then
-         Usage (Parser);
-         Set_Exit_Status (Failure);
-         raise Finish;
-      end if;
-
-      Command := Command_Type'Value (Ada.Command_Line.Argument (1));
-
-      return Result : Command_Line_Params (Command) do
-         Result.Source_File_Name  := +Ada.Command_Line.Argument (3);
-
-         case Command is
-         when Parse =>
-            Result.Post_Parse_Action := Wisi.Post_Parse_Action_Type'Value 
(Ada.Command_Line.Argument (2));
-
-            if Argument_Count >= 4 and then Argument (4)(1) /= '-' then
-               Result.Begin_Byte_Pos := WisiToken.Buffer_Pos'Value (Argument 
(4));
-               Result.End_Byte_Pos   := WisiToken.Buffer_Pos'Value (Argument 
(5)) - 1; -- match emacs region
-               Result.Goal_Byte_Pos  := WisiToken.Buffer_Pos'Value (Argument 
(6));
-               Result.Begin_Char_Pos := WisiToken.Buffer_Pos'Value (Argument 
(7));
-               Result.Begin_Line     := WisiToken.Line_Number_Type'Value 
(Argument (8));
-               Result.End_Line       := WisiToken.Line_Number_Type'Value 
(Argument (9));
-               Result.Begin_Indent   := Integer'Value (Argument (10));
-               Arg                   := 11;
-            else
-               Result.Begin_Byte_Pos := WisiToken.Invalid_Buffer_Pos;
-               Result.End_Byte_Pos   := WisiToken.Invalid_Buffer_Pos;
-               Result.Begin_Char_Pos := WisiToken.Buffer_Pos'First;
-               Result.Begin_Line     := WisiToken.Line_Number_Type'First;
-               Arg                   := 4;
-            end if;
-
-         when Refactor =>
-            Result.Refactor_Action := Integer'Value (Argument (2));
-            Result.Edit_Begin      := WisiToken.Buffer_Pos'Value (Argument 
(4));
-            Arg                    := 5;
-         end case;
-
-         loop
-            exit when Arg > Argument_Count;
-
-            if Argument (Arg) = "--verbosity" then
-               WisiToken.Trace_Parse    := Integer'Value (Argument (Arg + 1));
-               case Command is
-               when Parse =>
-                  WisiToken.Trace_McKenzie := Integer'Value (Argument (Arg + 
2));
-                  WisiToken.Trace_Action   := Integer'Value (Argument (Arg + 
3));
-                  Arg                      := Arg + 4;
-               when Refactor =>
-                  WisiToken.Trace_Action   := Integer'Value (Argument (Arg + 
2));
-                  Arg                      := Arg + 3;
-               end case;
-
-               WisiToken.Debug_Mode := WisiToken.Trace_Parse > Outline or 
WisiToken.Trace_McKenzie > Outline;
-
-            elsif Argument (Arg) = "--check_limit" then
-               Parser.Table.McKenzie_Param.Check_Limit := Token_Index'Value 
(Argument (Arg + 1));
-               Arg := Arg + 2;
-
-            elsif Argument (Arg) = "--check_delta" then
-               Parser.Table.McKenzie_Param.Check_Delta_Limit := Integer'Value 
(Argument (Arg + 1));
-               Arg := Arg + 2;
-
-            elsif Argument (Arg) = "--debug_mode" then
-               WisiToken.Debug_Mode := True;
-               Arg := Arg + 1;
-
-            elsif Argument (Arg) = "--disable_recover" then
-               Parser.Enable_McKenzie_Recover := False;
-               Arg := Arg + 1;
-
-            elsif Argument (Arg) = "--enqueue_limit" then
-               Parser.Table.McKenzie_Param.Enqueue_Limit := Integer'Value 
(Argument (Arg + 1));
-               Arg := Arg + 2;
-
-            elsif Argument (Arg) = "--lang_params" then
-               Result.Lang_Params := +Argument (Arg + 1);
-               Arg := Arg + 2;
-
-            elsif Argument (Arg) = "--max_parallel" then
-               Parser.Max_Parallel := SAL.Base_Peek_Type'Value (Argument (Arg 
+ 1));
-               Arg := Arg + 2;
-
-            elsif Argument (Arg) = "--repeat_count" then
-               Result.Repeat_Count := Integer'Value (Argument (Arg + 1));
-               Arg := Arg + 2;
-
-            elsif Argument (Arg) = "--task_count" then
-               Parser.Table.McKenzie_Param.Task_Count := 
System.Multiprocessors.CPU_Range'Value (Argument (Arg + 1));
-               Arg := Arg + 2;
-
-            else
-               Ada.Text_IO.Put_Line ("unrecognized option: '" & Argument (Arg) 
& "'");
-               Usage (Parser);
-               Set_Exit_Status (Failure);
-               raise SAL.Parameter_Error;
-            end if;
-         end loop;
-      end return;
-   exception
-   when Finish =>
-      raise;
-
-   when E : others =>
-      Ada.Text_IO.Put_Line (Ada.Exceptions.Exception_Name (E) & ": " & 
Ada.Exceptions.Exception_Message (E));
-      Usage (Parser);
-      Set_Exit_Status (Failure);
-      raise SAL.Parameter_Error;
-   end Get_CL_Params;
-
-   procedure Parse_File
-     (Parser     : in out WisiToken.Parse.LR.Parser.Parser;
-      Parse_Data : in out Wisi.Parse_Data_Type'Class;
-      Descriptor : in     WisiToken.Descriptor)
-   is
-      use Ada.Text_IO;
-      use WisiToken;
-
-      Start     : Ada.Real_Time.Time;
-      End_Line  : WisiToken.Line_Number_Type;
-
-      function Image_Augmented (Aug : in Base_Token_Class_Access) return String
-      is begin
-         --  For Syntax_Trees.Print_Tree
-         return Wisi.Image (Aug, Descriptor);
-      end Image_Augmented;
-
-   begin
-      Parser.Trace.Set_Prefix (";; "); -- so we get the same debug messages as 
Emacs_Wisi_Common_Parse
-
-      declare
-         Cl_Params : constant Command_Line_Params := Get_CL_Params (Parser);
-      begin
-         begin
-            case Cl_Params.Command is
-            when Parse =>
-               Parser.Lexer.Reset_With_File
-                 (-Cl_Params.Source_File_Name, Cl_Params.Begin_Byte_Pos, 
Cl_Params.End_Byte_Pos,
-                  Cl_Params.Begin_Char_Pos, Cl_Params.Begin_Line);
-            when Refactor =>
-               Parser.Lexer.Reset_With_File (-Cl_Params.Source_File_Name);
-            end case;
-         exception
-         when Ada.IO_Exceptions.Name_Error =>
-            Put_Line (Standard_Error, "'" & (-Cl_Params.Source_File_Name) & "' 
cannot be opened");
-            return;
-         end;
-
-         --  Parser.Line_Begin_Token First, Last set by Lex_All
-
-         if Cl_Params.Command = Refactor or else Cl_Params.End_Line = 
Invalid_Line_Number then
-            --  User did not provide; run lexer to get end line.
-            declare
-               Token       : Base_Token;
-               Lexer_Error : Boolean;
-               pragma Unreferenced (Lexer_Error);
-            begin
-               loop
-                  Lexer_Error := Parser.Lexer.Find_Next (Token);
-                  exit when Token.ID = Descriptor.EOI_ID;
-               end loop;
-               End_Line := Token.Line;
-            end;
-         else
-            End_Line := Cl_Params.End_Line;
-         end if;
-
-         Parse_Data.Initialize
-           (Post_Parse_Action =>
-              (case Cl_Params.Command is
-               when Parse    => Cl_Params.Post_Parse_Action,
-               when Refactor => Wisi.Navigate),
-            Lexer            => Parser.Lexer,
-            Descriptor       => Descriptor'Unrestricted_Access,
-            Base_Terminals   => Parser.Terminals'Unrestricted_Access,
-            Begin_Line       =>
-              (case Cl_Params.Command is
-               when Parse => Cl_Params.Begin_Line,
-               when Refactor => WisiToken.Line_Number_Type'First),
-            End_Line         => End_Line,
-            Begin_Indent     =>
-              (case Cl_Params.Command is
-               when Parse    => Cl_Params.Begin_Indent,
-               when Refactor => 0),
-            Params            => -Cl_Params.Lang_Params);
-
-         if Cl_Params.Repeat_Count > 1 then
-            Start := Ada.Real_Time.Clock;
-         end if;
-
-         for I in 1 .. Cl_Params.Repeat_Count loop
-            declare
-               procedure Clean_Up
-               is
-                  use all type SAL.Base_Peek_Type;
-               begin
-                  Parser.Lexer.Discard_Rest_Of_Input;
-                  if Cl_Params.Repeat_Count = 1 and Parser.Parsers.Count > 0 
then
-                     Parse_Data.Put
-                       (Parser.Lexer.Errors,
-                        Parser.Parsers.First.State_Ref.Errors,
-                        Parser.Parsers.First.State_Ref.Tree);
-                  end if;
-               end Clean_Up;
-
-            begin
-               Parse_Data.Reset;
-               Parser.Lexer.Reset;
-
-               begin
-                  Parser.Parse;
-               exception
-               when WisiToken.Partial_Parse =>
-                  null;
-               end;
-
-               Parser.Execute_Actions (Image_Augmented'Unrestricted_Access);
-
-               case Cl_Params.Command is
-               when Parse =>
-                  if Cl_Params.Repeat_Count = 1 then
-                     Parse_Data.Put (Parser);
-                     Parse_Data.Put
-                       (Parser.Lexer.Errors,
-                        Parser.Parsers.First.State_Ref.Errors,
-                        Parser.Parsers.First.State_Ref.Tree);
-                  end if;
-
-               when Refactor =>
-                  Parse_Data.Refactor
-                    (Parser.Parsers.First_State_Ref.Tree,
-                     Cl_Params.Refactor_Action, Cl_Params.Edit_Begin);
-               end case;
-            exception
-            when WisiToken.Syntax_Error =>
-               Clean_Up;
-               Put_Line ("(parse_error)");
-
-            when E : WisiToken.Parse_Error =>
-               Clean_Up;
-               Put_Line ("(parse_error """ & Ada.Exceptions.Exception_Name (E) 
& " " &
-                           Ada.Exceptions.Exception_Message (E) & """)");
-
-            when E : others => -- includes Fatal_Error
-               Clean_Up;
-               Put_Line ("(error """ & Ada.Exceptions.Exception_Name (E) & " " 
&
-                           Ada.Exceptions.Exception_Message (E) & """)");
-            end;
-         end loop;
-
-         if Cl_Params.Repeat_Count > 1 then
-            declare
-               use Ada.Real_Time;
-               Finish : constant Time := Clock;
-            begin
-               Put_Line ("Total time:" & Duration'Image (To_Duration (Finish - 
Start)));
-               Put_Line ("per iteration:" & Duration'Image (To_Duration 
((Finish - Start) / Cl_Params.Repeat_Count)));
-            end;
-         end if;
-      end;
-   exception
-   when SAL.Parameter_Error | Finish =>
-      --  From Get_CL_Params; already handled.
-      null;
-
-   when E : others =>
-      Ada.Command_Line.Set_Exit_Status (Ada.Command_Line.Failure);
-      New_Line (2);
-      Put_Line
-        ("(error ""unhandled exception: " & Ada.Exceptions.Exception_Name (E) 
& ": " &
-           Ada.Exceptions.Exception_Message (E) & """)");
-   end Parse_File;
-
-end Run_Wisi_Common_Parse;
diff --git a/packages/wisi/run_wisi_common_parse.ads 
b/packages/wisi/run_wisi_common_parse.ads
deleted file mode 100644
index c00d007..0000000
--- a/packages/wisi/run_wisi_common_parse.ads
+++ /dev/null
@@ -1,73 +0,0 @@
---  Abstract :
---
---  Common utilities for Gen_Run_Wisi_*_Parse
---
---  Copyright (C) 2018 - 2019 Free Software Foundation, Inc.
---
---  This program is free software; you can redistribute it and/or
---  modify it under terms of the GNU General Public License as
---  published by the Free Software Foundation; either version 3, 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
---  distributed with this program; see file COPYING. If not, write to
---  the Free Software Foundation, 51 Franklin Street, Suite 500, Boston,
---  MA 02110-1335, USA.
-
-pragma License (GPL);
-
-with Ada.Strings.Unbounded;
-with Wisi;
-with WisiToken.Parse.LR.Parser;
-package Run_Wisi_Common_Parse is
-
-   Finish : exception;
-
-   procedure Usage (Parser : in out WisiToken.Parse.LR.Parser.Parser);
-   --  Puts parameter description to Current_Output.
-
-   type Command_Type is (Parse, Refactor);
-
-   type Command_Line_Params (Command : Command_Type) is record
-
-      Source_File_Name : Ada.Strings.Unbounded.Unbounded_String;
-      Lang_Params      : Ada.Strings.Unbounded.Unbounded_String;
-      Repeat_Count     : Integer := 1;
-
-      case Command is
-      when Parse =>
-         Post_Parse_Action : Wisi.Post_Parse_Action_Type;
-         Begin_Byte_Pos    : WisiToken.Buffer_Pos       := 
WisiToken.Invalid_Buffer_Pos;
-         End_Byte_Pos      : WisiToken.Buffer_Pos       := 
WisiToken.Invalid_Buffer_Pos;
-         Goal_Byte_Pos     : WisiToken.Buffer_Pos       := 
WisiToken.Invalid_Buffer_Pos;
-         Begin_Char_Pos    : WisiToken.Buffer_Pos       := 
WisiToken.Buffer_Pos'First;
-         Begin_Line        : WisiToken.Line_Number_Type := 
WisiToken.Line_Number_Type'First;
-         End_Line          : WisiToken.Line_Number_Type := 
WisiToken.Invalid_Line_Number;
-         Begin_Indent      : Integer                    := 0;
-
-      when Refactor =>
-         --  We assume the file contains only the one statement/declaration
-         --  that needs refactoring.
-
-         Refactor_Action : Positive;
-         --  Language-specific
-
-         Edit_Begin : WisiToken.Buffer_Pos;
-         --  Source file byte position at start of expression to refactor.
-      end case;
-   end record;
-
-   function Get_CL_Params (Parser : in out WisiToken.Parse.LR.Parser.Parser) 
return Command_Line_Params;
-   --  For any errors, calls Usage, raises SAL.Parameter_Error.
-   --
-   --  Handles --help by outputing help, raising Finish.
-
-   procedure Parse_File
-     (Parser     : in out WisiToken.Parse.LR.Parser.Parser;
-      Parse_Data : in out Wisi.Parse_Data_Type'Class;
-      Descriptor : in     WisiToken.Descriptor);
-   --  Calls Get_CL_Params, reads in file, parses, does post-parse actions.
-
-end Run_Wisi_Common_Parse;
diff --git a/packages/wisi/sal-ada_containers-gen_doubly_linked_lists_image.adb 
b/packages/wisi/sal-ada_containers-gen_doubly_linked_lists_image.adb
deleted file mode 100644
index a5dd042..0000000
--- a/packages/wisi/sal-ada_containers-gen_doubly_linked_lists_image.adb
+++ /dev/null
@@ -1,50 +0,0 @@
---  Abstract :
---
---  See spec.
---
---  Copyright (C) 2019 Free Software Foundation, Inc.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-with Ada.Strings.Unbounded;
-function SAL.Ada_Containers.Gen_Doubly_Linked_Lists_Image
-  (Item   : in Lists.List;
-   Strict : in Boolean := False)
-  return String
-is
-   use all type Ada.Containers.Count_Type;
-   use Ada.Strings;
-   use Ada.Strings.Unbounded;
-   Result     : Unbounded_String := To_Unbounded_String ("(");
-   Need_Comma : Boolean          := False;
-begin
-   if Strict and Item.Length = 0 then
-      return "(1 .. 0 => <>)";
-
-   elsif Strict and Item.Length = 1 then
-      return "(1 => " & Element_Image (Lists.Element (Item.First)) & ")";
-
-   else
-      for El of Item loop
-         if Need_Comma then
-            Result := Result & ", ";
-         else
-            Need_Comma := True;
-         end if;
-         Result := Result & Element_Image (El);
-      end loop;
-      Result := Result & ")";
-      return To_String (Result);
-   end if;
-end SAL.Ada_Containers.Gen_Doubly_Linked_Lists_Image;
diff --git a/packages/wisi/sal-ada_containers-gen_doubly_linked_lists_image.ads 
b/packages/wisi/sal-ada_containers-gen_doubly_linked_lists_image.ads
deleted file mode 100644
index 39e9b9e..0000000
--- a/packages/wisi/sal-ada_containers-gen_doubly_linked_lists_image.ads
+++ /dev/null
@@ -1,28 +0,0 @@
---  Abstract :
---
---  Image for normal Ada array types
---
---  Copyright (C) 2019 Free Software Foundation, Inc.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-with Ada.Containers.Doubly_Linked_Lists;
-generic
-   type Element_Type is private;
-   with function "=" (Left, Right : Element_Type) return Boolean is <>;
-   with package Lists is new Ada.Containers.Doubly_Linked_Lists (Element_Type, 
"=");
-   with function Element_Image (Item : in Element_Type) return String;
-function SAL.Ada_Containers.Gen_Doubly_Linked_Lists_Image
-  (Item   : in Lists.List;
-   Strict : in Boolean := False)
-  return String;
diff --git a/packages/wisi/sal-ada_containers.ads 
b/packages/wisi/sal-ada_containers.ads
deleted file mode 100644
index 4afad1e..0000000
--- a/packages/wisi/sal-ada_containers.ads
+++ /dev/null
@@ -1,21 +0,0 @@
---  Abstract :
---
---  Root of extensions to Ada.Containers.
---
---  Copyright (C) 2019 Free Software Foundation All Rights Reserved.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-package SAL.Ada_Containers is
-
-end SAL.Ada_Containers;
diff --git a/packages/wisi/sal-gen_array_image.adb 
b/packages/wisi/sal-gen_array_image.adb
deleted file mode 100644
index 7f9097d..0000000
--- a/packages/wisi/sal-gen_array_image.adb
+++ /dev/null
@@ -1,34 +0,0 @@
---  Abstract :
---
---  See spec.
---
---  Copyright (C) 2019 Free Software Foundation, Inc.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-with Ada.Strings.Unbounded; use Ada.Strings.Unbounded;
-function SAL.Gen_Array_Image (Item : in Array_Type) return String
-is
-   Result : Unbounded_String := To_Unbounded_String ("(");
-begin
-   for I in Item'Range loop
-      Result := Result & Element_Image (Item (I));
-      if I = Item'Last then
-         Result := Result & ")";
-      else
-         Result := Result & ", ";
-      end if;
-   end loop;
-   return To_String (Result);
-end SAL.Gen_Array_Image;
diff --git a/packages/wisi/sal-gen_array_image.ads 
b/packages/wisi/sal-gen_array_image.ads
deleted file mode 100644
index 53bd25f..0000000
--- a/packages/wisi/sal-gen_array_image.ads
+++ /dev/null
@@ -1,24 +0,0 @@
---  Abstract :
---
---  Image for normal Ada array types
---
---  Copyright (C) 2019 Free Software Foundation, Inc.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-generic
-   type Index_Type is (<>);
-   type Element_Type is private;
-   type Array_Type is array (Index_Type) of Element_Type;
-   with function Element_Image (Item : in Element_Type) return String;
-function SAL.Gen_Array_Image (Item : in Array_Type) return String;
diff --git a/packages/wisi/sal-gen_bounded_definite_queues.adb 
b/packages/wisi/sal-gen_bounded_definite_queues.adb
deleted file mode 100644
index 71b68c5..0000000
--- a/packages/wisi/sal-gen_bounded_definite_queues.adb
+++ /dev/null
@@ -1,103 +0,0 @@
---  Abstract:
---
---  See spec.
---
---  Copyright (C) 2004, 2008, 2009, 2011, 2017, 2019 Free Software Foundation 
All Rights Reserved.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
---
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-package body SAL.Gen_Bounded_Definite_Queues
-  with Spark_Mode
-is
-   pragma Suppress (All_Checks);
-
-   ----------
-   --  Public subprograms
-
-   procedure Clear (Queue : in out Queue_Type) is
-   begin
-      Queue.Count := 0;
-   end Clear;
-
-   function Count (Queue : in Queue_Type) return Base_Peek_Type is 
(Queue.Count);
-
-   function Is_Empty (Queue : in Queue_Type) return Boolean is
-   begin
-      return Queue.Count = 0;
-   end Is_Empty;
-
-   function Is_Full (Queue : in Queue_Type) return Boolean is
-   begin
-      return Queue.Count = Queue.Size;
-   end Is_Full;
-
-   procedure Remove (Queue : in out Queue_Type; Item : out Item_Type)
-   is begin
-      Item := Queue.Data (Queue.Head);
-
-      Queue.Count := Queue.Count - 1;
-
-      if Queue.Count > 0 then
-         Queue.Head := Wrap (Queue.Size, Queue.Head + 1);
-      end if;
-   end Remove;
-
-   function Remove (Queue : in out Queue_Type) return Item_Type with
-     Spark_Mode => Off
-   is begin
-      return Item : Item_Type  do
-         Remove (Queue, Item);
-      end return;
-   end Remove;
-
-   procedure Drop (Queue : in out Queue_Type)
-   is begin
-      Queue.Count := Queue.Count - 1;
-
-      if Queue.Count > 0 then
-         Queue.Head := Wrap (Queue.Size, Queue.Head + 1);
-      end if;
-   end Drop;
-
-   function Peek (Queue : in Queue_Type; N : Peek_Type := 1) return Item_Type
-     is (Queue.Data (Wrap (Queue.Size, Queue.Head + N - 1)));
-   --  Expression function to allow use in Spark proofs of conditions in spec.
-
-   procedure Add (Queue : in out Queue_Type; Item : in Item_Type) is
-   begin
-      if Queue.Count = 0 then
-         Queue.Tail  := 1;
-         Queue.Head  := 1;
-         Queue.Count := 1;
-      else
-         Queue.Tail  := Wrap (Queue.Size, Queue.Tail + 1);
-         Queue.Count := Queue.Count + 1;
-      end if;
-      Queue.Data (Queue.Tail) := Item;
-   end Add;
-
-   procedure Add_To_Head (Queue : in out Queue_Type; Item : in Item_Type) is
-   begin
-      if Queue.Count = 0 then
-         Queue.Tail  := 1;
-         Queue.Head  := 1;
-         Queue.Count := 1;
-      else
-         Queue.Head  := Wrap (Queue.Size, Queue.Head - 1);
-         Queue.Count := Queue.Count + 1;
-      end if;
-      Queue.Data (Queue.Head) := Item;
-   end Add_To_Head;
-
-end SAL.Gen_Bounded_Definite_Queues;
diff --git a/packages/wisi/sal-gen_bounded_definite_queues.ads 
b/packages/wisi/sal-gen_bounded_definite_queues.ads
deleted file mode 100644
index 5614519..0000000
--- a/packages/wisi/sal-gen_bounded_definite_queues.ads
+++ /dev/null
@@ -1,117 +0,0 @@
---  Abstract:
---
---  A generic queue, allowing definite non-limited item types.
---
---  Copyright (C) 2004, 2008, 2009, 2011, 2017, 2019 Free Software Foundation  
All Rights Reserved.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
---
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-generic
-   type Item_Type is private;
-package SAL.Gen_Bounded_Definite_Queues
-  with Spark_Mode
-is
-   pragma Pure;
-   pragma Suppress (All_Checks); --  Users must check Is_Full before Add, 
Is_Empty before Remove.
-
-   subtype Size_Type is Peek_Type range 1 .. Peek_Type'Last / 2;
-   --  The upper limit is needed to avoid overflow in Peek.
-
-   type Queue_Type (Size : Size_Type) is private;
-   --  Size is maximum number of items in the queue.
-
-   procedure Clear (Queue : in out Queue_Type)
-   with Post => Count (Queue) = 0;
-   --  Empty Queue of all items.
-
-   function Count (Queue : in Queue_Type) return Base_Peek_Type;
-   --  Returns count of items in the Queue
-
-   function Is_Empty (Queue : in Queue_Type) return Boolean
-   with Post => Is_Empty'Result = (Count (Queue) = 0);
-   --  Returns true if no items are in Queue.
-
-   function Is_Full (Queue : in Queue_Type) return Boolean
-   with Post => Is_Full'Result = (Count (Queue) = Queue.Size);
-   --  Returns true if Queue is full.
-
-   procedure Remove (Queue : in out Queue_Type; Item : out Item_Type) with
-     Pre  => Count (Queue) > 0,
-     Post => Count (Queue) = Count (Queue)'Old - 1 and Item = Peek (Queue'Old) 
and
-             (for all I in 1 .. Count (Queue) => Peek (Queue'Old, I + 1) = 
Peek (Queue, I));
-   --  Remove head item from Queue, return it.
-
-   function Remove (Queue : in out Queue_Type) return Item_Type with
-     Spark_Mode => Off;
-
-   function Get (Queue : in out Queue_Type) return Item_Type renames Remove;
-
-   procedure Drop (Queue : in out Queue_Type) with
-     Pre  => Count (Queue) > 0,
-     Post => Count (Queue) = Count (Queue)'Old - 1 and
-             (for all I in 1 .. Count (Queue) => Peek (Queue'Old, I + 1) = 
Peek (Queue, I));
-   --  Remove head item from Queue, discard it.
-
-   function Peek (Queue : in Queue_Type; N : Peek_Type := 1) return Item_Type 
with
-     Pre  => Count (Queue) in 1 .. Queue.Size and N in 1 .. Count (Queue);
-   --  Return a copy of a queue item, without removing it. N = 1 is
-   --  the queue head.
-
-   procedure Add (Queue : in out Queue_Type; Item : in Item_Type) with
-     Pre  => Count (Queue) in 0 .. Queue.Size - 1,
-     Post => Count (Queue) = Count (Queue)'Old + 1 and Peek (Queue, Count 
(Queue)) = Item and
-             (for all I in 1 .. Count (Queue)'Old => Peek (Queue'Old, I) = 
Peek (Queue, I));
-   --  Add Item to the tail of Queue.
-
-   procedure Put (Queue : in out Queue_Type; Item : in Item_Type) renames Add;
-
-   procedure Add_To_Head (Queue : in out Queue_Type; Item : in Item_Type) with
-     Pre  => Count (Queue) in 0 .. Queue.Size - 1,
-     Post => Count (Queue) = Count (Queue)'Old + 1 and
-             (Peek (Queue) = Item and
-              (for all I in 2 .. Count (Queue) => Peek (Queue'Old, I - 1) = 
Peek (Queue, I)));
-   --  Add Item to the head of Queue.
-
-private
-
-   type Item_Array_Type is array (Peek_Type range <>) of Item_Type;
-
-   type Queue_Type (Size : Size_Type) is
-   record
-      Head  : Peek_Type      := 1;
-      Tail  : Peek_Type      := 1;
-      Count : Base_Peek_Type := 0;
-      Data  : Item_Array_Type (1 .. Size);
-      --  Add at Tail + 1, remove at Head. Count is current count;
-      --  easier to keep track of that than to compute Is_Empty for
-      --  each Add and Remove.
-      --
-      --  Empty is indicated by Count = 0; head and tail are arbitrary
-      --  in that case.
-   end record with
-     Type_Invariant =>
-       (Head in 1 .. Size and
-        Tail in 1 .. Size and
-        Count in 0 .. Size) and then
-       (Count = 0 or else Wrap (Size, Head + Count - 1) = Tail);
-
-   function Wrap (Size : in Size_Type; I : in Base_Peek_Type) return Peek_Type
-     is (if I > Size then I - Size
-         elsif I = 0 then Size
-         else I)
-     with
-       Pre  => I in 0 .. 2 * Size - 1,
-       Post => Wrap'Result in 1 .. Size;
-
-end SAL.Gen_Bounded_Definite_Queues;
diff --git a/packages/wisi/sal-gen_bounded_definite_stacks-gen_image_aux.adb 
b/packages/wisi/sal-gen_bounded_definite_stacks-gen_image_aux.adb
deleted file mode 100644
index 7dcd96f..0000000
--- a/packages/wisi/sal-gen_bounded_definite_stacks-gen_image_aux.adb
+++ /dev/null
@@ -1,42 +0,0 @@
---  Abstract :
---
---  See spec.
---
---  Copyright (C) 2019 Free Software Foundation, Inc.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-with Ada.Strings.Unbounded;
-function SAL.Gen_Bounded_Definite_Stacks.Gen_Image_Aux
-  (Item  : in Stack;
-   Aux   : in Aux_Data;
-   Depth : in SAL.Base_Peek_Type := 0)
-  return String
-is
-   use Ada.Strings.Unbounded;
-   Result : Unbounded_String        := To_Unbounded_String ("(");
-   Last   : constant Base_Peek_Type :=
-     (if Depth = 0
-      then Item.Top
-      else Base_Peek_Type'Min (Depth, Item.Top));
-begin
-   for I in 1 .. Last loop
-      Result := Result & Element_Image (Item.Peek (I), Aux);
-      if I /= Last then
-         Result := Result & ", ";
-      end if;
-   end loop;
-   Result := Result & ")";
-   return To_String (Result);
-end SAL.Gen_Bounded_Definite_Stacks.Gen_Image_Aux;
diff --git a/packages/wisi/sal-gen_bounded_definite_stacks-gen_image_aux.ads 
b/packages/wisi/sal-gen_bounded_definite_stacks-gen_image_aux.ads
deleted file mode 100644
index e960398..0000000
--- a/packages/wisi/sal-gen_bounded_definite_stacks-gen_image_aux.ads
+++ /dev/null
@@ -1,27 +0,0 @@
---  Abstract :
---
---  Image with auxiliary data for instantiations of parent.
---
---  Copyright (C) 2019 Free Software Foundation, Inc.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-generic
-   type Aux_Data (<>) is private;
-   with function Element_Image (Item : in Element_Type; Aux : in Aux_Data) 
return String;
-function SAL.Gen_Bounded_Definite_Stacks.Gen_Image_Aux
-  (Item  : in Stack;
-   Aux   : in Aux_Data;
-   Depth : in SAL.Base_Peek_Type := 0)
-  return String;
diff --git a/packages/wisi/sal-gen_bounded_definite_stacks.adb 
b/packages/wisi/sal-gen_bounded_definite_stacks.adb
deleted file mode 100644
index fc81daa..0000000
--- a/packages/wisi/sal-gen_bounded_definite_stacks.adb
+++ /dev/null
@@ -1,82 +0,0 @@
---  Abstract:
---
---  see spec
---
---  Copyright (C) 1998, 2003, 2009, 2015, 2017 - 2019 Free Software 
Foundation, Inc.
---
---  SAL is free software; you can redistribute it and/or modify it
---  under terms of the GNU General Public License as published by the
---  Free Software Foundation; either version 3, or (at your option)
---  any later version. SAL 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 distributed
---  with SAL; see file COPYING. If not, write to the Free Software
---  Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
---  USA.
---
---  As a special exception, if other files instantiate generics from
---  SAL, or you link SAL object files with other files to produce an
---  executable, that does not by itself cause the resulting executable
---  to be covered by the GNU General Public License. This exception
---  does not however invalidate any other reasons why the executable
---  file might be covered by the GNU Public License.
-
-pragma License (Modified_GPL);
-
-package body SAL.Gen_Bounded_Definite_Stacks
-  with Spark_Mode
-is
-   pragma Suppress (All_Checks);
-
-   procedure Clear (Stack : in out Sgbds.Stack)
-   is begin
-      Stack.Top := 0;
-   end Clear;
-
-   function Depth (Stack : in Sgbds.Stack) return Size_Type
-     is (Stack.Top);
-
-   function Is_Empty (Stack : in Sgbds.Stack) return Boolean
-   is begin
-      return Stack.Top = 0;
-   end Is_Empty;
-
-   function Is_Full (Stack : in Sgbds.Stack) return Boolean
-   is begin
-      return Stack.Top = Stack.Size;
-   end Is_Full;
-
-   function Peek
-     (Stack : in Sgbds.Stack;
-      Index : in Peek_Type := 1)
-     return Element_Type
-     is (Stack.Data (Stack.Top - Index + 1));
-
-   procedure Pop (Stack : in out Sgbds.Stack; Count : in Base_Peek_Type := 1)
-   is begin
-      Stack.Top := Stack.Top - Count;
-   end Pop;
-
-   procedure Pop (Stack : in out Sgbds.Stack; Item : out Element_Type)
-   is begin
-      Item := Stack.Peek (1);
-      Stack.Top := Stack.Top - 1;
-   end Pop;
-
-   function Pop (Stack : in out Sgbds.Stack) return Element_Type with
-     Spark_Mode => Off
-   is begin
-      return Result : Element_Type do
-         Pop (Stack, Result);
-      end return;
-   end Pop;
-
-   procedure Push (Stack : in out Sgbds.Stack; Item : in Element_Type)
-   is begin
-      Stack.Top := Stack.Top + 1;
-      Stack.Data (Stack.Top) := Item;
-   end Push;
-
-end SAL.Gen_Bounded_Definite_Stacks;
diff --git a/packages/wisi/sal-gen_bounded_definite_stacks.ads 
b/packages/wisi/sal-gen_bounded_definite_stacks.ads
deleted file mode 100644
index e2ba7ab..0000000
--- a/packages/wisi/sal-gen_bounded_definite_stacks.ads
+++ /dev/null
@@ -1,103 +0,0 @@
---  Abstract:
---
---  Bounded stack implementation, with full Spark verification,
---  optimized for speed.
---
---  Copyright (C) 1998-2000, 2002-2003, 2009, 2015, 2017 - 2020 Free Software 
Foundation, Inc.
---
---  SAL is free software; you can redistribute it and/or modify it
---  under terms of the GNU General Public License as published by the
---  Free Software Foundation; either version 3, or (at your option)
---  any later version. SAL 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 distributed
---  with SAL; see file COPYING. If not, write to the Free Software
---  Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
---  USA.
---
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-generic
-   type Element_Type is private;
-package SAL.Gen_Bounded_Definite_Stacks
-  with Spark_Mode
-is
-   pragma Pure;
-   --  pragma Suppress (All_Checks); --  Users must check Is_Full before Push, 
Is_Empty before Pop etc.
-
-   package Sgbds renames SAL.Gen_Bounded_Definite_Stacks;
-
-   subtype Size_Type is Base_Peek_Type range 0 .. Base_Peek_Type'Last / 2;
-   --  The upper limit is needed to avoid overflow in Peek.
-   --  Zero included for Depth result.
-
-   type Stack (Size : Size_Type) is tagged private;
-   --  Tagged to allow Object.Method notation.
-
-   --  No Empty_Stack constant, to avoid requiring a Default_Element.
-
-   procedure Clear (Stack : in out Sgbds.Stack)
-   with Post'Class => Depth (Stack) = 0;
-   --  Empty Stack of all items.
-
-   function Depth (Stack : in Sgbds.Stack) return Size_Type;
-   --  Returns current count of items in Stack
-
-   function Is_Empty (Stack : in Sgbds.Stack) return Boolean
-   with Post'Class => Is_Empty'Result = (Depth (Stack) = 0);
-   --  Returns true iff no items are in Stack.
-
-   function Is_Full (Stack : in Sgbds.Stack) return Boolean
-   with Post'Class => Is_Full'Result = (Depth (Stack) = Stack.Size);
-   --  Returns true iff Stack is full.
-
-   function Peek (Stack : in Sgbds.Stack; Index : in Peek_Type := 1) return 
Element_Type
-   with Pre'Class  => Depth (Stack) in 1 .. Stack.Size and Index in 1 .. Depth 
(Stack);
-   --  Return the Index'th item from the top of Stack; the Item is _not_ 
removed.
-   --  Top item has index 1.
-
-   procedure Pop (Stack : in out Sgbds.Stack; Count : in Base_Peek_Type := 1) 
with
-     Pre'Class  => Depth (Stack) in 1 .. Stack.Size and Count in 0 .. Depth 
(Stack),
-     Post'Class => Depth (Stack) = Depth (Stack)'Old - Count and then
-                   (for all I in 1 .. Depth (Stack) => Peek (Stack'Old, I + 
Count) = Peek (Stack, I));
-   --  Remove Count Items from the top of Stack, discard them.
-
-   procedure Pop (Stack : in out Sgbds.Stack; Item : out Element_Type) with
-     Pre'Class  => Depth (Stack) in 1 .. Stack.Size,
-     Post'Class =>
-       Depth (Stack) = Depth (Stack)'Old - 1 and then
-       (Item = Peek (Stack'Old) and
-        (for all I in 1 .. Depth (Stack) => Peek (Stack'Old, I + 1) = Peek 
(Stack, I)));
-   --  Remove one item from the top of Stack, return in Item.
-
-   function Pop (Stack : in out Sgbds.Stack) return Element_Type with
-     Spark_Mode => Off;
-   --  Remove one item from the top of Stack, and return it.
-
-   procedure Push (Stack : in out Sgbds.Stack; Item : in Element_Type) with
-     Pre'Class  => Depth (Stack) in 0 .. Stack.Size - 1,
-     Post'Class =>
-       Depth (Stack) = Depth (Stack)'Old + 1 and then
-       (Item = Peek (Stack) and
-        (for all I in 1 .. Depth (Stack'Old) => Peek (Stack'Old, I) = Peek 
(Stack, I + 1)));
-   --  Add Item to the top of Stack.
-
-private
-
-   type Element_Array is array (Size_Type range <>) of aliased Element_Type;
-
-   type Stack (Size : Size_Type) is tagged record
-      Top  : Base_Peek_Type := Invalid_Peek_Index; -- empty
-      Data : Element_Array (1 .. Size);
-      --  Top of stack is at Data (Top).
-      --  Data (1 .. Top) has been set at some point.
-   end record with
-     Dynamic_Predicate => Stack.Top in 0 .. Stack.Size;
-
-end SAL.Gen_Bounded_Definite_Stacks;
diff --git a/packages/wisi/sal-gen_bounded_definite_vectors-gen_image.adb 
b/packages/wisi/sal-gen_bounded_definite_vectors-gen_image.adb
deleted file mode 100644
index ae901fe..0000000
--- a/packages/wisi/sal-gen_bounded_definite_vectors-gen_image.adb
+++ /dev/null
@@ -1,40 +0,0 @@
---  Abstract :
---
---  See spec.
---
---  Copyright (C) 2018 - 2019 Free Software Foundation, Inc.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-with Ada.Strings.Fixed;
-with Ada.Strings.Unbounded;
-function SAL.Gen_Bounded_Definite_Vectors.Gen_Image (Item : in Vector) return 
String
-is
-   use Ada.Strings;
-   use Ada.Strings.Unbounded;
-   Result : Unbounded_String        := To_Unbounded_String ("(");
-   Last   : constant Base_Peek_Type := To_Peek_Index (Item.Last);
-begin
-   for I in 1 .. Last loop
-      Result := Result &
-        (if Trim
-         then Fixed.Trim (Element_Image (Item.Elements (I)), Left)
-         else Element_Image (Item.Elements (I)));
-      if I /= Last then
-         Result := Result & ", ";
-      end if;
-   end loop;
-   Result := Result & ")";
-   return To_String (Result);
-end SAL.Gen_Bounded_Definite_Vectors.Gen_Image;
diff --git a/packages/wisi/sal-gen_bounded_definite_vectors-gen_image.ads 
b/packages/wisi/sal-gen_bounded_definite_vectors-gen_image.ads
deleted file mode 100644
index 950b9d0..0000000
--- a/packages/wisi/sal-gen_bounded_definite_vectors-gen_image.ads
+++ /dev/null
@@ -1,23 +0,0 @@
---  Abstract :
---
---  Image for instantiations of parent.
---
---  Copyright (C) 2018 Free Software Foundation, Inc.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-generic
-   with function Element_Image (Item : in Element_Type) return String;
-   Trim : in Boolean;
-function SAL.Gen_Bounded_Definite_Vectors.Gen_Image (Item : in Vector) return 
String;
diff --git a/packages/wisi/sal-gen_bounded_definite_vectors-gen_image_aux.adb 
b/packages/wisi/sal-gen_bounded_definite_vectors-gen_image_aux.adb
deleted file mode 100644
index 685ef13..0000000
--- a/packages/wisi/sal-gen_bounded_definite_vectors-gen_image_aux.adb
+++ /dev/null
@@ -1,35 +0,0 @@
---  Abstract :
---
---  See spec.
---
---  Copyright (C) 2018 Free Software Foundation, Inc.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-with Ada.Strings.Unbounded;
-function SAL.Gen_Bounded_Definite_Vectors.Gen_Image_Aux (Item : in Vector; Aux 
: in Aux_Data) return String
-is
-   use Ada.Strings.Unbounded;
-   Result : Unbounded_String        := To_Unbounded_String ("(");
-   Last   : constant Base_Peek_Type := To_Peek_Index (Item.Last);
-begin
-   for I in 1 .. Last loop
-      Result := Result & Element_Image (Item.Elements (I), Aux);
-      if I /= Last then
-         Result := Result & ", ";
-      end if;
-   end loop;
-   Result := Result & ")";
-   return To_String (Result);
-end SAL.Gen_Bounded_Definite_Vectors.Gen_Image_Aux;
diff --git a/packages/wisi/sal-gen_bounded_definite_vectors-gen_image_aux.ads 
b/packages/wisi/sal-gen_bounded_definite_vectors-gen_image_aux.ads
deleted file mode 100644
index 241e67b..0000000
--- a/packages/wisi/sal-gen_bounded_definite_vectors-gen_image_aux.ads
+++ /dev/null
@@ -1,23 +0,0 @@
---  Abstract :
---
---  Image with auxiliary data for instantiations of parent.
---
---  Copyright (C) 2018 Free Software Foundation, Inc.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-generic
-   type Aux_Data (<>) is private;
-   with function Element_Image (Item : in Element_Type; Aux : in Aux_Data) 
return String;
-function SAL.Gen_Bounded_Definite_Vectors.Gen_Image_Aux (Item : in Vector; Aux 
: in Aux_Data) return String;
diff --git a/packages/wisi/sal-gen_bounded_definite_vectors-gen_refs.adb 
b/packages/wisi/sal-gen_bounded_definite_vectors-gen_refs.adb
deleted file mode 100644
index 8f9d741..0000000
--- a/packages/wisi/sal-gen_bounded_definite_vectors-gen_refs.adb
+++ /dev/null
@@ -1,35 +0,0 @@
---  Abstract :
---
---  See spec.
---
---  Copyright (C) 2019 Free Software Foundation, Inc.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-package body SAL.Gen_Bounded_Definite_Vectors.Gen_Refs is
-
-   function Variable_Ref
-     (Container : aliased in out Vector;
-      Index     :         in     Index_Type)
-     return Variable_Reference_Type
-   is begin
-      return (Element => Container.Elements (To_Peek_Index (Index))'Access, 
Dummy => 1);
-   end Variable_Ref;
-
-   function Constant_Ref (Container : aliased in Vector; Index : in 
Index_Type) return Constant_Reference_Type
-   is begin
-      return (Element => Container.Elements (To_Peek_Index (Index))'Access, 
Dummy => 1);
-   end Constant_Ref;
-
-end SAL.Gen_Bounded_Definite_Vectors.Gen_Refs;
diff --git a/packages/wisi/sal-gen_bounded_definite_vectors-gen_refs.ads 
b/packages/wisi/sal-gen_bounded_definite_vectors-gen_refs.ads
deleted file mode 100644
index c235cbc..0000000
--- a/packages/wisi/sal-gen_bounded_definite_vectors-gen_refs.ads
+++ /dev/null
@@ -1,54 +0,0 @@
---  Abstract :
---
---  Variable_Reference for parent.
---
---  In a child package because it's not Spark, and Spark does not
---  allow 'Spark_Mode => Off' on type declarations.
---
---  Copyright (C) 2019 Free Software Foundation, Inc.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-generic
-package SAL.Gen_Bounded_Definite_Vectors.Gen_Refs
-  with Spark_Mode => Off
-is
-
-   type Variable_Reference_Type (Element : not null access Element_Type) is 
private with
-     Implicit_Dereference => Element;
-
-   function Variable_Ref (Container : aliased in out Vector; Index : in 
Index_Type) return Variable_Reference_Type
-   with Inline,
-     Pre => Index in Index_Type'First .. Last_Index (Container);
-
-   type Constant_Reference_Type (Element : not null access constant 
Element_Type) is private with
-     Implicit_Dereference => Element;
-
-   function Constant_Ref (Container : aliased in Vector; Index : in 
Index_Type) return Constant_Reference_Type
-   with Inline,
-     Pre => Index in Index_Type'First .. Last_Index (Container);
-
-private
-
-   type Variable_Reference_Type (Element : not null access Element_Type) is
-   record
-      Dummy : Integer := raise Program_Error with "uninitialized reference";
-   end record;
-
-   type Constant_Reference_Type (Element : not null access constant 
Element_Type) is
-   record
-      Dummy : Integer := raise Program_Error with "uninitialized reference";
-   end record;
-
-end SAL.Gen_Bounded_Definite_Vectors.Gen_Refs;
diff --git a/packages/wisi/sal-gen_bounded_definite_vectors.adb 
b/packages/wisi/sal-gen_bounded_definite_vectors.adb
deleted file mode 100644
index 17aac08..0000000
--- a/packages/wisi/sal-gen_bounded_definite_vectors.adb
+++ /dev/null
@@ -1,120 +0,0 @@
---  Abstract :
---
---  See spec.
---
---  Copyright (C) 2017 - 2019 Free Software Foundation, Inc.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-package body SAL.Gen_Bounded_Definite_Vectors
-  with Spark_Mode
-is
-   pragma Suppress (All_Checks);
-
-   function Length (Container : in Vector) return Ada.Containers.Count_Type
-   is (Ada.Containers.Count_Type (To_Peek_Index (Container.Last)));
-
-   function Is_Full (Container : in Vector) return Boolean
-   is begin
-      return Length (Container) = Capacity;
-   end Is_Full;
-
-   procedure Clear (Container : in out Vector)
-   is begin
-      Container.Last := No_Index;
-   end Clear;
-
-   function Element (Container : Vector; Index : Index_Type) return 
Element_Type
-   is (Container.Elements (Peek_Type (Index - Index_Type'First + 1)));
-
-   procedure Replace_Element
-     (Container : in out Vector;
-      Index     : in     Index_Type;
-      New_Item  : in     Element_Type)
-   is begin
-      Container.Elements (To_Peek_Index (Index)) := New_Item;
-   end Replace_Element;
-
-   function Last_Index (Container : Vector) return Extended_Index
-   is (Container.Last);
-
-   procedure Append (Container : in out Vector; New_Item : in Element_Type)
-   is
-      J : constant Peek_Type := To_Peek_Index (Container.Last + 1);
-   begin
-      Container.Elements (J) := New_Item;
-      Container.Last := Container.Last + 1;
-   end Append;
-
-   procedure Prepend (Container : in out Vector; New_Item : in Element_Type)
-   is
-      J : constant Peek_Type := Peek_Type (Container.Last + 1 - 
Index_Type'First + 1);
-   begin
-      Container.Elements (2 .. J) := Container.Elements (1 .. J - 1);
-      Container.Elements (1) := New_Item;
-      Container.Last := Container.Last + 1;
-   end Prepend;
-
-   procedure Insert
-     (Container : in out Vector;
-      New_Item  : in     Element_Type;
-      Before    : in     Extended_Index)
-   is
-      J : constant Peek_Type := To_Peek_Index ((if Before = No_Index then 
Container.Last + 1 else Before));
-      K : constant Base_Peek_Type := To_Peek_Index (Container.Last);
-   begin
-      Container.Elements (J + 1 .. K + 1) := Container.Elements (J .. K);
-      Container.Elements (J) := New_Item;
-      Container.Last := Container.Last + 1;
-   end Insert;
-
-   function "+" (Item : in Element_Type) return Vector
-   is begin
-      return Result : Vector do
-         Append (Result, Item);
-      end return;
-   end "+";
-
-   function "&" (Left : in Vector; Right : in Element_Type) return Vector
-   is begin
-      --  WORKAROUND: If init Result with ":= Left", GNAT Community 2019
-      --  checks Default_Initial_Condition (which fails when Left is not
-      --  empty)! That is only supposed to be checked when initialized by
-      --  default. Reported to AdaCore as ticket S724-042.
-      return Result : Vector do
-         Result := Left;
-         Append (Result, Right);
-      end return;
-   end "&";
-
-   procedure Delete_First (Container : in out Vector; Count : in 
Ada.Containers.Count_Type := 1)
-   is
-      use Ada.Containers;
-   begin
-      if Count = 0 then
-         return;
-      end if;
-
-      declare
-         New_Last : constant Extended_Index := Extended_Index (Integer 
(Container.Last) - Integer (Count));
-         J        : constant Base_Peek_Type := Base_Peek_Type (Count);
-         K        : constant Peek_Type      := To_Peek_Index (Container.Last);
-      begin
-         --  Delete items 1 .. J, shift remaining down.
-         Container.Elements (1 .. K - J) := Container.Elements (J + 1 .. K);
-         Container.Last := New_Last;
-      end;
-   end Delete_First;
-
-end SAL.Gen_Bounded_Definite_Vectors;
diff --git a/packages/wisi/sal-gen_bounded_definite_vectors.ads 
b/packages/wisi/sal-gen_bounded_definite_vectors.ads
deleted file mode 100644
index 9e698e2..0000000
--- a/packages/wisi/sal-gen_bounded_definite_vectors.ads
+++ /dev/null
@@ -1,145 +0,0 @@
---  Abstract :
---
---  A simple bounded vector of definite items, in Spark.
---
---  Copyright (C) 2017 - 2019 Free Software Foundation, Inc.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-generic
-   type Index_Type is range <>;
-   type Element_Type is private;
-   Capacity : in Ada.Containers.Count_Type;
-package SAL.Gen_Bounded_Definite_Vectors
-  with Spark_Mode
-is
-   use all type Ada.Containers.Count_Type;
-
-   subtype Extended_Index is Index_Type'Base
-     range Index_Type'First - 1 ..
-           Index_Type'Min (Index_Type'Base'Last - 1, Index_Type'Last) + 1;
-
-   pragma Assert (Capacity <= Ada.Containers.Count_Type (Index_Type'Last - 
Index_Type'First + 1));
-
-   No_Index : constant Extended_Index := Extended_Index'First;
-
-   type Vector is private with
-     Default_Initial_Condition => Length (Vector) = 0;
-
-   function Length (Container : in Vector) return Ada.Containers.Count_Type 
with
-     Post => Length'Result in 0 .. Capacity;
-
-   function Is_Full (Container : in Vector) return Boolean with
-     Post => Is_Full'Result = (Length (Container) = Capacity);
-
-   function Has_Space (Container : in Vector; Item_Count : in 
Ada.Containers.Count_Type) return Boolean
-     is (Length (Container) + Item_Count <= Capacity)
-     with Pre => Item_Count <= Ada.Containers.Count_Type'Last - Length 
(Container);
-
-   procedure Clear (Container : in out Vector) with
-     Post => Length (Container) = 0;
-
-   function First_Index (Container : in Vector) return Index_Type is 
(Index_Type'First) with
-       Depends => (First_Index'Result => null, null => Container);
-
-   function Last_Index (Container : in Vector) return Extended_Index;
-   --  No_Index when Container is empty.
-
-   function Element (Container : in Vector; Index : in Index_Type) return 
Element_Type
-   with Pre => Index <= Last_Index (Container);
-   --  Index of first element in Vector is Index_Type'First.
-
-   procedure Replace_Element
-     (Container : in out Vector;
-      Index     : in     Index_Type;
-      New_Item  : in     Element_Type)
-   with
-     Pre  => Index <= Last_Index (Container),
-     Post => Element (Container, Index) = New_Item;
-   --  Index of first element in Vector is Index_Type'First.
-
-   procedure Append (Container : in out Vector; New_Item : in Element_Type) 
with
-     Pre  => Length (Container) < Capacity,
-     Post => Length (Container) = Length (Container'Old) + 1 and
-             Element (Container, Last_Index (Container)) = New_Item and
-             (for all I in Index_Type'First .. Last_Index (Container) - 1 =>
-                Element (Container'Old, I) = Element (Container, I));
-
-   procedure Prepend (Container : in out Vector; New_Item : in Element_Type) 
with
-     Pre  => Length (Container) < Capacity,
-     Post => Length (Container) = Length (Container'Old) + 1 and then
-             (Element (Container, Index_Type'First) = New_Item and
-              (for all I in Index_Type'First .. Last_Index (Container'Old) =>
-                 Element (Container'Old, I) = Element (Container, I + 1)));
-   --  Insert New_Item at beginning of Container; current elements slide right.
-
-   procedure Insert
-     (Container : in out Vector;
-      New_Item  : in     Element_Type;
-      Before    : in     Extended_Index) with
-     Pre  => Length (Container) < Capacity and Before <= Last_Index 
(Container),
-     Contract_Cases =>
-       (Before = No_Index =>
-          Length (Container) = Length (Container'Old) + 1 and
-          Element (Container, Last_Index (Container)) = New_Item and
-          (for all I in Index_Type'First .. Last_Index (Container) - 1 =>
-             Element (Container'Old, I) = Element (Container, I)),
-        Before /= No_Index =>
-          Length (Container) = Length (Container'Old) + 1 and
-          Element (Container, Before) = New_Item and
-             (for all I in Index_Type'First .. Before - 1 =>
-                Element (Container'Old, I) = Element (Container, I)) and
-             (for all I in Before + 1 .. Last_Index (Container) =>
-                Element (Container'Old, I - 1) = Element (Container, I)));
-   --  Insert New_Item before Before, or after Last_Index if Before is
-   --  No_Index. Current elements at Before and after slide right.
-   --  New_Item then has index Before.
-
-   function "+" (Item : in Element_Type) return Vector with
-     Post => Length ("+"'Result) = 1 and
-             Element ("+"'Result, Index_Type'First) = Item;
-
-   function "&" (Left : in Vector; Right : in Element_Type) return Vector with
-     Pre  => Length (Left) < Capacity,
-     Post => Length ("&"'Result) = Length (Left) + 1 and
-             (for all I in Index_Type'First .. Last_Index (Left) => Element 
(Left, I) = Element ("&"'Result, I)) and
-             Element ("&"'Result, Last_Index ("&"'Result)) = Right;
-
-   procedure Delete_First (Container : in out Vector; Count : in 
Ada.Containers.Count_Type := 1) with
-     Pre  => Length (Container) >= Count,
-     Post => Length (Container) = Length (Container)'Old - Count and then
-             (for all I in Index_Type'First .. Last_Index (Container) =>
-                Element (Container'Old, Index_Type (Integer (I) + Integer 
(Count))) = Element (Container, I));
-   --  Remaining elements slide down.
-
-private
-
-   type Array_Type is array (Peek_Type range 1 .. Peek_Type (Capacity)) of 
aliased Element_Type;
-
-   type Vector is
-   record
-      Elements : Array_Type;
-      Last     : Extended_Index := No_Index;
-   end record with
-     Type_Invariant => To_Peek_Index (Last) <= Elements'Last;
-   pragma Annotate (GNATprove, Intentional, "type ""Vector"" is not fully 
initialized",
-                    "Only items in Elements with index < Last are accessed");
-
-   ----------
-   --  For child units
-
-   function To_Peek_Index (Index : in Extended_Index) return Base_Peek_Type is
-     (Base_Peek_Type (Index - Index_Type'First + 1));
-
-end SAL.Gen_Bounded_Definite_Vectors;
diff --git 
a/packages/wisi/sal-gen_bounded_definite_vectors_sorted-gen_image_aux.adb 
b/packages/wisi/sal-gen_bounded_definite_vectors_sorted-gen_image_aux.adb
deleted file mode 100644
index cee9c74..0000000
--- a/packages/wisi/sal-gen_bounded_definite_vectors_sorted-gen_image_aux.adb
+++ /dev/null
@@ -1,35 +0,0 @@
---  Abstract :
---
---  See spec.
---
---  Copyright (C) 2019 Free Software Foundation, Inc.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-with Ada.Strings.Unbounded;
-function SAL.Gen_Bounded_Definite_Vectors_Sorted.Gen_Image_Aux (Item : in 
Vector; Aux : in Aux_Data) return String
-is
-   use Ada.Strings.Unbounded;
-   Result : Unbounded_String        := To_Unbounded_String ("(");
-   Last   : constant Base_Peek_Type := Item.Last;
-begin
-   for I in 1 .. Last loop
-      Result := Result & Element_Image (Item.Elements (I), Aux);
-      if I /= Last then
-         Result := Result & ", ";
-      end if;
-   end loop;
-   Result := Result & ")";
-   return To_String (Result);
-end SAL.Gen_Bounded_Definite_Vectors_Sorted.Gen_Image_Aux;
diff --git 
a/packages/wisi/sal-gen_bounded_definite_vectors_sorted-gen_image_aux.ads 
b/packages/wisi/sal-gen_bounded_definite_vectors_sorted-gen_image_aux.ads
deleted file mode 100644
index 28c56fd..0000000
--- a/packages/wisi/sal-gen_bounded_definite_vectors_sorted-gen_image_aux.ads
+++ /dev/null
@@ -1,23 +0,0 @@
---  Abstract :
---
---  Image with auxiliary data for instantiations of parent.
---
---  Copyright (C) 2019 Free Software Foundation, Inc.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-generic
-   type Aux_Data (<>) is private;
-   with function Element_Image (Item : in Element_Type; Aux : in Aux_Data) 
return String;
-function SAL.Gen_Bounded_Definite_Vectors_Sorted.Gen_Image_Aux (Item : in 
Vector; Aux : in Aux_Data) return String;
diff --git a/packages/wisi/sal-gen_bounded_definite_vectors_sorted-gen_refs.adb 
b/packages/wisi/sal-gen_bounded_definite_vectors_sorted-gen_refs.adb
deleted file mode 100644
index fb5d619..0000000
--- a/packages/wisi/sal-gen_bounded_definite_vectors_sorted-gen_refs.adb
+++ /dev/null
@@ -1,29 +0,0 @@
---  Abstract :
---
---  See spec.
---
---  Copyright (C) 2019 Free Software Foundation, Inc.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-package body SAL.Gen_Bounded_Definite_Vectors_Sorted.Gen_Refs is
-
-   function Constant_Ref (Container : aliased Vector; Index : in Peek_Type) 
return Constant_Reference_Type
-   is begin
-      return
-        (Element => Container.Elements (Index)'Access,
-         Dummy   => 1);
-   end Constant_Ref;
-
-end SAL.Gen_Bounded_Definite_Vectors_Sorted.Gen_Refs;
diff --git a/packages/wisi/sal-gen_bounded_definite_vectors_sorted-gen_refs.ads 
b/packages/wisi/sal-gen_bounded_definite_vectors_sorted-gen_refs.ads
deleted file mode 100644
index 17e98c4..0000000
--- a/packages/wisi/sal-gen_bounded_definite_vectors_sorted-gen_refs.ads
+++ /dev/null
@@ -1,39 +0,0 @@
---  Abstract :
---
---  Constant_Reference for parent.
---
---  In a child package because it's not Spark, and Spark does not
---  allow 'Spark_Mode => Off' on type declarations.
---
---  Copyright (C) 2019 Free Software Foundation, Inc.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-generic
-package SAL.Gen_Bounded_Definite_Vectors_Sorted.Gen_Refs is
-
-   type Constant_Reference_Type (Element : not null access constant 
Element_Type) is private with
-     Implicit_Dereference => Element;
-
-   function Constant_Ref (Container : aliased Vector; Index : in Peek_Type) 
return Constant_Reference_Type with
-     Inline;
-
-private
-
-   type Constant_Reference_Type (Element : not null access constant 
Element_Type) is
-   record
-      Dummy : Integer := raise Program_Error with "uninitialized reference";
-   end record;
-
-end SAL.Gen_Bounded_Definite_Vectors_Sorted.Gen_Refs;
diff --git a/packages/wisi/sal-gen_bounded_definite_vectors_sorted.adb 
b/packages/wisi/sal-gen_bounded_definite_vectors_sorted.adb
deleted file mode 100644
index 8b89a7f..0000000
--- a/packages/wisi/sal-gen_bounded_definite_vectors_sorted.adb
+++ /dev/null
@@ -1,96 +0,0 @@
---  Abstract :
---
---  See spec.
---
---  Copyright (C) 2018 - 2020 Free Software Foundation, Inc.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-package body SAL.Gen_Bounded_Definite_Vectors_Sorted is
-
-   function Length (Container : in Vector) return Ada.Containers.Count_Type
-     is (Ada.Containers.Count_Type (Container.Last));
-
-   function Is_Full (Container : in Vector) return Boolean
-   is begin
-      return Container.Last = Peek_Type (Capacity);
-   end Is_Full;
-
-   procedure Clear (Container : in out Vector)
-   is begin
-      Container.Last := No_Index;
-   end Clear;
-
-   function Last_Index (Container : in Vector) return Base_Peek_Type
-     is (Container.Last);
-
-   function Element (Container : in Vector; Index : in Peek_Type) return 
Element_Type
-     is (Container.Elements (Index));
-
-   procedure Insert
-     (Container       : in out Vector;
-      New_Item        : in     Element_Type;
-      Ignore_If_Equal : in     Boolean := False)
-   is
-      K : constant Base_Peek_Type := Container.Last;
-      J : Base_Peek_Type := K;
-   begin
-      if K = 0 then
-         --  Container empty
-         Container.Last := 1;
-         Container.Elements (1) := New_Item;
-         return;
-      end if;
-
-      loop
-         --  These seem obvious, but gnatprove needs them (in 2019).
-         pragma Loop_Invariant (J <= Container.Last);
-         pragma Loop_Invariant (J <= Container.Elements'Last);
-         pragma Loop_Variant (Decreases => J);
-
-         --  This is less obvious, helps a lot.
-         pragma Loop_Invariant
-           ((for all I in J + 1 .. Container.Last => Element_Compare
-             (New_Item, Container.Elements (I)) = Less));
-
-         exit when J < 1;
-
-         case Element_Compare (New_Item, Container.Elements (J)) is
-         when Less =>
-            J := J - 1;
-         when Equal =>
-            if Ignore_If_Equal then
-               return;
-            else
-               --  Insert after J
-               exit;
-            end if;
-         when Greater =>
-            --  Insert after J
-            exit;
-         end case;
-      end loop;
-
-      --  Note that this assertion is _not_ a Loop_Invariant; the whole
-      --  point here is to find the right J.
-      pragma Assert
-        (for all I in 1 .. J - 1 =>
-           Element_Compare (Container.Elements (I), New_Item) in Less | Equal);
-
-      Container.Elements (J + 2 .. K + 1) := Container.Elements (J + 1 .. K);
-      Container.Elements (J + 1) := New_Item;
-      Container.Last := Container.Last + 1;
-   end Insert;
-
-end SAL.Gen_Bounded_Definite_Vectors_Sorted;
diff --git a/packages/wisi/sal-gen_bounded_definite_vectors_sorted.ads 
b/packages/wisi/sal-gen_bounded_definite_vectors_sorted.ads
deleted file mode 100644
index e86fbca..0000000
--- a/packages/wisi/sal-gen_bounded_definite_vectors_sorted.ads
+++ /dev/null
@@ -1,100 +0,0 @@
---  Abstract :
---
---  A simple bounded sorted vector of definite items, in Spark.
---
---  Copyright (C) 2018 - 2020 Free Software Foundation, Inc.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-generic
-   type Element_Type is private;
-   with function Element_Compare (Left, Right : in Element_Type) return 
Compare_Result;
-   Capacity : in Ada.Containers.Count_Type;
-package SAL.Gen_Bounded_Definite_Vectors_Sorted
-  with Spark_Mode
-is
-   use all type Ada.Containers.Count_Type;
-
-   No_Index : constant Base_Peek_Type := 0;
-
-   type Vector is private with
-     Default_Initial_Condition => Last_Index (Vector) = No_Index;
-
-   function Length (Container : in Vector) return Ada.Containers.Count_Type 
with
-     Post => Length'Result in 0 .. Capacity;
-
-   function Is_Full (Container : in Vector) return Boolean with
-     Post => Is_Full'Result = (Length (Container) = Capacity);
-
-   procedure Clear (Container : in out Vector) with
-     Post => Last_Index (Container) = No_Index;
-
-   function First_Index (Container : in Vector) return Peek_Type
-     is (Peek_Type'First) with
-       Depends => (First_Index'Result => null, null => Container);
-
-   function Last_Index (Container : in Vector) return Base_Peek_Type with
-     Inline;
-
-   function Element (Container : in Vector; Index : in Peek_Type) return 
Element_Type with
-     Pre => Index in First_Index (Container) .. Last_Index (Container);
-
-   function Is_Sorted (Container : in Vector) return Boolean is
-     --  See comment on similar Is_Sorted below
-     (for all I in First_Index (Container) .. Last_Index (Container) - 1 =>
-        (for all J in I + 1 .. Last_Index (Container) =>
-           Element_Compare (Element (Container, I), Element (Container, J)) in 
Less | Equal));
-
-   procedure Insert
-     (Container       : in out Vector;
-      New_Item        : in     Element_Type;
-      Ignore_If_Equal : in     Boolean := False) with
-     Pre  => Last_Index (Container) < Peek_Type (Capacity),
-     Post => Is_Sorted (Container) and
-             (if Ignore_If_Equal then
-                (Last_Index (Container) = Last_Index (Container'Old) or
-                 Last_Index (Container) = Last_Index (Container'Old) + 1)
-              else
-                Last_Index (Container) = Last_Index (Container'Old) + 1);
-   --  Insert New_Item in sorted position. Items are sorted in increasing
-   --  order according to Element_Compare. New_Item is inserted after
-   --  Equal items, unless Ignore_If_Equal is true, in which case
-   --  New_Item is not inserted.
-
-private
-
-   type Array_Type is array (Peek_Type range 1 .. Peek_Type (Capacity)) of 
aliased Element_Type;
-
-   function Is_Sorted (Container : in Array_Type; Last : in Base_Peek_Type) 
return Boolean
-     --  This is too hard for gnatprove (in 2019):
-     --  is (for all I in Container'First .. Last - 1 =>
-     --        Element_Compare (Container (I), Container (I + 1)) in Less | 
Equal)
-     --  This works:
-     is (for all I in Container'First .. Last - 1 =>
-           (for all J in I + 1 .. Last =>
-              Element_Compare (Container (I), Container (J)) in Less | Equal))
-     with Pre => Last <= Container'Last;
-
-   subtype Index_Type is Base_Peek_Type range No_Index .. Base_Peek_Type 
(Capacity);
-   --  Helps with proofs
-
-   type Vector is record
-      Elements : Array_Type;
-      Last     : Index_Type := No_Index;
-   end record with
-     Type_Invariant => Last <= Elements'Last and Is_Sorted (Vector.Elements, 
Vector.Last);
-   pragma Annotate (GNATprove, Intentional, "type ""Vector"" is not fully 
initialized",
-                    "Only items in Elements with index <= Last are accessed");
-
-end SAL.Gen_Bounded_Definite_Vectors_Sorted;
diff --git a/packages/wisi/sal-gen_definite_doubly_linked_lists.adb 
b/packages/wisi/sal-gen_definite_doubly_linked_lists.adb
deleted file mode 100644
index d86441a..0000000
--- a/packages/wisi/sal-gen_definite_doubly_linked_lists.adb
+++ /dev/null
@@ -1,317 +0,0 @@
---  Abstract :
---
---  see spec
---
---  Copyright (C) 2017 - 2020 Free Software Foundation, Inc.
---
---  This library is free software; you can redistribute it and/or
---  modify it under terms of the GNU General Public License as
---  published by the Free Software Foundation; either version 3, or (at
---  your option) any later version. This library 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
---  distributed with this program; see file COPYING. If not, write to
---  the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
---  MA 02111-1307, USA.
---
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-package body SAL.Gen_Definite_Doubly_Linked_Lists is
-
-   procedure Delete_Node (Container : in out List; Node : in out Node_Access)
-   is begin
-      if Node.Next = null then
-         Container.Tail := Node.Prev;
-      else
-         Node.Next.Prev := Node.Prev;
-      end if;
-      if Node.Prev = null then
-         Container.Head := Node.Next;
-      else
-         Node.Prev.Next := Node.Next;
-      end if;
-      Free (Node);
-   end Delete_Node;
-
-   ---------
-   --  Public operations, declaration order.
-
-   overriding
-   procedure Adjust (Container : in out List)
-   is
-      Next_Source : Node_Access := Container.Head;
-      New_Node    : Node_Access;
-   begin
-      if Next_Source = null then
-         return;
-      end if;
-
-      Container.Tail := null;
-
-      loop
-         New_Node := new Node_Type'
-           (Element => Next_Source.Element,
-            Next    => null,
-            Prev    => Container.Tail);
-         if Container.Tail = null then
-            Container.Head := New_Node;
-            Container.Tail := New_Node;
-         else
-            Container.Tail.Next := New_Node;
-            Container.Tail      := New_Node;
-         end if;
-         Next_Source := Next_Source.Next;
-         exit when Next_Source = null;
-      end loop;
-   end Adjust;
-
-   overriding
-   procedure Finalize (Container : in out List)
-   is
-      Next : Node_Access := Container.Head;
-   begin
-      loop
-         exit when Next = null;
-         Next := Container.Head.Next;
-         Free (Container.Head);
-         Container.Head := Next;
-      end loop;
-      Container.Tail := null;
-   end Finalize;
-
-   function Length (Container : in List) return Ada.Containers.Count_Type
-   is begin
-      return Container.Count;
-   end Length;
-
-   procedure Append (Container : in out List; Element : in Element_Type)
-   is
-      use all type Ada.Containers.Count_Type;
-      New_Node : constant Node_Access := new Node_Type'
-        (Element => Element,
-         Prev    => Container.Tail,
-         Next    => null);
-   begin
-      if Container.Tail = null then
-         Container.Head := New_Node;
-         Container.Tail := New_Node;
-      else
-         Container.Tail.Next := New_Node;
-         Container.Tail      := New_Node;
-      end if;
-      Container.Count := Container.Count + 1;
-   end Append;
-
-   procedure Prepend (Container : in out List; Element : in Element_Type)
-   is
-      use all type Ada.Containers.Count_Type;
-      New_Node : constant Node_Access := new Node_Type'
-        (Element => Element,
-         Prev    => null,
-         Next    => Container.Head);
-   begin
-      if Container.Tail = null then
-         Container.Head := New_Node;
-         Container.Tail := New_Node;
-      else
-         Container.Head.Prev := New_Node;
-         Container.Head      := New_Node;
-      end if;
-      Container.Count := Container.Count + 1;
-   end Prepend;
-
-   function To_List (Element : in Element_Type) return List
-   is begin
-      return Result : List do
-         Result.Append (Element);
-      end return;
-   end To_List;
-
-   function Has_Element (Position : in Cursor) return Boolean
-   is begin
-      return Position.Ptr /= null;
-   end Has_Element;
-
-   function First (Container : in List) return Cursor
-   is begin
-      if Container.Head = null then
-         return (Ptr => null);
-      else
-         return (Ptr => Container.Head);
-      end if;
-   end First;
-
-   function Last (Container : in List) return Cursor
-   is begin
-      if Container.Tail = null then
-         return (Ptr => null);
-      else
-         return (Ptr => Container.Tail);
-      end if;
-   end Last;
-
-   procedure Next (Position : in out Cursor)
-   is begin
-      if Position.Ptr /= null then
-         if Position.Ptr.Next = null then
-            Position.Ptr := null;
-         else
-            Position.Ptr := Position.Ptr.Next;
-         end if;
-      end if;
-   end Next;
-
-   function Next (Position : in Cursor) return Cursor
-   is begin
-      if Position.Ptr = null then
-         return Position;
-      else
-         if Position.Ptr.Next = null then
-            return (Ptr => null);
-         else
-            return (Ptr => Position.Ptr.Next);
-         end if;
-      end if;
-   end Next;
-
-   function Previous (Position : in Cursor) return Cursor
-   is begin
-      if Position.Ptr = null then
-         return Position;
-      else
-         if Position.Ptr.Prev = null then
-            return (Ptr => null);
-         else
-            return (Ptr => Position.Ptr.Prev);
-         end if;
-      end if;
-   end Previous;
-
-   function Element (Position : in Cursor) return Element_Type
-   is begin
-      return Position.Ptr.Element;
-   end Element;
-
-   procedure Delete (Container : in out List; Position : in out Cursor)
-   is
-      use all type Ada.Containers.Count_Type;
-   begin
-      Delete_Node (Container, Position.Ptr);
-      Position        := (Ptr => null);
-      Container.Count := Container.Count - 1;
-   end Delete;
-
-   procedure Delete_First (Container : in out List)
-   is
-      use all type Ada.Containers.Count_Type;
-      Node : Node_Access := Container.Head;
-   begin
-      Delete_Node (Container, Node);
-      Container.Count := Container.Count - 1;
-   end Delete_First;
-
-   procedure Insert
-     (Container : in out List;
-      Before    : in     Cursor;
-      Element   : in     Element_Type)
-   is
-      use all type Ada.Containers.Count_Type;
-   begin
-      if Before = (Ptr => null) then
-         Container.Append (Element);
-      else
-         if Before.Ptr = Container.Head then
-            declare
-               --  old list: before ...
-               --  newlist:  new  before ...
-               New_Node : constant Node_Access := new Node_Type'
-                 (Element => Element,
-                  Prev    => null,
-                  Next    => Before.Ptr);
-            begin
-               Before.Ptr.Prev := New_Node;
-               Container.Head  := New_Node;
-            end;
-         else
-            declare
-               --  old list: ... prev  before ...
-               --  newlist:  ... prev  new  before ...
-               New_Node : constant Node_Access := new Node_Type'
-                 (Element => Element,
-                  Prev    => Before.Ptr.Prev,
-                  Next    => Before.Ptr);
-            begin
-               Before.Ptr.Prev.Next := New_Node;
-               Before.Ptr.Prev      := New_Node;
-
-            end;
-         end if;
-         Container.Count := Container.Count + 1;
-      end if;
-   end Insert;
-
-   function Persistent_Ref (Position : in Cursor) return access Element_Type
-   is begin
-      return Position.Ptr.Element'Access;
-   end Persistent_Ref;
-
-   function Constant_Reference (Container : in List; Position : in Cursor) 
return Constant_Reference_Type
-   is
-      pragma Unreferenced (Container);
-   begin
-      return (Element => Position.Ptr.all.Element'Access, Dummy => 1);
-   end Constant_Reference;
-
-   function Constant_Ref (Position : in Cursor) return Constant_Reference_Type
-   is begin
-      return (Element => Position.Ptr.all.Element'Access, Dummy => 1);
-   end Constant_Ref;
-
-   function Variable_Reference (Container : in List; Position : in Cursor) 
return Variable_Reference_Type
-   is
-      pragma Unreferenced (Container);
-   begin
-      return (Element => Position.Ptr.all.Element'Access, Dummy => 1);
-   end Variable_Reference;
-
-   function Variable_Ref (Position : in Cursor) return Variable_Reference_Type
-   is begin
-      return (Element => Position.Ptr.all.Element'Access, Dummy => 1);
-   end Variable_Ref;
-
-   function Iterate (Container : aliased in List) return 
Iterator_Interfaces.Reversible_Iterator'Class
-   is begin
-      return Iterator'(Container => Container'Access);
-   end Iterate;
-
-   overriding function First (Object : Iterator) return Cursor
-   is begin
-      return First (Object.Container.all);
-   end First;
-
-   overriding function Last  (Object : Iterator) return Cursor
-   is begin
-      return Last (Object.Container.all);
-   end Last;
-
-   overriding function Next (Object : in Iterator; Position : in Cursor) 
return Cursor
-   is
-      pragma Unreferenced (Object);
-   begin
-      return Next (Position);
-   end Next;
-
-   overriding function Previous (Object : in Iterator; Position : in Cursor) 
return Cursor
-   is
-      pragma Unreferenced (Object);
-   begin
-      return Previous (Position);
-   end Previous;
-
-end SAL.Gen_Definite_Doubly_Linked_Lists;
diff --git a/packages/wisi/sal-gen_definite_doubly_linked_lists.ads 
b/packages/wisi/sal-gen_definite_doubly_linked_lists.ads
deleted file mode 100644
index 8470daf..0000000
--- a/packages/wisi/sal-gen_definite_doubly_linked_lists.ads
+++ /dev/null
@@ -1,172 +0,0 @@
---  Abstract :
---
---  A generic doubly linked list with definite elements, allowing
---  permanent references to elements.
---
---  Copyright (C) 2017 - 2020 Free Software Foundation, Inc.
---
---  This library is free software; you can redistribute it and/or
---  modify it under terms of the GNU General Public License as
---  published by the Free Software Foundation; either version 3, or (at
---  your option) any later version. This library 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
---  distributed with this program; see file COPYING. If not, write to
---  the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
---  MA 02111-1307, USA.
---
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-with Ada.Containers;
-with Ada.Finalization;
-with Ada.Iterator_Interfaces;
-with Ada.Unchecked_Deallocation;
-generic
-   type Element_Type is private;
-package SAL.Gen_Definite_Doubly_Linked_Lists is
-
-   type List is new Ada.Finalization.Controlled with private
-   with
-      Constant_Indexing => Constant_Reference,
-      Variable_Indexing => Variable_Reference,
-      Default_Iterator  => Iterate,
-      Iterator_Element  => Element_Type;
-
-   type List_Access_Constant is access constant List;
-   for List_Access_Constant'Storage_Size use 0;
-
-   type List_Access is access all List;
-   for List_Access'Storage_Size use 0;
-
-   Empty_List : constant List;
-
-   overriding procedure Adjust (Container : in out List);
-   --  Deep copy.
-
-   overriding procedure Finalize (Container : in out List);
-   --  Free all items in List.
-
-   procedure Clear (Container : in out List) renames Finalize;
-
-   function Length (Container : in List) return Ada.Containers.Count_Type;
-
-   procedure Append (Container : in out List; Element : in Element_Type);
-
-   procedure Prepend (Container : in out List; Element : in Element_Type);
-
-   function To_List (Element : in Element_Type) return List;
-
-   type Cursor is private;
-
-   function Has_Element (Position : in Cursor) return Boolean;
-
-   No_Element : constant Cursor;
-   function First (Container : in List) return Cursor;
-   function Last (Container : in List) return Cursor;
-
-   procedure Next (Position : in out Cursor)
-   with Pre => Has_Element (Position);
-
-   function Next (Position : in Cursor) return Cursor
-   with Pre => Has_Element (Position);
-   function Previous (Position : in Cursor) return Cursor
-   with Pre => Has_Element (Position);
-
-   function Element (Position : in Cursor) return Element_Type
-   with Pre => Has_Element (Position);
-
-   procedure Delete (Container : in out List; Position : in out Cursor)
-   with Pre => Has_Element (Position);
-
-   procedure Delete_First (Container : in out List);
-
-   procedure Insert
-     (Container : in out List;
-      Before    : in     Cursor;
-      Element   : in     Element_Type);
-   --  If Before is No_Element, insert after Last.
-
-   function Persistent_Ref (Position : in Cursor) return access Element_Type
-   with Pre => Has_Element (Position);
-
-   type Constant_Reference_Type (Element : not null access constant 
Element_Type) is private with
-     Implicit_Dereference => Element;
-
-   function Constant_Reference (Container : in List; Position : in Cursor) 
return Constant_Reference_Type
-   with Inline, Pre => Has_Element (Position);
-   --  Not 'Constant_Ref' because that is taken, and it is wrong for 
Constant_Indexing
-
-   function Constant_Ref (Position : in Cursor) return Constant_Reference_Type
-   with Inline, Pre => Has_Element (Position);
-
-   type Variable_Reference_Type (Element : not null access Element_Type) is 
private with
-     Implicit_Dereference => Element;
-
-   function Variable_Reference (Container : in List; Position : in Cursor) 
return Variable_Reference_Type
-   with Inline, Pre => Has_Element (Position);
-
-   function Variable_Ref (Position : in Cursor) return Variable_Reference_Type
-   with Inline, Pre => Has_Element (Position);
-
-   package Iterator_Interfaces is new Ada.Iterator_Interfaces (Cursor, 
Has_Element);
-
-   function Iterate (Container : aliased in List) return 
Iterator_Interfaces.Reversible_Iterator'Class;
-
-private
-   type Node_Type;
-
-   type Node_Access is access Node_Type;
-
-   type Node_Type is record
-      Element : aliased Element_Type;
-      Prev    : Node_Access;
-      Next    : Node_Access;
-   end record;
-
-   procedure Free is new Ada.Unchecked_Deallocation (Node_Type, Node_Access);
-
-   type List is new Ada.Finalization.Controlled with record
-      Head  : Node_Access               := null;
-      Tail  : Node_Access               := null;
-      Count : Ada.Containers.Count_Type := 0;
-   end record;
-
-   type Cursor is record
-      Ptr : Node_Access;
-   end record;
-
-   type Constant_Reference_Type (Element : not null access constant 
Element_Type) is
-   record
-      Dummy : Integer := raise Program_Error with "uninitialized reference";
-   end record;
-
-   type Variable_Reference_Type (Element : not null access Element_Type) is
-   record
-      Dummy : Integer := raise Program_Error with "uninitialized reference";
-   end record;
-
-   No_Element : constant Cursor := (Ptr => null);
-
-   Empty_List : constant List := (Ada.Finalization.Controlled with null, null, 
0);
-
-   type Iterator (Container : not null access constant List) is new 
Iterator_Interfaces.Reversible_Iterator with
-   null record;
-
-   overriding function First (Object : Iterator) return Cursor;
-   overriding function Last  (Object : Iterator) return Cursor;
-
-   overriding function Next
-     (Object   : Iterator;
-      Position : Cursor) return Cursor;
-
-   overriding function Previous
-     (Object   : Iterator;
-      Position : Cursor) return Cursor;
-
-end SAL.Gen_Definite_Doubly_Linked_Lists;
diff --git 
a/packages/wisi/sal-gen_definite_doubly_linked_lists_sorted-gen_image.adb 
b/packages/wisi/sal-gen_definite_doubly_linked_lists_sorted-gen_image.adb
deleted file mode 100644
index 6e6efb3..0000000
--- a/packages/wisi/sal-gen_definite_doubly_linked_lists_sorted-gen_image.adb
+++ /dev/null
@@ -1,47 +0,0 @@
---  Abstract :
---
---  See spec.
---
---  Copyright (C) 2018 Free Software Foundation, Inc.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-with Ada.Strings.Unbounded;
-function SAL.Gen_Definite_Doubly_Linked_Lists_Sorted.Gen_Image
-  (Item : in List; Strict : in Boolean := False) return String
-is
-   use Ada.Strings;
-   use Ada.Strings.Unbounded;
-   Result     : Unbounded_String := To_Unbounded_String ("(");
-   Need_Comma : Boolean          := False;
-begin
-   if Strict and Item.Length = 0 then
-      return "(1 .. 0 => <>)";
-
-   elsif Strict and Item.Length = 1 then
-      return "(1 => " & Element_Image (Element (Item.First)) & ")";
-
-   else
-      for El of Item loop
-         if Need_Comma then
-            Result := Result & ", ";
-         else
-            Need_Comma := True;
-         end if;
-         Result := Result & Element_Image (El);
-      end loop;
-      Result := Result & ")";
-      return To_String (Result);
-   end if;
-end SAL.Gen_Definite_Doubly_Linked_Lists_Sorted.Gen_Image;
diff --git 
a/packages/wisi/sal-gen_definite_doubly_linked_lists_sorted-gen_image.ads 
b/packages/wisi/sal-gen_definite_doubly_linked_lists_sorted-gen_image.ads
deleted file mode 100644
index 4080707..0000000
--- a/packages/wisi/sal-gen_definite_doubly_linked_lists_sorted-gen_image.ads
+++ /dev/null
@@ -1,25 +0,0 @@
---  Abstract :
---
---  Image of parent.
---
---  Copyright (C) 2018 Free Software Foundation, Inc.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-generic
-   with function Element_Image (Item : in Element_Type) return String;
-function SAL.Gen_Definite_Doubly_Linked_Lists_Sorted.Gen_Image
-  (Item : in List; Strict : in Boolean := False) return String;
---  Image of Item, in Ada aggregate syntax. If Strict, use correct
---  syntax for 0 and 1 item; otherwise, use () and (item).
diff --git a/packages/wisi/sal-gen_definite_doubly_linked_lists_sorted.adb 
b/packages/wisi/sal-gen_definite_doubly_linked_lists_sorted.adb
deleted file mode 100644
index 702914d..0000000
--- a/packages/wisi/sal-gen_definite_doubly_linked_lists_sorted.adb
+++ /dev/null
@@ -1,542 +0,0 @@
---  Abstract :
---
---  See spec.
---
---  Copyright (C) 2018 - 2020 Free Software Foundation, Inc.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-package body SAL.Gen_Definite_Doubly_Linked_Lists_Sorted is
-
-   ----------
-   --  Body subprograms, alphabetical
-
-   procedure Find
-     (Container     : in     List;
-      Element       : in     Element_Type;
-      Found         :    out Node_Access;
-      Found_Compare :    out Compare_Result)
-   is
-      --  Return pointer to first item in Container for which Compare (item,
-      --  element) returns True or Greater. If no such element exists, Found
-      --  is null, Found_Compare is Less.
-      use Ada.Containers;
-   begin
-      if Container.Head = null then
-         Found         := null;
-         Found_Compare := Less;
-         return;
-      end if;
-
-      declare
-         Low_Index  : Count_Type  := 1;
-         High_Index : Count_Type  := Container.Count;
-         Next_Node  : Node_Access := Container.Head;
-         Next_Index : Count_Type  := Low_Index;
-         Old_Index  : Count_Type;
-      begin
-         loop
-            Old_Index  := Next_Index;
-            Next_Index := (Low_Index + High_Index) / 2;
-
-            if Next_Index > Old_Index then
-               for I in Old_Index + 1 .. Next_Index loop
-                  Next_Node := Next_Node.Next;
-               end loop;
-            elsif Next_Index < Old_Index then
-               for I in Next_Index .. Old_Index - 1 loop
-                  Next_Node := Next_Node.Prev;
-               end loop;
-            end if;
-
-            case Element_Compare (Next_Node.Element, Element) is
-            when Less =>
-               if Next_Index = High_Index then
-                  --  no more nodes to check
-                  Found         := null;
-                  Found_Compare := Less;
-                  return;
-               elsif Next_Index = Low_Index then
-                  --  force check of high_index
-                  Low_Index := High_Index;
-               else
-                  Low_Index := Next_Index;
-               end if;
-
-            when Equal =>
-               Found         := Next_Node;
-               Found_Compare := Equal;
-               return;
-
-            when Greater =>
-               if Low_Index = Next_Index then
-                  --  no more nodes to check
-                  Found         := Next_Node;
-                  Found_Compare := Greater;
-                  return;
-               elsif High_Index = Next_Index then
-                  --  Desired result is either high_index or low_index
-                  pragma Assert (Low_Index + 1 = High_Index);
-                  case Element_Compare (Next_Node.Prev.Element, Element) is
-                  when Less =>
-                     Found         := Next_Node;
-                     Found_Compare := Greater;
-                     return;
-                  when Equal =>
-                     Found         := Next_Node.Prev;
-                     Found_Compare := Equal;
-                     return;
-                  when Greater =>
-                     Found         := Next_Node.Prev;
-                     Found_Compare := Greater;
-                     return;
-                  end case;
-               else
-                  High_Index := Next_Index;
-               end if;
-            end case;
-         end loop;
-      end;
-   end Find;
-
-   procedure Insert_Before
-     (Container : in out List;
-      Before    : in     Node_Access;
-      Element   : in     Element_Type)
-   is
-      New_Node : constant Node_Access := new Node_Type'
-        (Element => Element,
-         Prev    => Before.Prev,
-         Next    => Before);
-   begin
-      if Before = Container.Head then
-         Before.Prev    := New_Node;
-         Container.Head := New_Node;
-      else
-         Before.Prev.Next := New_Node;
-         Before.Prev      := New_Node;
-      end if;
-   end Insert_Before;
-
-   procedure Insert_After_Tail
-     (Container : in out List;
-      Element   : in     Element_Type)
-   is
-      New_Node : constant Node_Access := new Node_Type'
-        (Element => Element,
-         Prev    => Container.Tail,
-         Next    => null);
-   begin
-      Container.Tail.Next := New_Node;
-      Container.Tail      := New_Node;
-   end Insert_After_Tail;
-
-   ---------
-   --  Public operations, declaration order.
-
-   overriding
-   procedure Adjust (Container : in out List)
-   is
-      Next_Source : Node_Access := Container.Head;
-      New_Node    : Node_Access;
-   begin
-      if Next_Source = null then
-         return;
-      end if;
-
-      Container.Tail := null;
-
-      loop
-         New_Node := new Node_Type'
-           (Element => Next_Source.Element,
-            Next    => null,
-            Prev    => Container.Tail);
-         if Container.Tail = null then
-            Container.Head := New_Node;
-            Container.Tail := New_Node;
-         else
-            Container.Tail.Next := New_Node;
-            Container.Tail      := New_Node;
-         end if;
-         Next_Source := Next_Source.Next;
-         exit when Next_Source = null;
-      end loop;
-   end Adjust;
-
-   overriding
-   procedure Finalize (Container : in out List)
-   is
-      Next : Node_Access := Container.Head;
-   begin
-      loop
-         exit when Next = null;
-         Next := Container.Head.Next;
-         Free (Container.Head);
-         Container.Head := Next;
-      end loop;
-      Container.Tail := null;
-   end Finalize;
-
-   overriding function "=" (Left, Right : in List) return Boolean
-   is
-      Left_I  : Node_Access := Left.Head;
-      Right_I : Node_Access := Right.Head;
-   begin
-      loop
-         exit when Left_I = null;
-
-         if Right_I = null then
-            return False;
-         elsif Left_I.Element /= Right_I.Element then
-            return False;
-         end if;
-
-         Left_I  := Left_I.Next;
-         Right_I := Right_I.Next;
-      end loop;
-      return Right_I = null;
-   end "=";
-
-   function Length (Container : in List) return Ada.Containers.Count_Type
-   is begin
-      return Container.Count;
-   end Length;
-
-   function To_List (Element : in Element_Type) return List
-   is
-      New_Node : constant Node_Access := new Node_Type'
-        (Element => Element,
-         Prev    => null,
-         Next    => null);
-   begin
-      return Result : constant List :=
-        (Ada.Finalization.Controlled with
-         Head  => New_Node,
-         Tail  => New_Node,
-         Count => 1);
-   end To_List;
-
-   procedure Insert (Container : in out List; Element : in Element_Type)
-   is
-      Node    : Node_Access := Container.Head;
-      Compare : Compare_Result;
-   begin
-      if Node = null then
-         Container := To_List (Element);
-      else
-         Find (Container, Element, Node, Compare);
-
-         Container.Count := Container.Count + 1;
-
-         if Node = null then
-            Insert_After_Tail (Container, Element);
-         else
-            Insert_Before (Container, Node, Element);
-         end if;
-      end if;
-   end Insert;
-
-   function Contains (Container : in List; Element : in Element_Type) return 
Boolean
-   is
-      Node    : Node_Access := Container.Head;
-      Compare : Compare_Result;
-   begin
-      Find (Container, Element, Node, Compare);
-      return Compare = Equal;
-   end Contains;
-
-   procedure Merge
-     (Target : in out List;
-      Source : in     List;
-      Added  :    out Boolean)
-   is
-      Target_I : Node_Access := Target.Head;
-      Source_I : Node_Access := Source.Head;
-   begin
-      if Target_I = null then
-         if Source_I = null then
-            Added := False;
-         else
-            Target.Head  := Source.Head;
-            Target.Tail  := Source.Tail;
-            Target.Count := Source.Count;
-            Adjust (Target);
-
-            Added := True;
-         end if;
-
-      elsif Source_I = null then
-         Added := False;
-
-      else
-         Added := False;
-         loop
-            exit when Source_I = null;
-
-            if Target_I = null then
-               Added := True;
-               Target.Count := Target.Count + 1;
-               Insert_After_Tail (Target, Source_I.Element);
-               Source_I := Source_I.Next;
-
-            else
-               case Element_Compare (Target_I.Element, Source_I.Element) is
-               when Greater =>
-                  Added := True;
-                  Target.Count := Target.Count + 1;
-                  Insert_Before (Target, Target_I, Source_I.Element);
-                  Source_I := Source_I.Next;
-
-               when Equal =>
-                  Target_I := Target_I.Next;
-                  Source_I := Source_I.Next;
-
-               when Less =>
-                  Target_I := Target_I.Next;
-               end case;
-            end if;
-         end loop;
-      end if;
-   end Merge;
-
-   procedure Merge
-     (Target  : in out List;
-      Source  : in     List;
-      Added   :    out Boolean;
-      Exclude : in     Element_Type)
-   is
-      Target_I : Node_Access := Target.Head;
-      Source_I : Node_Access := Source.Head;
-   begin
-      Added := False;
-
-      if Target_I = null then
-         if Source_I = null then
-            return;
-         else
-            loop
-               if Source_I = null then
-                  return;
-               end if;
-               exit when Source_I.Element /= Exclude;
-               Source_I := Source_I.Next;
-            end loop;
-
-            Added    := True;
-            Target   := To_List (Source_I.Element);
-            Source_I := Source_I.Next;
-         end if;
-      end if;
-
-      loop
-         exit when Source_I = null;
-
-         if Source_I.Element = Exclude then
-            Source_I := Source_I.Next;
-
-         elsif Target_I = null then
-            Added := True;
-            Target.Count := Target.Count + 1;
-            Insert_After_Tail (Target, Source_I.Element);
-            Source_I := Source_I.Next;
-
-         else
-            case Element_Compare (Target_I.Element, Source_I.Element) is
-            when Greater =>
-               Added := True;
-               Target.Count := Target.Count + 1;
-               Insert_Before (Target, Target_I, Source_I.Element);
-               Source_I := Source_I.Next;
-
-            when Equal =>
-               Target_I := Target_I.Next;
-               Source_I := Source_I.Next;
-
-            when Less =>
-               Target_I := Target_I.Next;
-            end case;
-         end if;
-      end loop;
-   end Merge;
-
-   function Has_Element (Position : in Cursor) return Boolean
-   is begin
-      return Position.Ptr /= null;
-   end Has_Element;
-
-   function First (Container : aliased in List) return Cursor
-   is begin
-      if Container.Head = null then
-         return (Container'Access, null);
-      else
-         return (Container'Access, Container.Head);
-      end if;
-   end First;
-
-   function Last (Container : aliased in List) return Cursor
-   is begin
-      if Container.Tail = null then
-         return (Container'Access, null);
-      else
-         return (Container'Access, Container.Tail);
-      end if;
-   end Last;
-
-   function Find (Container : aliased in List; Element : in Element_Type) 
return Cursor
-   is
-      Node    : Node_Access;
-      Compare : Compare_Result;
-   begin
-      Find (Container, Element, Node, Compare);
-
-      if Node = null then
-         return (Container'Access, null);
-      elsif Compare = Equal then
-         return (Container'Access, Node);
-      else
-         return (Container'Access, null);
-      end if;
-   end Find;
-
-   procedure Next (Position : in out Cursor)
-   is begin
-      if Position.Ptr /= null then
-         if Position.Ptr.Next = null then
-            Position.Ptr := null;
-         else
-            Position.Ptr := Position.Ptr.Next;
-         end if;
-      end if;
-   end Next;
-
-   function Next (Position : in Cursor) return Cursor
-   is begin
-      if Position.Ptr = null then
-         return Position;
-      else
-         if Position.Ptr.Next = null then
-            return (Position.Container, null);
-         else
-            return (Position.Container, Position.Ptr.Next);
-         end if;
-      end if;
-   end Next;
-
-   function Previous (Position : in Cursor) return Cursor
-   is begin
-      if Position.Ptr = null then
-         return Position;
-      else
-         if Position.Ptr.Prev = null then
-            return (Position.Container, null);
-         else
-            return (Position.Container, Position.Ptr.Prev);
-         end if;
-      end if;
-   end Previous;
-
-   function Element (Position : in Cursor) return Element_Type
-   is begin
-      return Position.Ptr.Element;
-   end Element;
-
-   procedure Delete (Container : in out List; Position : in out Cursor)
-   is
-      Node : Node_Access renames Position.Ptr;
-   begin
-      if Node.Next = null then
-         Container.Tail := Node.Prev;
-      else
-         Node.Next.Prev := Node.Prev;
-      end if;
-      if Node.Prev = null then
-         Container.Head := Node.Next;
-      else
-         Node.Prev.Next := Node.Next;
-      end if;
-      Free (Node);
-      Position        := (Container'Access, null);
-      Container.Count := Container.Count - 1;
-   end Delete;
-
-   function Pop (Container : in out List) return Element_Type
-   is
-      Node : Node_Access := Container.Head;
-   begin
-      return Result : constant Element_Type := Container.Head.Element do
-         Container.Head := Node.Next;
-         if Node.Next = null then
-            Container.Tail := null;
-         else
-            Node.Next.Prev := null;
-         end if;
-         Free (Node);
-         Container.Count := Container.Count - 1;
-      end return;
-   end Pop;
-
-   function Constant_Reference (Container : in List; Position : in Cursor) 
return Constant_Reference_Type
-   is
-      pragma Unreferenced (Container);
-   begin
-      return (Element => Position.Ptr.all.Element'Access, Dummy => 1);
-   end Constant_Reference;
-
-   function Constant_Ref (Position : in Cursor) return Constant_Reference_Type
-   is begin
-      return (Element => Position.Ptr.all.Element'Access, Dummy => 1);
-   end Constant_Ref;
-
-   function Variable_Reference (Container : in List; Position : in Cursor) 
return Variable_Reference_Type
-   is
-      pragma Unreferenced (Container);
-   begin
-      return (Element => Position.Ptr.all.Element'Access, Dummy => 1);
-   end Variable_Reference;
-
-   function Variable_Ref (Position : in Cursor) return Variable_Reference_Type
-   is begin
-      return (Element => Position.Ptr.all.Element'Access, Dummy => 1);
-   end Variable_Ref;
-
-   function Iterate (Container : aliased in List) return 
Iterator_Interfaces.Reversible_Iterator'Class
-   is begin
-      return Iterator'(Container => Container'Access);
-   end Iterate;
-
-   overriding function First (Object : Iterator) return Cursor
-   is begin
-      return First (Object.Container.all);
-   end First;
-
-   overriding function Last  (Object : Iterator) return Cursor
-   is begin
-      return Last (Object.Container.all);
-   end Last;
-
-   overriding function Next (Object : in Iterator; Position : in Cursor) 
return Cursor
-   is
-      pragma Unreferenced (Object);
-   begin
-      return Next (Position);
-   end Next;
-
-   overriding function Previous (Object : in Iterator; Position : in Cursor) 
return Cursor
-   is
-      pragma Unreferenced (Object);
-   begin
-      return Previous (Position);
-   end Previous;
-
-end SAL.Gen_Definite_Doubly_Linked_Lists_Sorted;
diff --git a/packages/wisi/sal-gen_definite_doubly_linked_lists_sorted.ads 
b/packages/wisi/sal-gen_definite_doubly_linked_lists_sorted.ads
deleted file mode 100644
index 91ffeda..0000000
--- a/packages/wisi/sal-gen_definite_doubly_linked_lists_sorted.ads
+++ /dev/null
@@ -1,190 +0,0 @@
---  Abstract :
---
---  A generic sorted doubly linked list with definite elements.
---
---  Copyright (C) 2018 - 2020 Free Software Foundation, Inc.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-with Ada.Finalization;
-with Ada.Iterator_Interfaces;
-with Ada.Unchecked_Deallocation;
-generic
-   type Element_Type is private;
-   with function Element_Compare (Left, Right : in Element_Type) return 
Compare_Result;
-package SAL.Gen_Definite_Doubly_Linked_Lists_Sorted is
-   use all type Ada.Containers.Count_Type;
-
-   type List is new Ada.Finalization.Controlled with private
-   with
-      Constant_Indexing => Constant_Reference,
-      Variable_Indexing => Variable_Reference,
-      Default_Iterator  => Iterate,
-      Iterator_Element  => Element_Type;
-
-   --  If user uses Variable_Indexing, they must not change the sort
-   --  order of the elements.
-
-   type List_Access is access all List;
-   for List_Access'Storage_Size use 0;
-
-   Empty_List : constant List;
-
-   overriding procedure Adjust (Container : in out List);
-   --  Deep copy.
-
-   overriding procedure Finalize (Container : in out List);
-   --  Free all items in List.
-
-   procedure Clear (Container : in out List) renames Finalize;
-
-   overriding function "=" (Left, Right : in List) return Boolean;
-   --  True if contents are the same.
-
-   function Length (Container : in List) return Ada.Containers.Count_Type;
-
-   function To_List (Element : in Element_Type) return List;
-
-   procedure Insert (Container : in out List; Element : in Element_Type);
-   --  Insert Element before first item for which Element_Order (item,
-   --  element) returns True.
-
-   function Contains (Container : in List; Element : in Element_Type) return 
Boolean;
-
-   procedure Merge
-     (Target : in out List;
-      Source : in     List;
-      Added  :    out Boolean);
-   --  Add all elements of Source to Target, if they are not already
-   --  present.
-   --
-   --  Added is True if any element was not already present.
-
-   procedure Merge
-     (Target  : in out List;
-      Source  : in     List;
-      Added   :    out Boolean;
-      Exclude : in     Element_Type);
-   --  Add all elements of Source to Target, if they are not already
-   --  present, and are not equal to Exclude.
-   --
-   --  Added is True if any element was not already present.
-
-   type Cursor (<>) is private;
-
-   function No_Element (Container : aliased in List) return Cursor;
-
-   function Has_Element (Position : in Cursor) return Boolean;
-
-   function First (Container : aliased in List) return Cursor;
-   function Last (Container : aliased in List) return Cursor;
-
-   function Find (Container : aliased in List; Element : in Element_Type) 
return Cursor;
-   --  No_Element if Element not found.
-
-   procedure Next (Position : in out Cursor)
-   with Pre => Has_Element (Position);
-
-   function Next (Position : in Cursor) return Cursor
-   with Pre => Has_Element (Position);
-   function Previous (Position : in Cursor) return Cursor
-   with Pre => Has_Element (Position);
-
-   function Element (Position : in Cursor) return Element_Type
-   with Pre => Has_Element (Position);
-
-   procedure Delete (Container : in out List; Position : in out Cursor)
-   with Pre => Has_Element (Position);
-
-   function Pop (Container : in out List) return Element_Type
-   with Pre => Container.Length > 0;
-   --  Return Container.First, delete it from Container.
-
-   type Constant_Reference_Type (Element : not null access constant 
Element_Type) is private with
-     Implicit_Dereference => Element;
-
-   function Constant_Reference (Container : in List; Position : in Cursor) 
return Constant_Reference_Type with
-     Inline, Pre => Has_Element (Position);
-
-   function Constant_Ref (Position : in Cursor) return Constant_Reference_Type 
with
-     Inline, Pre => Has_Element (Position);
-
-   type Variable_Reference_Type (Element : not null access Element_Type) is 
private with
-     Implicit_Dereference => Element;
-
-   function Variable_Reference (Container : in List; Position : in Cursor) 
return Variable_Reference_Type
-   with Inline, Pre => Has_Element (Position);
-
-   function Variable_Ref (Position : in Cursor) return Variable_Reference_Type
-   with Inline, Pre => Has_Element (Position);
-   --  User must not change the element in a way that affects the sort order.
-
-   package Iterator_Interfaces is new Ada.Iterator_Interfaces (Cursor, 
Has_Element);
-
-   function Iterate (Container : aliased in List) return 
Iterator_Interfaces.Reversible_Iterator'Class;
-
-private
-   type Node_Type;
-
-   type Node_Access is access Node_Type;
-
-   type Node_Type is record
-      Element : aliased Element_Type;
-      Prev    : Node_Access;
-      Next    : Node_Access;
-   end record;
-
-   procedure Free is new Ada.Unchecked_Deallocation (Node_Type, Node_Access);
-
-   type List is new Ada.Finalization.Controlled with record
-      Head  : Node_Access               := null;
-      Tail  : Node_Access               := null;
-      Count : Ada.Containers.Count_Type := 0;
-   end record;
-
-   type Cursor (Container : not null access constant List) is
-   record
-      Ptr : Node_Access;
-   end record;
-
-   type Constant_Reference_Type (Element : not null access constant 
Element_Type) is
-   record
-      Dummy : Integer := raise Program_Error with "uninitialized reference";
-   end record;
-
-   type Variable_Reference_Type (Element : not null access Element_Type) is
-   record
-      Dummy : Integer := raise Program_Error with "uninitialized reference";
-   end record;
-
-   Empty_List : constant List := (Ada.Finalization.Controlled with null, null, 
0);
-
-   function No_Element (Container : aliased in List) return Cursor
-     is (Container'Access, null);
-
-   type Iterator (Container : not null access constant List) is new 
Iterator_Interfaces.Reversible_Iterator with
-   null record;
-
-   overriding function First (Object : Iterator) return Cursor;
-   overriding function Last  (Object : Iterator) return Cursor;
-
-   overriding function Next
-     (Object   : Iterator;
-      Position : Cursor) return Cursor;
-
-   overriding function Previous
-     (Object   : Iterator;
-      Position : Cursor) return Cursor;
-
-end SAL.Gen_Definite_Doubly_Linked_Lists_Sorted;
diff --git a/packages/wisi/sal-gen_graphs.adb b/packages/wisi/sal-gen_graphs.adb
deleted file mode 100644
index ef0fcc3..0000000
--- a/packages/wisi/sal-gen_graphs.adb
+++ /dev/null
@@ -1,719 +0,0 @@
---  Abstract :
---
---  See spec.
---
---  Copyright (C) 2017, 2019 Free Software Foundation All Rights Reserved.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-with Ada.Strings.Unbounded;
-with Ada.Text_IO;
-with SAL.Gen_Bounded_Definite_Queues;
-with SAL.Gen_Unbounded_Definite_Stacks;
-package body SAL.Gen_Graphs is
-
-   package Vertex_Queues is new SAL.Gen_Bounded_Definite_Queues (Vertex_Index);
-   package Vertex_Stacks is new SAL.Gen_Unbounded_Definite_Stacks 
(Vertex_Index);
-
-   function Find (Data : in Edge_Data; List : in Edge_Node_Lists.List) return 
Edge_Node_Lists.Cursor
-   is begin
-      for I in List.Iterate loop
-         if Edge_Node_Lists.Element (I).Data = Data then
-            return I;
-         end if;
-      end loop;
-      return Edge_Node_Lists.No_Element;
-   end Find;
-
-   ----------
-   --  Visible subprograms
-
-   procedure Add_Edge
-     (Graph    : in out Gen_Graphs.Graph;
-      Vertex_A : in     Vertex_Index;
-      Vertex_B : in     Vertex_Index;
-      Data     : in     Edge_Data)
-   is
-      Multigraph : Boolean := False;
-
-      procedure Update_First_Last (Vertex : in Vertex_Index)
-      is
-         use all type Ada.Containers.Count_Type;
-      begin
-         if Graph.Vertices.Length = 0 then
-            Graph.Vertices.Set_First_Last (Vertex, Vertex);
-         else
-            if Vertex < Graph.Vertices.First_Index then
-               Graph.Vertices.Set_First_Last (Vertex, 
Graph.Vertices.Last_Index);
-            elsif Vertex > Graph.Vertices.Last_Index then
-               Graph.Vertices.Set_First_Last (Graph.Vertices.First_Index, 
Vertex);
-            end if;
-         end if;
-      end Update_First_Last;
-
-   begin
-      Update_First_Last (Vertex_A);
-      Update_First_Last (Vertex_B);
-
-      Graph.Last_Edge_ID := Graph.Last_Edge_ID + 1;
-      if (for some E of Graph.Vertices (Vertex_A) => E.Vertex_B = Vertex_B) 
then
-         Multigraph       := True;
-         Graph.Multigraph := True;
-      end if;
-
-      Graph.Vertices (Vertex_A).Append ((Graph.Last_Edge_ID, Vertex_B, 
Multigraph, Data));
-   end Add_Edge;
-
-   function Count_Nodes (Graph : in Gen_Graphs.Graph) return 
Ada.Containers.Count_Type
-   is begin
-      return Graph.Vertices.Length;
-   end Count_Nodes;
-
-   function Count_Edges (Graph : in Gen_Graphs.Graph) return 
Ada.Containers.Count_Type
-   is
-      use Ada.Containers;
-      Result : Count_Type := 0;
-   begin
-      for Edges of Graph.Vertices loop
-         Result := Result + Edges.Length;
-      end loop;
-      return Result;
-   end Count_Edges;
-
-   function Multigraph (Graph : in Gen_Graphs.Graph) return Boolean
-   is begin
-      return Graph.Multigraph;
-   end Multigraph;
-
-   function "+" (Right : in Edge_Item) return Edge_Lists.List
-   is
-      use Edge_Lists;
-   begin
-      return Result : List do
-         Append (Result, Right);
-      end return;
-   end "+";
-
-   function Edges (Graph : in Gen_Graphs.Graph; Vertex : in Vertex_Index) 
return Edge_Lists.List
-   is begin
-      return Result : Edge_Lists.List do
-         for E of Graph.Vertices (Vertex) loop
-            Result.Append ((E.ID, E.Data));
-         end loop;
-      end return;
-   end Edges;
-
-   function Image (Item : in Path) return String
-   is
-      use Ada.Strings.Unbounded;
-
-      Result : Unbounded_String := To_Unbounded_String ("(");
-   begin
-      for I in Item'Range loop
-         Result := Result & Trimmed_Image (Item (I).Vertex) & " " &
-           Image ((if I = Item'Last then Item (Item'First).Edges else Item (I 
+ 1).Edges)) & " -> ";
-      end loop;
-      Result := Result & ")";
-      return To_String (Result);
-   end Image;
-
-   function "<" (Left, Right : in Path) return Boolean
-   is begin
-      for I in Left'Range loop
-         if I > Right'Last then
-            return False;
-         elsif Left (I).Vertex < Right (I).Vertex then
-            return True;
-         elsif Left (I).Vertex > Right (I).Vertex then
-            return False;
-         else
-            --  =; check remaining elements
-            null;
-         end if;
-      end loop;
-
-      if Left'Last < Right'Last then
-         return True;
-      else
-         --  All =
-         return False;
-      end if;
-   end "<";
-
-   function Find_Paths
-     (Graph : in out Gen_Graphs.Graph;
-      From  : in     Vertex_Index;
-      To    : in     Edge_Data)
-     return Path_Arrays.Vector
-   is
-      use Vertex_Queues;
-
-      Vertex_Queue  : Queue_Type
-        (Size => Peek_Type (Graph.Vertices.Last_Index - 
Graph.Vertices.First_Index + 1));
-
-      type Colors is (White, Gray, Black);
-
-      type Aux_Node is record
-         Color       : Colors            := Colors'First;
-         D           : Natural           := Natural'Last;
-         Parent      : Vertex_Index'Base := Invalid_Vertex;
-         Parent_Set  : Boolean           := False;
-         Parent_Edge : Edge_Node_Lists.Cursor := Edge_Node_Lists.No_Element;
-      end record;
-
-      package Aux_Arrays is new SAL.Gen_Unbounded_Definite_Vectors 
(Vertex_Index, Aux_Node, (others => <>));
-      Aux : Aux_Arrays.Vector;
-
-      function Build_Path
-        (Tail_Vertex : in Vertex_Index;
-         Tail_Edge   : in Edge_Node_Lists.Cursor)
-        return Path
-      is
-      begin
-         return Result : Path (1 .. Aux (Tail_Vertex).D + 1)
-         do
-            declare
-               use Edge_Node_Lists;
-               V_Index   : Vertex_Index := Tail_Vertex;
-               Last_Edge : Cursor       := Tail_Edge;
-            begin
-               for I in reverse 1 .. Result'Length loop
-                  declare
-                     V : Aux_Node renames Aux (V_Index);
-                  begin
-                     if Last_Edge = No_Element then
-                        Result (I) := (V_Index, Edge_Lists.Empty_List);
-                     else
-                        Result (I) := (V_Index, +(Element (Last_Edge).ID, 
Element (Last_Edge).Data));
-                     end if;
-
-                     if V.Parent_Set then
-                        Last_Edge := V.Parent_Edge;
-                        V_Index   := V.Parent;
-                     end if;
-                  end;
-               end loop;
-            end;
-         end return;
-      end Build_Path;
-
-      Result_List : Path_Arrays.Vector;
-      Result_Edge : Edge_Node_Lists.Cursor;
-   begin
-      --  [1] figure 22.3 breadth-first search; 'From' = s.
-
-      Aux.Set_First_Last (Graph.Vertices.First_Index, 
Graph.Vertices.Last_Index);
-
-      for I in Aux.First_Index .. Aux.Last_Index loop
-         if I = From then
-            Aux (I).Color      := Gray;
-            Aux (I).D          := 0;
-            Aux (I).Parent_Set := False;
-
-         else
-            Aux (I).Color      := White;
-            Aux (I).D          := Natural'Last;
-            Aux (I).Parent_Set := False;
-         end if;
-      end loop;
-
-      Put (Vertex_Queue, From);
-
-      while not Is_Empty (Vertex_Queue) loop
-         declare
-            U_Index : constant Vertex_Index := Get (Vertex_Queue);
-            U       : Aux_Node renames Aux (U_Index);
-         begin
-            Edges :
-            for C in Graph.Vertices (U_Index).Iterate loop
-               declare
-                  use all type Edge_Node_Lists.Cursor;
-                  V_Index : constant Vertex_Index := Edge_Node_Lists.Element 
(C).Vertex_B;
-                  V       : Aux_Node renames Aux (V_Index);
-               begin
-                  if V.Color = White then
-                     V.Color       := Gray;
-                     V.D           := U.D + 1;
-                     V.Parent      := U_Index;
-                     V.Parent_Edge := C;
-                     V.Parent_Set  := True;
-
-                     Result_Edge := Find (To, Graph.Vertices (V_Index));
-                     if Result_Edge /= Edge_Node_Lists.No_Element then
-                        Result_List.Append (Build_Path (V_Index, Result_Edge));
-                     end if;
-
-                     Put (Vertex_Queue, V_Index);
-                  end if;
-               end;
-            end loop Edges;
-            U.Color := Black;
-         end;
-      end loop;
-      return Result_List;
-   end Find_Paths;
-
-   function Find_Cycles_Tiernan (Graph : in Gen_Graphs.Graph)
-     return Path_Arrays.Vector
-   is
-      --  Implements [2] "Algorithm EC"
-      --
-      --  vertex 0 = Invalid_Vertex
-      --  vertex 1 = Graph.Vertices.First_Index
-      --  vertex N = Graph.Vertices.Last_Index
-
-      First : Vertex_Index renames Graph.Vertices.First_Index;
-      Last  : Vertex_Index renames Graph.Vertices.Last_Index;
-
-      G : Vertex_Arrays.Vector renames Graph.Vertices;
-      P : Path (1 .. Integer (Last - First + 1));
-      K : Positive := 1; -- ie P_Last
-
-      type H_Row is array (G.First_Index .. G.Last_Index) of Vertex_Index'Base;
-      H : array (G.First_Index .. G.Last_Index) of H_Row := (others => (others 
=> Invalid_Vertex));
-
-      Next_Vertex_Found : Boolean;
-
-      Result : Path_Arrays.Vector;
-
-      function Contains (P : in Path; V : in Vertex_Index) return Boolean
-      is (for some N of P => N.Vertex = V);
-
-      function Contains (Row : in H_Row; V : in Vertex_Index) return Boolean
-      is (for some N of Row => N = V);
-
-      function Contains (Edges : in Edge_Lists.List; ID : in Edge_ID) return 
Boolean
-        is (for some E of Edges => E.ID = ID);
-
-      procedure Add_Alternate_Edges (P : in out Path)
-      is
-         function Dec (I : in Positive) return Positive
-           is (if I = P'First then P'Last else I - 1);
-      begin
-         for I in P'Range loop
-            for New_Edge of G (P (Dec (I)).Vertex) loop
-               if New_Edge.Vertex_B = P (I).Vertex and (not Contains (P 
(I).Edges, New_Edge.ID)) then
-                  P (I).Edges.Append ((New_Edge.ID, New_Edge.Data));
-               end if;
-            end loop;
-         end loop;
-      end Add_Alternate_Edges;
-
-   begin
-      P (1) := (First, Edge_Lists.Empty_List);
-
-      All_Initial_Vertices :
-      loop
-         Explore_Vertex :
-         loop
-            Path_Extension :
-            loop  -- EC2 Path Extension
-               Next_Vertex_Found := False;
-
-               Find_Next_Vertex :
-               for Edge of G (P (K).Vertex) loop
-                  declare
-                     Next_Vertex : constant Vertex_Index := Edge.Vertex_B; -- 
ie G[P[k],j]
-                  begin
-                     if Next_Vertex > P (1).Vertex and -- (1)
-                       (not Contains (P, Next_Vertex)) and -- (2)
-                       (not Contains (H (P (K).Vertex), Next_Vertex))
-                     then
-                        K     := K + 1;
-                        P (K) := (Next_Vertex, +(Edge.ID, Edge.Data));
-
-                        Next_Vertex_Found := True;
-                        exit Find_Next_Vertex;
-                     end if;
-                  end;
-               end loop Find_Next_Vertex;
-
-               exit Path_Extension when not Next_Vertex_Found;
-            end loop Path_Extension;
-
-            --  EC3 Circuit Confirmation
-            for Edge of G (P (K).Vertex) loop
-               if Edge.Vertex_B = P (1).Vertex then
-                  P (1).Edges := +(Edge.ID, Edge.Data);
-                  if Graph.Multigraph then
-                     Add_Alternate_Edges (P (1 .. K));
-                  end if;
-                  Result.Append (P (1 .. K));
-                  exit;
-               end if;
-            end loop;
-
-            --  EC4 Vertex Closure
-            exit Explore_Vertex when K = 1;
-
-            H (P (K).Vertex) := (others => Invalid_Vertex);
-            for M in H (P (K - 1).Vertex)'Range loop
-               if H (P (K - 1).Vertex)(M) = Invalid_Vertex then
-                  H (P (K - 1).Vertex)(M) := P (K).Vertex;
-                  P (K) := (Invalid_Vertex, Edge_Lists.Empty_List);
-                  exit;
-               end if;
-            end loop;
-            K := K - 1;
-         end loop Explore_Vertex;
-
-         --  EC5 Advance Initial Index
-         exit All_Initial_Vertices when P (1).Vertex = 
Graph.Vertices.Last_Index;
-
-         P (1) := (P (1).Vertex + 1, Edge_Lists.Empty_List);
-         pragma Assert (K = 1);
-         H := (others => (others => Invalid_Vertex));
-      end loop All_Initial_Vertices;
-
-      --  EC6 Terminate
-      return Result;
-   end Find_Cycles_Tiernan;
-
-   function Find_Cycles (Graph : in Gen_Graphs.Graph) return Path_Arrays.Vector
-   is
-      --  Implements Circuit-Finding Algorithm from [3]
-
-      use all type Ada.Containers.Count_Type;
-
-      pragma Warnings (Off, """Edited_Graph"" is not modified, could be 
declared constant");
-      Edited_Graph : Gen_Graphs.Graph := Graph;
-
-      Result : Path_Arrays.Vector;
-
-      A_K     : Adjacency_Structures.Vector;
-      B       : Adjacency_Structures.Vector;
-      Blocked : array (Graph.Vertices.First_Index .. 
Graph.Vertices.Last_Index) of Boolean := (others => False);
-
-      Stack : Vertex_Stacks.Stack;
-      S     : Vertex_Index := Graph.Vertices.First_Index;
-
-      Dummy : Boolean;
-      pragma Unreferenced (Dummy);
-
-      function Circuit (V : in Vertex_Index) return Boolean
-      is
-         F : Boolean := False;
-
-         procedure Unblock (U : in Vertex_Index)
-         is begin
-            Blocked (U) := False;
-            declare
-               use Vertex_Lists;
-               Cur  : Cursor := B (U).First;
-               Temp : Cursor;
-               W    : Vertex_Index;
-            begin
-               loop
-                  exit when not Has_Element (Cur);
-                  W := Element (Cur);
-                  Temp := Cur;
-                  Next (Cur);
-                  B (U).Delete (Temp);
-                  if Blocked (W) then
-                     Unblock (W);
-                  end if;
-               end loop;
-            end;
-         end Unblock;
-
-         procedure Add_Result
-         is
-            Cycle : Path (1 .. Integer (Stack.Depth));
-         begin
-            for I in 1 .. Stack.Depth loop
-               Cycle (Integer (Stack.Depth - I + 1)) := (Stack.Peek (I), 
Edge_Lists.Empty_List);
-               --  We add the edge info later, after finding all the cycles.
-            end loop;
-            Result.Append (Cycle);
-            if Trace > 0 then
-               Ada.Text_IO.Put_Line ("cycle " & Image (Cycle));
-            end if;
-         end Add_Result;
-
-      begin
-         if Trace > 0 then
-            Ada.Text_IO.Put_Line ("circuit start" & V'Image);
-         end if;
-
-         Stack.Push (V);
-         Blocked (V) := True;
-         if V in A_K.First_Index .. A_K.Last_Index then
-            for W of A_K (V) loop
-               if W = S then
-                  Add_Result;
-                  F := True;
-               elsif not Blocked (W) then
-                  if Circuit (W) then
-                     F := True;
-                  end if;
-               end if;
-            end loop;
-         end if;
-         if F then
-            Unblock (V);
-         else
-            if V in A_K.First_Index .. A_K.Last_Index then
-               for W of A_K (V) loop
-                  if (for all V1 of B (W) => V /= V1) then
-                     B (W).Append (V);
-                  end if;
-               end loop;
-            end if;
-         end if;
-         Stack.Pop;
-         if Trace > 0 then
-            Ada.Text_IO.Put_Line ("circuit finish" & V'Image);
-         end if;
-         return F;
-      end Circuit;
-
-   begin
-      --  [3] restricts the graph to not have loops (edge v-v) or multiple
-      --  edges between two nodes. So we first delete any such edges.
-      Delete_Loops_Multigraph :
-      for V in Edited_Graph.Vertices.First_Index .. 
Edited_Graph.Vertices.Last_Index loop
-         declare
-            use Edge_Node_Lists;
-            Cur        : Cursor  := Edited_Graph.Vertices (V).First;
-            Temp       : Cursor;
-            Found_Loop : Boolean := False;
-         begin
-            loop
-               exit when not Has_Element (Cur);
-               if Element (Cur).Vertex_B = V then
-                  if not Found_Loop then
-                     --  This is a cycle we want in the result. Edge data is 
added to all
-                     --  cycles later.
-                     Result.Append (Path'(1 => (V, Edge_Lists.Empty_List)));
-                     Found_Loop := True;
-                  end if;
-                  Temp := Cur;
-                  Next (Cur);
-                  Edited_Graph.Vertices (V).Delete (Temp);
-               elsif Element (Cur).Multigraph then
-                  --  These will be added back from Graph after we find all 
cycles.
-                  Temp := Cur;
-                  Next (Cur);
-                  Edited_Graph.Vertices (V).Delete (Temp);
-               else
-                  Next (Cur);
-               end if;
-            end loop;
-         end;
-      end loop Delete_Loops_Multigraph;
-
-      B.Set_First_Last (Graph.Vertices.First_Index, Graph.Vertices.Last_Index);
-
-      --  Start of body of Circuit-Finding Algorithm from [3]
-      loop
-         exit when S = Graph.Vertices.Last_Index;
-         declare
-            use Component_Lists;
-            Subgraph         : Adjacency_Structures.Vector;
-            Components       : Component_Lists.List;
-            Cur              : Component_Lists.Cursor;
-            Least_Vertex_Cur : Component_Lists.Cursor;
-            Least_Vertex_V   : Vertex_Index := Vertex_Index'Last;
-
-            function Delete_Edges (Edges : in Edge_Node_Lists.List) return 
Vertex_Lists.List
-            is begin
-               return Result : Vertex_Lists.List do
-                  for Edge of Edges loop
-                     if Edge.Vertex_B >= S then
-                        Result.Append (Edge.Vertex_B);
-                     end if;
-                  end loop;
-               end return;
-            end Delete_Edges;
-         begin
-            Subgraph.Set_First_Last (S, Edited_Graph.Vertices.Last_Index);
-            for V in S .. Edited_Graph.Vertices.Last_Index loop
-               Subgraph (V) := Delete_Edges (Edited_Graph.Vertices (V));
-            end loop;
-
-            Components := Strongly_Connected_Components (Subgraph, 
Non_Trivial_Only => True);
-            Cur        := Components.First;
-            loop
-               exit when not Has_Element (Cur);
-
-               if Element (Cur).Length > 1 then
-                  declare
-                     Comp : Vertex_Lists.List renames 
Components.Constant_Reference (Cur);
-                  begin
-                     for W of Comp loop
-                        if W < Least_Vertex_V then
-                           Least_Vertex_Cur := Cur;
-                           Least_Vertex_V   := W;
-                        end if;
-                     end loop;
-                  end;
-               end if;
-               Next (Cur);
-            end loop;
-
-            A_K.Clear;
-            if Has_Element (Least_Vertex_Cur) then
-               declare
-                  Component : Vertex_Lists.List renames Components 
(Least_Vertex_Cur);
-                  Min : Vertex_Index := Vertex_Index'Last;
-                  Max : Vertex_Index := Vertex_Index'First;
-               begin
-                  if Trace > 0 then
-                     Ada.Text_IO.Put_Line ("strong component " & 
Least_Vertex_V'Image);
-                     Ada.Text_IO.Put_Line (Image (Component));
-                  end if;
-                  for V of Component loop
-                     if Min > V then
-                        Min := V;
-                     end if;
-                     if Max < V then
-                        Max := V;
-                     end if;
-                  end loop;
-                  A_K.Set_First_Last (Min, Max);
-                  for V of Component loop
-                     for Edge of Edited_Graph.Vertices (V) loop
-                        A_K (V).Append (Edge.Vertex_B);
-                     end loop;
-                  end loop;
-               end;
-            end if;
-         end;
-
-         if A_K.Length > 0 then
-            S := A_K.First_Index;
-            for I in A_K.First_Index .. A_K.Last_Index loop
-               Blocked (I) := False;
-               B (I).Clear;
-            end loop;
-            Dummy := Circuit (S);
-            S := S + 1;
-         else
-            S := Graph.Vertices.Last_Index;
-         end if;
-      end loop;
-
-      --  Add edge data.
-      for Cycle of Result loop
-         for I in Cycle'First .. Cycle'Last loop
-            declare
-               Prev_I : constant Positive := (if I = Cycle'First then 
Cycle'Last else I - 1);
-            begin
-               for Edge of Graph.Vertices (Cycle (Prev_I).Vertex) loop
-                  if Cycle (I).Vertex = Edge.Vertex_B then
-                     Cycle (I).Edges.Append ((Edge.ID, Edge.Data));
-                  end if;
-               end loop;
-            end;
-         end loop;
-      end loop;
-      return Result;
-   end Find_Cycles;
-
-   function Loops (Graph : in Gen_Graphs.Graph) return Vertex_Lists.List
-   is begin
-      return Result : Vertex_Lists.List do
-         for V in Graph.Vertices.First_Index .. Graph.Vertices.Last_Index loop
-            for Edge of Graph.Vertices (V) loop
-               if V = Edge.Vertex_B then
-                  Result.Append (V);
-                  exit;
-               end if;
-            end loop;
-         end loop;
-      end return;
-   end Loops;
-
-   function To_Adjancency (Graph : in Gen_Graphs.Graph) return 
Adjacency_Structures.Vector
-   is
-      function To_Vertex_List (Edges : in Edge_Node_Lists.List) return 
Vertex_Lists.List
-      is begin
-         return Result : Vertex_Lists.List do
-            for Edge of Edges loop
-               Result.Append (Edge.Vertex_B);
-            end loop;
-         end return;
-      end To_Vertex_List;
-   begin
-      return Result : Adjacency_Structures.Vector do
-         Result.Set_First_Last (Graph.Vertices.First_Index, 
Graph.Vertices.Last_Index);
-         for V in Graph.Vertices.First_Index .. Graph.Vertices.Last_Index loop
-            Result (V) := To_Vertex_List (Graph.Vertices (V));
-         end loop;
-      end return;
-   end To_Adjancency;
-
-   function Strongly_Connected_Components
-     (Graph            : in Adjacency_Structures.Vector;
-      Non_Trivial_Only : in Boolean := False)
-     return Component_Lists.List
-   is
-      --  Implements [4] section 4.
-
-      Low_Link : array (Graph.First_Index .. Graph.Last_Index) of 
Vertex_Index'Base := (others => Invalid_Vertex);
-
-      Number : array (Graph.First_Index .. Graph.Last_Index) of 
Vertex_Index'Base := (others => Invalid_Vertex);
-      --  Number is the order visited in the depth-first search.
-
-      Points : Vertex_Stacks.Stack;
-
-      I : Vertex_Index'Base := Graph.First_Index - 1;
-
-      Result : Component_Lists.List;
-
-      procedure Strong_Connect (V : in Vertex_Index)
-      is begin
-         I            := I + 1;
-         Number (V)   := I;
-         Low_Link (V) := I;
-         Points.Push (V);
-
-         for W of Graph (V) loop
-            if Number (W) = Invalid_Vertex then
-               --  (v, w) is a tree arc
-               Strong_Connect (W);
-               Low_Link (V) := Vertex_Index'Min (Low_Link (V), Low_Link (W));
-
-            elsif Number (W) < Number (V) then
-               --  (v, w) is a frond or cross-link
-               if (for some P of Points => P = W) then
-                  Low_Link (V) := Vertex_Index'Min (Low_Link (V), Low_Link 
(W));
-               end if;
-            end if;
-         end loop;
-         if Low_Link (V) = Number (V) then
-            --  v is the root of a component
-            declare
-               use all type Ada.Containers.Count_Type;
-               Component : Vertex_Lists.List;
-            begin
-               while (not Points.Is_Empty) and then Number (Points.Peek) >= 
Number (V) loop
-                  Component.Append (Points.Pop);
-               end loop;
-               if (not Non_Trivial_Only) or Component.Length > 1 then
-                  Result.Append (Component);
-               end if;
-            end;
-         end if;
-      end Strong_Connect;
-   begin
-      for W in Graph.First_Index .. Graph.Last_Index loop
-         if Number (W) = Invalid_Vertex then
-            Strong_Connect (W);
-         end if;
-      end loop;
-      return Result;
-   end Strongly_Connected_Components;
-
-end SAL.Gen_Graphs;
diff --git a/packages/wisi/sal-gen_graphs.ads b/packages/wisi/sal-gen_graphs.ads
deleted file mode 100644
index 03cc1c6..0000000
--- a/packages/wisi/sal-gen_graphs.ads
+++ /dev/null
@@ -1,190 +0,0 @@
---  Abstract :
---
---  Type and operations for graphs.
---
---  References:
---
---  [1] Introduction to Algorithms, Thomas H. Cormen, Charles E.
---  Leiserson, Ronald L. Rivest, Clifford Stein.
---
---  [2] "An Efficient Search Algorithm to Find the Elementary Circuits
---  of a Graph", James C. Tiernan, Communications of the ACM Volume 13
---  Number 12 December 1970.
---  
https://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.516.9454&rep=rep1&type=pdf
---
---  [3] "Finding all the Elementary Circuits of a Directed Graph",
---  Donald B. Johnson, SIAM J. Comput. Vol 4, No. 1, March 1975.
---  https://epubs.siam.org/doi/abs/10.1137/0204007
---
---  [4] "Depth-First Search and Linear Graph Algorithms", Robert
---  Tarjan, SIAM J. Comput. Vol. 1, No 2, June 1972.
---  https://epubs.siam.org/doi/abs/10.1137/0201010
---
---  Copyright (C) 2017, 2019, 2020 Free Software Foundation All Rights 
Reserved.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-with Ada.Containers.Doubly_Linked_Lists;
-with Ada.Containers.Indefinite_Vectors;
-with SAL.Ada_Containers.Gen_Doubly_Linked_Lists_Image;
-with SAL.Gen_Trimmed_Image;
-with SAL.Gen_Unbounded_Definite_Vectors;
-generic
-   type Edge_Data is private;
-   Default_Edge_Data : in Edge_Data;
-   type Vertex_Index is range <>;
-   Invalid_Vertex : in Vertex_Index'Base;
-
-   type Path_Index is range <>;
-
-   with function Edge_Image (Item : in Edge_Data) return String;
-
-package SAL.Gen_Graphs is
-
-   type Graph is tagged private;
-
-   procedure Add_Edge
-     (Graph    : in out Gen_Graphs.Graph;
-      Vertex_A : in     Vertex_Index;
-      Vertex_B : in     Vertex_Index;
-      Data     : in     Edge_Data);
-   --  Adds a directed edge from Vertex_A to Vertex_B.
-
-   function Count_Nodes (Graph : in Gen_Graphs.Graph) return 
Ada.Containers.Count_Type;
-   function Count_Edges (Graph : in Gen_Graphs.Graph) return 
Ada.Containers.Count_Type;
-
-   function Multigraph (Graph : in Gen_Graphs.Graph) return Boolean;
-   --  If more than one edge is added between two vertices, the graph is
-   --  a multigraph. The edges are given separate identifiers internally.
-
-   Multigraph_Error : exception;
-
-   type Base_Edge_ID is range 0 .. Integer'Last;
-   subtype Edge_ID is Base_Edge_ID range 1 .. Base_Edge_ID'Last;
-   Invalid_Edge_ID : constant Base_Edge_ID := 0;
-   --  Edge ids are unique graph-wide, assigned by Add_Edge.
-
-   type Edge_Item is record
-      ID   : Base_Edge_ID := Invalid_Edge_ID;
-      Data : Edge_Data    := Default_Edge_Data;
-   end record;
-   function Image (Item : in Edge_Item) return String
-     is (Edge_Image (Item.Data));
-
-   package Edge_Lists is new Ada.Containers.Doubly_Linked_Lists (Edge_Item);
-
-   function "+" (Right : in Edge_Item) return Edge_Lists.List;
-
-   function Edges (Graph : in Gen_Graphs.Graph; Vertex : in Vertex_Index) 
return Edge_Lists.List;
-   --  All edges from Vertex, as set by Add_Edge.
-
-   function Image is new SAL.Ada_Containers.Gen_Doubly_Linked_Lists_Image
-     (Element_Type  => Edge_Item,
-      Lists         => Edge_Lists,
-      Element_Image => Image);
-
-   type Path_Item is record
-      Vertex : Vertex_Index'Base := Invalid_Vertex;
-      Edges  : Edge_Lists.List;
-      --  Edges describe the edges leading from the previous vertex
-      --  in the path to Vertex. If this is the first vertex in an open
-      --  path, Edges is empty. If it is the first vertex in a
-      --  cycle, the edge are from the last vertex in the cycle.
-   end record;
-
-   type Path is array (Positive range <>) of Path_Item;
-
-   function Image (Item : in Path) return String;
-   --  For trace, debugging.
-
-   package Path_Arrays is new Ada.Containers.Indefinite_Vectors (Path_Index, 
Path);
-
-   function "<" (Left, Right : in Path) return Boolean;
-
-   package Sort_Paths is new Path_Arrays.Generic_Sorting;
-
-   function Find_Paths
-     (Graph : in out Gen_Graphs.Graph;
-      From  : in     Vertex_Index;
-      To    : in     Edge_Data)
-     return Path_Arrays.Vector;
-   --  Return all non-cyclic paths starting at From that lead to a To
-   --  edge, using algorithm [1]. First entry in each item in result is
-   --  From, with first edge. Last entry in result contains edge data for
-   --  To.
-   --
-   --  Raises Multigraph_Error if Graph is a multigraph.
-
-   function Find_Cycles_Tiernan (Graph : in Gen_Graphs.Graph) return 
Path_Arrays.Vector;
-   --  Return all cyclic paths in Graph, using algorithm [2] extended for
-   --  multigraphs.
-   --
-   --  Time complexity is exponential in the number of nodes. Used in
-   --  unit tests for Find_Cycles, since [2] is easier to
-   --  implement.
-
-   function Find_Cycles (Graph : in Gen_Graphs.Graph) return 
Path_Arrays.Vector;
-   --  Return all cyclic paths in Graph, using algorithm [3] extended for
-   --  multigraphs.
-   --
-   --  Time complexity is linear in the number of nodes and edges.
-
-   package Vertex_Lists is new Ada.Containers.Doubly_Linked_Lists 
(Vertex_Index);
-   function Trimmed_Image is new SAL.Gen_Trimmed_Image (Vertex_Index);
-   function Image is new SAL.Ada_Containers.Gen_Doubly_Linked_Lists_Image
-     (Vertex_Index, "=", Vertex_Lists, Trimmed_Image);
-
-   function Loops (Graph : in Gen_Graphs.Graph) return Vertex_Lists.List;
-   --  List of vertices that have an edge to themselves.
-
-   package Adjacency_Structures is new SAL.Gen_Unbounded_Definite_Vectors
-     (Vertex_Index, Vertex_Lists.List, Vertex_Lists.Empty_List);
-   --  Graphs with no Edge_ID or Edge_Data; useful as intermediate results.
-
-   function To_Adjancency (Graph : in Gen_Graphs.Graph) return 
Adjacency_Structures.Vector;
-
-   package Component_Lists is new Ada.Containers.Doubly_Linked_Lists 
(Vertex_Lists.List, Vertex_Lists."=");
-
-   function Strongly_Connected_Components
-     (Graph            : in Adjacency_Structures.Vector;
-      Non_Trivial_Only : in Boolean := False)
-     return Component_Lists.List;
-   --  Find strongly connected components of Graph, using algorithm in [4].
-   --  If Non_Trivial_Only, don't include single-vertex components.
-
-   Trace : Integer := 0;
-   --  Some bodies output debug info to Text_IO.Current_Output for
-   --  non-zero values of Trace.
-private
-
-   type Edge_Node is record
-      --  Edge is from vertex contaning this Node to Vertex_B
-      ID         : Edge_ID;
-      Vertex_B   : Vertex_Index;
-      Multigraph : Boolean; -- Same Vertex_B as another edge in same vertex.
-      Data       : Edge_Data;
-   end record;
-
-   package Edge_Node_Lists is new Ada.Containers.Doubly_Linked_Lists 
(Edge_Node);
-
-   package Vertex_Arrays is new SAL.Gen_Unbounded_Definite_Vectors
-     (Vertex_Index, Edge_Node_Lists.List, Edge_Node_Lists.Empty_List);
-
-   type Graph is tagged record
-      Last_Edge_ID : Base_Edge_ID := Invalid_Edge_ID;
-      Multigraph   : Boolean      := False;
-      Vertices     : Vertex_Arrays.Vector;
-   end record;
-
-end SAL.Gen_Graphs;
diff --git a/packages/wisi/sal-gen_indefinite_doubly_linked_lists.adb 
b/packages/wisi/sal-gen_indefinite_doubly_linked_lists.adb
deleted file mode 100644
index 71d3f61..0000000
--- a/packages/wisi/sal-gen_indefinite_doubly_linked_lists.adb
+++ /dev/null
@@ -1,211 +0,0 @@
---  Abstract :
---
---  see spec
---
---  Copyright (C) 2018 - 2020 Free Software Foundation, Inc.
---
---  This library is free software; you can redistribute it and/or
---  modify it under terms of the GNU General Public License as
---  published by the Free Software Foundation; either version 3, or (at
---  your option) any later version. This library 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
---  distributed with this program; see file COPYING. If not, write to
---  the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
---  MA 02111-1307, USA.
---
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-package body SAL.Gen_Indefinite_Doubly_Linked_Lists is
-
-   ---------
-   --  Public operations, declaration order.
-
-   overriding
-   procedure Adjust (Container : in out List)
-   is
-      Source   : Node_Access := Container.Head;
-      New_Node : Node_Access;
-   begin
-      if Source = null then
-         return;
-      end if;
-
-      Container.Tail := null;
-
-      loop
-         New_Node := new Node_Type'
-           (Element => new Element_Type'(Source.Element.all),
-            Next    => null,
-            Prev    => Container.Tail);
-         if Container.Tail = null then
-            Container.Head := New_Node;
-            Container.Tail := New_Node;
-         else
-            Container.Tail.Next := New_Node;
-            Container.Tail      := New_Node;
-         end if;
-         Source := Source.Next;
-         exit when Source = null;
-      end loop;
-   end Adjust;
-
-   overriding
-   procedure Finalize (Container : in out List)
-   is
-      Next : Node_Access := Container.Head;
-   begin
-      loop
-         exit when Next = null;
-         Next := Container.Head.Next;
-         Free (Container.Head.Element);
-         Free (Container.Head);
-         Container.Head := Next;
-      end loop;
-      Container.Tail := null;
-   end Finalize;
-
-   function Length (Container : in List) return SAL.Base_Peek_Type
-   is begin
-      return Container.Count;
-   end Length;
-
-   procedure Append (Container : in out List; Element : in Element_Type)
-   is
-      New_Node : constant Node_Access := new Node_Type'
-        (Element => new Element_Type'(Element),
-         Prev    => Container.Tail,
-         Next    => null);
-   begin
-      if Container.Tail = null then
-         Container.Head := New_Node;
-         Container.Tail := New_Node;
-      else
-         Container.Tail.Next := New_Node;
-         Container.Tail      := New_Node;
-      end if;
-      Container.Count := Container.Count + 1;
-   end Append;
-
-   procedure Prepend (Container : in out List; Element : in Element_Type)
-   is
-      New_Node : constant Node_Access := new Node_Type'
-        (Element => new Element_Type'(Element),
-         Prev    => null,
-         Next    => Container.Head);
-   begin
-      if Container.Tail = null then
-         Container.Head := New_Node;
-         Container.Tail := New_Node;
-      else
-         Container.Head.Prev := New_Node;
-         Container.Head      := New_Node;
-      end if;
-      Container.Count := Container.Count + 1;
-   end Prepend;
-
-   function Has_Element (Position : in Cursor) return Boolean
-   is begin
-      return Position.Ptr /= null;
-   end Has_Element;
-
-   function First (Container : in List) return Cursor
-   is begin
-      if Container.Head = null then
-         return (Ptr => null);
-      else
-         return (Ptr => Container.Head);
-      end if;
-   end First;
-
-   procedure Next (Position : in out Cursor)
-   is begin
-      if Position.Ptr /= null then
-         if Position.Ptr.Next = null then
-            Position.Ptr := null;
-         else
-            Position.Ptr := Position.Ptr.Next;
-         end if;
-      end if;
-   end Next;
-
-   function Next (Position : in Cursor) return Cursor
-   is begin
-      if Position.Ptr = null then
-         return Position;
-      else
-         if Position.Ptr.Next = null then
-            return (Ptr => null);
-         else
-            return (Ptr => Position.Ptr.Next);
-         end if;
-      end if;
-   end Next;
-
-   function Element (Position : in Cursor) return Element_Type
-   is begin
-      return Position.Ptr.Element.all;
-   end Element;
-
-   procedure Delete (Container : in out List; Position : in out Cursor)
-   is
-      Node : Node_Access renames Position.Ptr;
-   begin
-      if Node.Next = null then
-         Container.Tail := Node.Prev;
-      else
-         Node.Next.Prev := Node.Prev;
-      end if;
-      if Node.Prev = null then
-         Container.Head := Node.Next;
-      else
-         Node.Prev.Next := Node.Next;
-      end if;
-      Free (Node.Element);
-      Free (Node);
-      Position        := (Ptr => null);
-      Container.Count := Container.Count - 1;
-   end Delete;
-
-   function Persistent_Ref (Position : in Cursor) return access Element_Type
-   is begin
-      return Position.Ptr.Element;
-   end Persistent_Ref;
-
-   function Constant_Ref (Position : in Cursor) return Constant_Reference_Type
-   is begin
-      return (Element => Position.Ptr.all.Element, Dummy => 1);
-   end Constant_Ref;
-
-   function Constant_Reference (Container : in List; Position : in Peek_Type) 
return Constant_Reference_Type
-   is
-      Ptr : Node_Access := Container.Head;
-   begin
-      for I in 2 .. Position loop
-         Ptr := Ptr.Next;
-      end loop;
-      return (Element => Ptr.all.Element, Dummy => 1);
-   end Constant_Reference;
-
-   function Variable_Reference (Container : in List; Position : in Peek_Type) 
return Variable_Reference_Type
-   is
-      Ptr : Node_Access := Container.Head;
-   begin
-      for I in 2 .. Position loop
-         Ptr := Ptr.Next;
-      end loop;
-      return (Element => Ptr.all.Element, Dummy => 1);
-   end Variable_Reference;
-
-   function Variable_Ref (Position : in Cursor) return Variable_Reference_Type
-   is begin
-      return (Element => Position.Ptr.all.Element, Dummy => 1);
-   end Variable_Ref;
-
-end SAL.Gen_Indefinite_Doubly_Linked_Lists;
diff --git a/packages/wisi/sal-gen_indefinite_doubly_linked_lists.ads 
b/packages/wisi/sal-gen_indefinite_doubly_linked_lists.ads
deleted file mode 100644
index b1d1cdb..0000000
--- a/packages/wisi/sal-gen_indefinite_doubly_linked_lists.ads
+++ /dev/null
@@ -1,128 +0,0 @@
---  Abstract :
---
---  A generic doubly linked list with indefinite elements, allowing
---  permanent references to elements.
---
---  Copyright (C) 2018 - 2020 Free Software Foundation, Inc.
---
---  This library is free software; you can redistribute it and/or
---  modify it under terms of the GNU General Public License as
---  published by the Free Software Foundation; either version 3, or (at
---  your option) any later version. This library 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
---  distributed with this program; see file COPYING. If not, write to
---  the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
---  MA 02111-1307, USA.
---
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-with Ada.Finalization;
-with Ada.Unchecked_Deallocation;
-generic
-   type Element_Type (<>) is private;
-package SAL.Gen_Indefinite_Doubly_Linked_Lists is
-
-   type List is new Ada.Finalization.Controlled with private with
-     Constant_Indexing => Constant_Reference,
-     Variable_Indexing => Variable_Reference;
-
-   Empty_List : constant List;
-
-   overriding procedure Adjust (Container : in out List);
-   --  Deep copy.
-
-   overriding procedure Finalize (Container : in out List);
-   --  Free all items in List.
-
-   function Length (Container : in List) return Base_Peek_Type;
-
-   procedure Append (Container : in out List; Element : in Element_Type);
-
-   procedure Prepend (Container : in out List; Element : in Element_Type);
-
-   type Cursor is private;
-
-   No_Element : constant Cursor;
-
-   function Has_Element (Position : in Cursor) return Boolean;
-
-   function First (Container : in List) return Cursor;
-
-   procedure Next (Position : in out Cursor);
-
-   function Next (Position : in Cursor) return Cursor;
-
-   function Element (Position : in Cursor) return Element_Type
-   with Pre => Has_Element (Position);
-
-   procedure Delete (Container : in out List; Position : in out Cursor)
-   with Pre => Has_Element (Position);
-
-   function Persistent_Ref (Position : in Cursor) return access Element_Type
-   with Pre => Has_Element (Position);
-
-   type Constant_Reference_Type (Element : not null access constant 
Element_Type) is private with
-     Implicit_Dereference => Element;
-
-   function Constant_Ref (Position : in Cursor) return Constant_Reference_Type
-   with Inline, Pre => Has_Element (Position);
-
-   function Constant_Reference (Container : in List; Position : in Peek_Type) 
return Constant_Reference_Type
-   with Inline, Pre => Position <= Container.Length;
-
-   type Variable_Reference_Type (Element : not null access Element_Type) is 
private with
-     Implicit_Dereference => Element;
-
-   function Variable_Reference (Container : in List; Position : in Peek_Type) 
return Variable_Reference_Type
-   with Inline, Pre => Position <= Container.Length;
-
-   function Variable_Ref (Position : in Cursor) return Variable_Reference_Type
-   with Inline, Pre => Has_Element (Position);
-
-private
-   type Node_Type;
-   type Node_Access is access Node_Type;
-   type Element_Access is access Element_Type;
-
-
-   type Node_Type is record
-      Element : Element_Access;
-      Prev    : Node_Access;
-      Next    : Node_Access;
-   end record;
-
-   procedure Free is new Ada.Unchecked_Deallocation (Node_Type, Node_Access);
-   procedure Free is new Ada.Unchecked_Deallocation (Element_Type, 
Element_Access);
-
-   type List is new Ada.Finalization.Controlled with record
-      Head  : Node_Access        := null;
-      Tail  : Node_Access        := null;
-      Count : SAL.Base_Peek_Type := 0;
-   end record;
-
-   type Cursor is record
-      Ptr : Node_Access;
-   end record;
-
-   type Constant_Reference_Type (Element : not null access constant 
Element_Type) is
-   record
-      Dummy : Integer := raise Program_Error with "uninitialized reference";
-   end record;
-
-   type Variable_Reference_Type (Element : not null access Element_Type) is
-   record
-      Dummy : Integer := raise Program_Error with "uninitialized reference";
-   end record;
-
-   Empty_List : constant List := (Ada.Finalization.Controlled with null, null, 
0);
-
-   No_Element : constant Cursor := (Ptr => null);
-
-end SAL.Gen_Indefinite_Doubly_Linked_Lists;
diff --git a/packages/wisi/sal-gen_trimmed_image.adb 
b/packages/wisi/sal-gen_trimmed_image.adb
deleted file mode 100644
index 41fb042..0000000
--- a/packages/wisi/sal-gen_trimmed_image.adb
+++ /dev/null
@@ -1,28 +0,0 @@
---  Abstract :
---
---  See spec.
---
---  Copyright (C) 2018 Stephen Leake All Rights Reserved.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-with Ada.Strings;
-with Ada.Strings.Fixed;
-function SAL.Gen_Trimmed_Image (Item : in Element_Type) return String
-is
-   use Ada.Strings;
-   use Ada.Strings.Fixed;
-begin
-   return Trim (Element_Type'Image (Item), Both);
-end SAL.Gen_Trimmed_Image;
diff --git a/packages/wisi/sal-gen_trimmed_image.ads 
b/packages/wisi/sal-gen_trimmed_image.ads
deleted file mode 100644
index 3ff29f9..0000000
--- a/packages/wisi/sal-gen_trimmed_image.ads
+++ /dev/null
@@ -1,23 +0,0 @@
---  Abstract :
---
---  Generic trimmed image.
---
---  Copyright (C) 2018 Free Software Foundation, Inc.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-generic
-   type Element_Type is range <>;
-function SAL.Gen_Trimmed_Image (Item : in Element_Type) return String;
---  Return image of Item with no leading space.
diff --git a/packages/wisi/sal-gen_unbounded_definite_min_heaps_fibonacci.adb 
b/packages/wisi/sal-gen_unbounded_definite_min_heaps_fibonacci.adb
deleted file mode 100644
index c88a0cb..0000000
--- a/packages/wisi/sal-gen_unbounded_definite_min_heaps_fibonacci.adb
+++ /dev/null
@@ -1,354 +0,0 @@
---  Abstract:
---
---  See spec.
---
---  Copyright (C) 2017 - 2019 Free Software Foundation, Inc.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
---
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-with Ada.Unchecked_Deallocation;
-with Long_Float_Elementary_Functions;
-package body SAL.Gen_Unbounded_Definite_Min_Heaps_Fibonacci is
-
-   ----------
-   --  local subprogram specs (as needed), alphabetical order
-
-   procedure Insert_Into_Root_List (Heap : in out Heap_Type; X : in 
Node_Access);
-
-   procedure Link (Y, X : in Node_Access);
-
-   procedure Remove_From_List (X : in Node_Access);
-
-   procedure Swap (A, B : in out Node_Access);
-
-   ----------
-   --  local subprogram bodies, alphabetical order
-
-   procedure Consolidate (Heap : in out Heap_Type)
-   is
-      --  [1] 19.4 max degree of Fibonacci heap
-      Phi : constant := 1.61803398874989484820458683436563811772; -- 
https://oeis.org/A001622/constant
-      Max_Degree : constant Integer := Integer
-        (Long_Float_Elementary_Functions.Log (Long_Float (Heap.Count), Base => 
Phi));
-
-      --  [1] 19.2 CONSOLIDATE
-      A : array (0 .. Max_Degree) of Node_Access := (others => null);
-
-      W    : Node_Access := Heap.Min;
-      Last : Node_Access := Heap.Min;
-      X, Y : Node_Access;
-      D    : Integer;
-
-      Min_Key : Key_Type;
-   begin
-      loop
-         X := W;
-         W := W.Right;
-
-         D := X.Degree;
-
-         loop
-            exit when A (D) = null;
-
-            Y := A (D);
-            if Key (Y.Element) < Key (X.Element) then
-               Swap (X, Y);
-            end if;
-            if Y = Last and W /= Last then
-               Last := Y.Right;
-            end if;
-            Link (Y, X);
-            A (D) := null;
-            D := D + 1;
-            exit when D = A'Last;
-         end loop;
-
-         A (D) := X;
-
-         exit when W = Last;
-      end loop;
-
-      Heap.Min := null;
-      for I in A'Range loop
-         if A (I) /= null then
-            if Heap.Min = null then
-               Heap.Min       := A (I);
-               Heap.Min.Left  := Heap.Min;
-               Heap.Min.Right := Heap.Min;
-               Min_Key        := Key (Heap.Min.Element);
-            else
-               Insert_Into_Root_List (Heap, A (I));
-               if Key (A (I).Element) < Min_Key then
-                  Heap.Min := A (I);
-                  Min_Key := Key (A (I).Element);
-               end if;
-            end if;
-         end if;
-      end loop;
-   end Consolidate;
-
-   procedure Copy_Node (Old_Obj : in Node_Access; New_Obj : in out Heap_Type)
-   is
-      Child : Node_Access;
-   begin
-      if Old_Obj = null then
-         return;
-      end if;
-
-      if Old_Obj.Child /= null then
-         Child := Old_Obj.Child;
-
-         loop
-            Add (New_Obj, Child.Element);
-            Child := Child.Right;
-            exit when Child = Old_Obj.Child;
-         end loop;
-      end if;
-
-      Add (New_Obj, Old_Obj.Element);
-   end Copy_Node;
-
-   procedure Free is new Ada.Unchecked_Deallocation (Node, Node_Access);
-
-   procedure Free_Node (Item : in out Node_Access)
-   is
-      Child : Node_Access;
-      Temp  : Node_Access;
-   begin
-      if Item = null then
-         return;
-      end if;
-
-      --  Parent has already been free'd
-      --  Siblings are freed by caller
-
-      --  Free children
-      if Item.Child /= null then
-         Child := Item.Child;
-
-         loop
-            Temp  := Child;
-            Child := Child.Right;
-            Free_Node (Temp);
-            exit when Child = Item.Child;
-         end loop;
-      end if;
-      Free (Item);
-   end Free_Node;
-
-   procedure Insert_Into_Root_List (Heap : in out Heap_Type; X : in 
Node_Access)
-   is begin
-      --  match [1] fig 19.3
-      X.Right             := Heap.Min;
-      X.Left              := Heap.Min.Left;
-      Heap.Min.Left.Right := X;
-      Heap.Min.Left       := X;
-   end Insert_Into_Root_List;
-
-   procedure Link (Y, X : in Node_Access)
-   is begin
-      --  [1] 19.2 FIB-HEAP-LINK
-      Remove_From_List (Y);
-      Y.Parent := X;
-      X.Degree := X.Degree + 1;
-      if X.Child = null then
-         X.Child := Y;
-         Y.Right := Y;
-         Y.Left  := Y;
-      else
-         --  Insert Y into X child list
-         Y.Right            := X.Child;
-         Y.Left             := X.Child.Left;
-         X.Child.Left.Right := Y;
-         X.Child.Left       := Y;
-      end if;
-      Y.Mark := False;
-   end Link;
-
-   procedure Remove_From_List (X : in Node_Access)
-   is begin
-      X.Left.Right := X.Right;
-      X.Right.Left := X.Left;
-   end Remove_From_List;
-
-   procedure Swap (A, B : in out Node_Access)
-   is
-      C : constant Node_Access := A;
-   begin
-      A := B;
-      B := C;
-   end Swap;
-
-   ----------
-   --  Visible operations
-
-   overriding
-   procedure Initialize (Object : in out Heap_Type)
-   is begin
-      --  Min is null by default.
-      Object.Count := 0;
-   end Initialize;
-
-   overriding
-   procedure Finalize (Object : in out Heap_Type)
-   is
-      Next : Node_Access := Object.Min;
-      Temp : Node_Access;
-   begin
-      if Next = null then
-         return;
-      end if;
-
-      loop
-         Temp := Next;
-         Next := Next.Right;
-         Free_Node (Temp);
-         exit when Next = Object.Min;
-      end loop;
-      Object.Min   := null;
-      Object.Count := 0;
-   end Finalize;
-
-   overriding
-   procedure Adjust (Object : in out Heap_Type)
-   is
-      Old_Obj : Node_Access := Object.Min;
-      Last : constant Node_Access := Old_Obj;
-   begin
-      if Old_Obj = null then
-         return;
-      end if;
-
-      Object.Min := null;
-      Object.Count := 0;
-
-      loop
-         Copy_Node (Old_Obj, Object);
-         Old_Obj := Old_Obj.Right;
-         exit when Old_Obj = Last;
-      end loop;
-   end Adjust;
-
-   procedure Clear (Heap : in out Heap_Type)
-   is begin
-      Finalize (Heap);
-   end Clear;
-
-   function Count (Heap : in Heap_Type) return Base_Peek_Type
-   is begin
-      return Heap.Count;
-   end Count;
-
-   function Remove (Heap : in out Heap_Type) return Element_Type
-   is
-      Z           : Node_Access := Heap.Min;
-      Child, Temp : Node_Access;
-   begin
-      if Heap.Count = 0 then
-         raise Container_Empty;
-      end if;
-
-      --  [1] 19.2 FIB-HEAP-EXTRACT-MIN
-      Child := Z.Child;
-      for I in 1 .. Z.Degree loop
-         Temp        := Child;
-         Child       := Child.Right;
-         Temp.Parent := null;
-         Insert_Into_Root_List (Heap, Temp);
-      end loop;
-
-      Remove_From_List (Z);
-
-      if Z.Right = Z then
-         Heap.Min := null;
-      else
-         Heap.Min := Z.Right;
-         Consolidate (Heap);
-      end if;
-      Heap.Count := Heap.Count - 1;
-
-      return Result : constant Element_Type := Z.Element do
-         Free (Z);
-      end return;
-   end Remove;
-
-   function Min_Key (Heap : in out Heap_Type) return Key_Type
-   is begin
-      return Key (Heap.Min.Element);
-   end Min_Key;
-
-   procedure Drop (Heap : in out Heap_Type)
-   is
-      Junk : Element_Type := Remove (Heap);
-      pragma Unreferenced (Junk);
-   begin
-      null;
-   end Drop;
-
-   procedure Add (Heap : in out Heap_Type; Item : in Element_Type)
-   is
-      X : constant Node_Access := new Node'(Item, null, null, null, null, 0, 
False);
-   begin
-      --  [1] 19.2 FIB-HEAP-INSERT
-      if Heap.Min = null then
-         Heap.Min       := X;
-         Heap.Min.Left  := Heap.Min;
-         Heap.Min.Right := Heap.Min;
-      else
-         Insert_Into_Root_List (Heap, X);
-
-         if Key (Item) < Key (Heap.Min.Element) then
-            Heap.Min := X;
-         end if;
-      end if;
-      Heap.Count := Heap.Count + 1;
-   end Add;
-
-   function Peek (Heap : in Heap_Type) return Constant_Reference_Type
-   is begin
-      return (Element => Heap.Min.all.Element'Access, Dummy => 1);
-   end Peek;
-
-   procedure Process (Heap : in Heap_Type; Process_Element : access procedure 
(Element : in Element_Type))
-   is
-      type Cursor is record
-         --  Every node is in a circular list. List_Origin is the node where we
-         --  entered the list, so we know when we are done.
-         Node        : Node_Access;
-         List_Origin : Node_Access;
-      end record;
-
-      Cur : Cursor := (Heap.Min, Heap.Min);
-
-      procedure Process_Node (Cur : in out Cursor)
-      is
-         Next_Cur : Cursor;
-      begin
-         loop
-            if Cur.Node.Child /= null then
-               Next_Cur := (Cur.Node.Child, Cur.Node.Child);
-               Process_Node (Next_Cur);
-            end if;
-            Process_Element (Cur.Node.Element);
-            Cur.Node := Cur.Node.Right;
-            exit when Cur.Node = Cur.List_Origin;
-         end loop;
-      end Process_Node;
-   begin
-      if Cur.Node /= null then
-         Process_Node (Cur);
-      end if;
-   end Process;
-
-end SAL.Gen_Unbounded_Definite_Min_Heaps_Fibonacci;
diff --git a/packages/wisi/sal-gen_unbounded_definite_min_heaps_fibonacci.ads 
b/packages/wisi/sal-gen_unbounded_definite_min_heaps_fibonacci.ads
deleted file mode 100644
index aab9fcf..0000000
--- a/packages/wisi/sal-gen_unbounded_definite_min_heaps_fibonacci.ads
+++ /dev/null
@@ -1,112 +0,0 @@
---  Abstract:
---
---  An unbounded minimum Fibonacci heap of definite non-limited elements.
---
---  References:
---
---  [1] Introduction to Algorithms, Third Edition. Thomas H. Cormen,
---  Charles E. Leiserson, Ronald L. Rivest, Clifford Stein. Chapter 19.
---
---  Copyright (C) 2017 - 2019 Free Software Foundation, Inc.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
---
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-with Ada.Finalization;
-generic
-   type Element_Type is private;
-   type Key_Type is private;
-   with function Key (Item : in Element_Type) return Key_Type;
-   with procedure Set_Key (Item : in out Element_Type; Key : in Key_Type);
-   pragma Unreferenced (Set_Key); -- needed for Decrease_Key
-   with function "<" (Left, Right : in Key_Type) return Boolean is <>;
-package SAL.Gen_Unbounded_Definite_Min_Heaps_Fibonacci is
-
-   type Heap_Type is new Ada.Finalization.Controlled with private;
-
-   Empty_Heap : constant Heap_Type;
-
-   overriding
-   procedure Initialize (Object : in out Heap_Type);
-
-   overriding
-   procedure Finalize (Object : in out Heap_Type);
-
-   overriding
-   procedure Adjust (Object : in out Heap_Type);
-
-   procedure Clear (Heap : in out Heap_Type);
-   --  Empty Heap.
-
-   function Count (Heap : in Heap_Type) return Base_Peek_Type;
-   --  Return count of elements in Heap.
-
-   function Remove (Heap : in out Heap_Type) return Element_Type;
-   --  Remove minimum element in Heap, return it.
-
-   function Min_Key (Heap : in out Heap_Type) return Key_Type;
-   --  Return a copy of the minimum key value.
-
-   function Get (Heap : in out Heap_Type) return Element_Type renames Remove;
-
-   procedure Drop (Heap : in out Heap_Type);
-   --  Remove minimum element in Heap, discard it.
-
-   procedure Add (Heap : in out Heap_Type; Item : in Element_Type);
-   --  Add Item to Heap.
-
-   procedure Insert (Heap : in out Heap_Type; Item : in Element_Type) renames 
Add;
-
-   type Constant_Reference_Type (Element : not null access constant 
Element_Type) is private with
-     Implicit_Dereference => Element;
-
-   function Peek (Heap : in Heap_Type) return Constant_Reference_Type;
-   --  Return a constant reference to the min element.
-   pragma Inline (Peek);
-
-   --  We don't provide a Cursor/Iterator interface; to complex to
-   --  implement. So far, we only need a read-only forward iterator,
-   --  which Process provides.
-
-   procedure Process (Heap : in Heap_Type; Process_Element : access procedure 
(Element : in Element_Type));
-   --  Call Process_Element with each Element in Heap. Min is first; rest are 
in
-   --  arbitrary order.
-
-private
-
-   type Node;
-   type Node_Access is access Node;
-
-   type Node is record
-      Element : aliased Element_Type;
-      Parent  : Node_Access;
-      Child   : Node_Access;
-      Left    : Node_Access;
-      Right   : Node_Access;
-      Degree  : Natural;
-      Mark    : Boolean;
-   end record;
-
-   type Heap_Type is new Ada.Finalization.Controlled with record
-      Min   : Node_Access;
-      Count : Base_Peek_Type;
-   end record;
-
-   type Constant_Reference_Type (Element : not null access constant 
Element_Type) is
-   record
-      Dummy : Integer := raise Program_Error with "uninitialized reference";
-   end record;
-
-   Empty_Heap : constant Heap_Type := (Ada.Finalization.Controlled with Min => 
null, Count => 0);
-
-end SAL.Gen_Unbounded_Definite_Min_Heaps_Fibonacci;
diff --git a/packages/wisi/sal-gen_unbounded_definite_queues-gen_image_aux.adb 
b/packages/wisi/sal-gen_unbounded_definite_queues-gen_image_aux.adb
deleted file mode 100644
index 2a1990b..0000000
--- a/packages/wisi/sal-gen_unbounded_definite_queues-gen_image_aux.adb
+++ /dev/null
@@ -1,35 +0,0 @@
---  Abstract :
---
---  See spec.
---
---  Copyright (C) 2018 Free Software Foundation, Inc.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-with Ada.Strings.Unbounded;
-function SAL.Gen_Unbounded_Definite_Queues.Gen_Image_Aux (Item : in Queue; Aux 
: in Aux_Data) return String
-is
-   use Ada.Strings.Unbounded;
-   Result : Unbounded_String        := To_Unbounded_String ("(");
-   Last   : constant Base_Peek_Type := Item.Count;
-begin
-   for I in 1 .. Last loop
-      Result := Result & Element_Image (Item.Peek (I), Aux);
-      if I /= Last then
-         Result := Result & ", ";
-      end if;
-   end loop;
-   Result := Result & ")";
-   return To_String (Result);
-end SAL.Gen_Unbounded_Definite_Queues.Gen_Image_Aux;
diff --git a/packages/wisi/sal-gen_unbounded_definite_queues-gen_image_aux.ads 
b/packages/wisi/sal-gen_unbounded_definite_queues-gen_image_aux.ads
deleted file mode 100644
index dafa8d9..0000000
--- a/packages/wisi/sal-gen_unbounded_definite_queues-gen_image_aux.ads
+++ /dev/null
@@ -1,23 +0,0 @@
---  Abstract :
---
---  Image with auxiliary data for instantiations of parent.
---
---  Copyright (C) 2018 Free Software Foundation, Inc.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-generic
-   type Aux_Data (<>) is private;
-   with function Element_Image (Item : in Element_Type; Aux : in Aux_Data) 
return String;
-function SAL.Gen_Unbounded_Definite_Queues.Gen_Image_Aux (Item : in Queue; Aux 
: in Aux_Data) return String;
diff --git a/packages/wisi/sal-gen_unbounded_definite_queues.adb 
b/packages/wisi/sal-gen_unbounded_definite_queues.adb
deleted file mode 100644
index af53823..0000000
--- a/packages/wisi/sal-gen_unbounded_definite_queues.adb
+++ /dev/null
@@ -1,97 +0,0 @@
---  Abstract:
---
---  See spec.
---
---  Copyright (C) 2017 - 2019 Free Software Foundation, Inc.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
---
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-package body SAL.Gen_Unbounded_Definite_Queues is
-
-   procedure Clear (Queue : in out Pkg.Queue)
-   is begin
-      Queue.Data.Clear;
-   end Clear;
-
-   function Count (Queue : in Pkg.Queue) return Base_Peek_Type
-   is begin
-      return Base_Peek_Type (Queue.Data.Length);
-   end Count;
-
-   function Is_Empty (Queue : in Pkg.Queue) return Boolean
-   is
-      use all type Ada.Containers.Count_Type;
-   begin
-      return Queue.Data.Length = 0;
-   end Is_Empty;
-
-   function Remove (Queue : in out Pkg.Queue) return Element_Type
-   is
-      use Element_Lists;
-   begin
-      return A : constant Element_Type := Element (Queue.Data.First) do
-         Queue.Data.Delete_First;
-      end return;
-   end Remove;
-
-   procedure Drop (Queue : in out Pkg.Queue)
-   is begin
-      Queue.Data.Delete_First;
-   end Drop;
-
-   function Peek (Queue : in Pkg.Queue; N : Peek_Type := 1) return 
Constant_Reference_Type
-   is
-      use Ada.Containers;
-      use Element_Lists;
-      I : Cursor := Queue.Data.First;
-   begin
-      if Count_Type (N) > Queue.Data.Length then
-         raise Parameter_Error;
-      end if;
-
-      for K in 2 .. N loop
-         Next (I);
-      end loop;
-
-      return (Element => Element_Lists.Constant_Reference (Queue.Data, 
I).Element, Dummy => 1);
-   end Peek;
-
-   function Variable_Peek (Queue : in out Pkg.Queue; N : Peek_Type := 1) 
return Variable_Reference_Type
-   is
-      use Ada.Containers;
-      use Element_Lists;
-      I : Cursor := Queue.Data.First;
-   begin
-      if Count_Type (N) > Queue.Data.Length then
-         raise Parameter_Error;
-      end if;
-
-      for K in 2 .. N loop
-         Next (I);
-      end loop;
-
-      return (Element => Element_Lists.Variable_Reference (Queue.Data, 
I).Element, Dummy => 1);
-   end Variable_Peek;
-
-   procedure Add (Queue : in out Pkg.Queue; Item : in Element_Type)
-   is begin
-      Queue.Data.Append (Item);
-   end Add;
-
-   procedure Add_To_Head (Queue : in out Pkg.Queue; Item : in Element_Type)
-   is begin
-      Queue.Data.Prepend (Item);
-   end Add_To_Head;
-
-end SAL.Gen_Unbounded_Definite_Queues;
diff --git a/packages/wisi/sal-gen_unbounded_definite_queues.ads 
b/packages/wisi/sal-gen_unbounded_definite_queues.ads
deleted file mode 100644
index 237800d..0000000
--- a/packages/wisi/sal-gen_unbounded_definite_queues.ads
+++ /dev/null
@@ -1,110 +0,0 @@
---  Abstract:
---
---  An unbounded queue of definite non-limited elements.
---
---  Copyright (C) 2017 - 2019 Free Software Foundation, Inc.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
---
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-with SAL.Gen_Definite_Doubly_Linked_Lists;
-generic
-   type Element_Type is private;
-package SAL.Gen_Unbounded_Definite_Queues is
-
-   package Pkg renames SAL.Gen_Unbounded_Definite_Queues;
-
-   type Queue is tagged private;
-
-   Empty_Queue : constant Queue;
-
-   procedure Clear (Queue : in out Pkg.Queue);
-   --  Empty Queue.
-
-   function Count (Queue : in Pkg.Queue) return Base_Peek_Type;
-   --  Return count of items in the Queue
-
-   function Length (Queue : in Pkg.Queue) return Base_Peek_Type renames Count;
-
-   function Is_Empty (Queue : in Pkg.Queue) return Boolean;
-   --  Return true if no items are in Queue.
-
-   function Is_Full (Queue : in Pkg.Queue) return Boolean is (False);
-   --  Return true if Queue is full.
-
-   function Remove (Queue : in out Pkg.Queue) return Element_Type;
-   --  Remove head/front item from Queue, return it.
-   --
-   --  Raise Container_Empty if Is_Empty.
-
-   function Get (Queue : in out Pkg.Queue) return Element_Type renames Remove;
-
-   procedure Drop (Queue : in out Pkg.Queue);
-   --  Remove head/front item from Queue, discard it.
-   --
-   --  Raise Container_Empty if Is_Empty.
-
-   type Constant_Reference_Type (Element : not null access constant 
Element_Type) is private
-   with
-      Implicit_Dereference => Element;
-
-   function Peek (Queue : in Pkg.Queue; N : Peek_Type := 1) return 
Constant_Reference_Type;
-   pragma Inline (Peek);
-   --  Return a constant reference to a queue item. N = 1 is the queue
-   --  head.
-   --
-   --  Raise Parameter_Error if N > Count
-
-   type Variable_Reference_Type (Element : not null access Element_Type) is 
private
-   with Implicit_Dereference => Element;
-
-   function Variable_Peek (Queue : in out Pkg.Queue; N : Peek_Type := 1) 
return Variable_Reference_Type;
-   pragma Inline (Variable_Peek);
-   --  Return a variable reference to a queue item. N = 1 is the queue
-   --  head.
-   --
-   --  Raises Parameter_Error if N > Count
-
-   procedure Add (Queue : in out Pkg.Queue; Item : in Element_Type);
-   --  Add Element to the tail/back of Queue.
-
-   procedure Put (Queue : in out Pkg.Queue; Item : in Element_Type) renames 
Add;
-
-   procedure Add_To_Head (Queue : in out Pkg.Queue; Item : in Element_Type);
-   --  Add Element to the head/front of Queue.
-
-private
-
-   package Element_Lists is new SAL.Gen_Definite_Doubly_Linked_Lists 
(Element_Type);
-
-   --  We don't provide cursors or write access to queue elements, so we
-   --  don't need any tampering checks.
-
-   type Queue is tagged record
-      Data : Element_Lists.List;
-      --  Add at Tail/Back = Last, remove at Head/Front = First.
-   end record;
-
-   type Constant_Reference_Type (Element : not null access constant 
Element_Type) is
-   record
-      Dummy : Integer := raise Program_Error with "uninitialized reference";
-   end record;
-
-   type Variable_Reference_Type (Element : not null access Element_Type) is
-   record
-      Dummy : Integer := raise Program_Error with "uninitialized reference";
-   end record;
-
-   Empty_Queue : constant Queue := (Data => Element_Lists.Empty_List);
-
-end SAL.Gen_Unbounded_Definite_Queues;
diff --git a/packages/wisi/sal-gen_unbounded_definite_red_black_trees.adb 
b/packages/wisi/sal-gen_unbounded_definite_red_black_trees.adb
deleted file mode 100644
index 0cbd6dd..0000000
--- a/packages/wisi/sal-gen_unbounded_definite_red_black_trees.adb
+++ /dev/null
@@ -1,870 +0,0 @@
---  Abstract :
---
---  Generic unbounded red-black tree with definite elements.
---
---  Copyright (C) 2017 - 2020 Free Software Foundation, Inc.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-package body SAL.Gen_Unbounded_Definite_Red_Black_Trees is
-
-   --  Local declarations (alphabetical order)
-
-   function Count_Tree (Item : in Node_Access; Nil : in Node_Access) return 
Ada.Containers.Count_Type
-   with Pre => Nil /= null;
-
-   procedure Delete_Fixup (T : in out Tree; X : in out Node_Access);
-
-   function Find (Root : in Node_Access; Key : in Key_Type; Nil : in 
Node_Access) return Node_Access
-   with Pre => Nil /= null;
-
-   procedure Left_Rotate (Tree : in out Pkg.Tree; X : in Node_Access)
-   with Pre => X /= null;
-
-   procedure Right_Rotate (Tree : in out Pkg.Tree; X : in Node_Access)
-   with Pre => X /= null;
-
-   procedure Transplant (T : in out Pkg.Tree; U, V : in Node_Access)
-   with Pre => U /= null and T.Root /= null;
-
-   ----------
-   --  local bodies (alphabetical order)
-
-   function Count_Tree (Item : in Node_Access; Nil : in Node_Access) return 
Ada.Containers.Count_Type
-   is
-      use all type Ada.Containers.Count_Type;
-      Result : Ada.Containers.Count_Type := 0;
-   begin
-      if Item.Left /= Nil then
-         Result := Result + Count_Tree (Item.Left, Nil);
-      end if;
-
-      if Item.Right /= Nil then
-         Result := Result + Count_Tree (Item.Right, Nil);
-      end if;
-
-      return Result + 1;
-   end Count_Tree;
-
-   procedure Delete_Fixup (T : in out Tree; X : in out Node_Access)
-   is
-      W : Node_Access;
-   begin
-      --  [1] 13.3 RB-Delete-Fixup
-      --  X is either "doubly black" or "red and black"
-      --  X.Parent is set, even if X = Nil.
-      --  In all cases, Nil.Left = null.Right = null.
-
-      while X /= T.Root and X.Color = Black loop
-         if X = X.Parent.Left then
-            W := X.Parent.Right;
-            if W.Color = Red then
-               W.Color        := Black;
-               X.Parent.Color := Red;
-               Left_Rotate (T, X.Parent);
-               W              := X.Parent.Right;
-            end if;
-
-            if W.Left.Color = Black and W.Right.Color = Black then
-               W.Color := Red;
-               X := X.Parent;
-            else
-               if W.Right.Color = Black then
-                  W.Left.Color := Black;
-                  W.Color      := Red;
-                  Right_Rotate (T, W);
-                  W            := X.Parent.Right;
-               end if;
-               W.Color        := X.Parent.Color;
-               X.Parent.Color := Black;
-               W.Right.Color  := Black;
-               Left_Rotate (T, X.Parent);
-               X              := T.Root;
-            end if;
-         else
-            W := X.Parent.Left;
-            if W.Color = Red then
-               W.Color        := Black;
-               X.Parent.Color := Red;
-               Right_Rotate (T, X.Parent);
-               W              := X.Parent.Left;
-            end if;
-
-            if W.Right.Color = Black and W.Left.Color = Black then
-               W.Color := Red;
-               X       := X.Parent;
-            else
-               if W.Left.Color = Black then
-                  W.Right.Color := Black;
-                  W.Color       := Red;
-                  Left_Rotate (T, W);
-                  W             := X.Parent.Left;
-               end if;
-               W.Color        := X.Parent.Color;
-               X.Parent.Color := Black;
-               W.Left.Color   := Black;
-               Right_Rotate (T, X.Parent);
-               X              := T.Root;
-            end if;
-         end if;
-      end loop;
-      X.Color := Black;
-   end Delete_Fixup;
-
-   function Find (Root : in Node_Access; Key : in Key_Type; Nil : in 
Node_Access) return Node_Access
-   is
-      Node : Node_Access := Root;
-   begin
-      while Node /= Nil loop
-         case Key_Compare (Key, Pkg.Key (Node.Element)) is
-         when Equal =>
-            return Node;
-         when Less =>
-            Node := Node.Left;
-         when Greater =>
-            Node := Node.Right;
-         end case;
-      end loop;
-      return null;
-   end Find;
-
-   procedure Free_Tree (Item : in out Node_Access; Nil : in Node_Access)
-   is begin
-      if Item = Nil or Item = null then
-         raise Programmer_Error;
-      end if;
-
-      if Item.Left /= Nil then
-         Free_Tree (Item.Left, Nil);
-      end if;
-
-      if Item.Right /= Nil then
-         Free_Tree (Item.Right, Nil);
-      end if;
-
-      Free (Item);
-   end Free_Tree;
-
-   procedure Insert_Fixup (Tree : in out Pkg.Tree; Z : in out Node_Access)
-   is
-      --  [1] 13.3 RB-Insert-Fixup (T, z)
-      Nil : Node_Access renames Tree.Nil;
-      Y   : Node_Access;
-   begin
-      while Z.Parent /= Nil and then Z.Parent.Color = Red loop
-         if Z.Parent = Z.Parent.Parent.Left then
-            Y := Z.Parent.Parent.Right;
-            if Y /= Nil and then Y.Color = Red then
-               Z.Parent.Color        := Black;
-               Y.Color               := Black;
-               Z.Parent.Parent.Color := Red;
-               Z                     := Z.Parent.Parent;
-            else
-               if Z = Z.Parent.Right then
-                  Z := Z.Parent;
-                  Left_Rotate (Tree, Z);
-               end if;
-               Z.Parent.Color        := Black;
-               Z.Parent.Parent.Color := Red;
-               Right_Rotate (Tree, Z.Parent.Parent);
-            end if;
-         else
-            Y := Z.Parent.Parent.Left;
-            if Y /= Nil and then Y.Color = Red then
-               Z.Parent.Color        := Black;
-               Y.Color               := Black;
-               Z.Parent.Parent.Color := Red;
-               Z                     := Z.Parent.Parent;
-            else
-               if Z = Z.Parent.Left then
-                  Z := Z.Parent;
-                  Right_Rotate (Tree, Z);
-               end if;
-               Z.Parent.Color        := Black;
-               Z.Parent.Parent.Color := Red;
-               Left_Rotate (Tree, Z.Parent.Parent);
-            end if;
-         end if;
-      end loop;
-      Tree.Root.Color := Black;
-   end Insert_Fixup;
-
-   procedure Left_Rotate (Tree : in out Pkg.Tree; X : in Node_Access)
-   is
-      --  [1] 13.2 Left-Rotate (T, x)
-      Nil : Node_Access renames Tree.Nil;
-      Y   : constant Node_Access := X.Right;
-   begin
-      X.Right := Y.Left;
-      if Y.Left /= Nil then
-         Y.Left.Parent := X;
-      end if;
-      Y.Parent := X.Parent;
-      if X.Parent = Nil then
-         Tree.Root := Y;
-      elsif X = X.Parent.Left then
-         X.Parent.Left := Y;
-      else
-         X.Parent.Right := Y;
-      end if;
-      Y.Left   := X;
-      X.Parent := Y;
-   end Left_Rotate;
-
-   function Minimum (Node : in Node_Access; Nil : in Node_Access) return 
Node_Access
-   is begin
-      return Result : Node_Access := Node
-      do
-         while Result.Left /= Nil loop
-            Result := Result.Left;
-         end loop;
-      end return;
-   end Minimum;
-
-   procedure Right_Rotate (Tree : in out Pkg.Tree; X : in Node_Access)
-   is
-      --  [1] 13.2 Right-Rotate (T, x)
-      Nil : Node_Access renames Tree.Nil;
-      Y   : constant Node_Access := X.Left;
-   begin
-      X.Left := Y.Right;
-      if Y.Right /= Nil then
-         Y.Right.Parent := X;
-      end if;
-      Y.Parent := X.Parent;
-      if X.Parent = Nil then
-         Tree.Root := Y;
-      elsif X = X.Parent.Right then
-         X.Parent.Right := Y;
-      else
-         X.Parent.Left := Y;
-      end if;
-      Y.Right  := X;
-      X.Parent := Y;
-   end Right_Rotate;
-
-   procedure Transplant (T : in out Pkg.Tree; U, V : in Node_Access)
-   is
-      Nil : Node_Access renames T.Nil;
-   begin
-      --  [1] 13.4 RB-Transplant, 12.3 Transplant
-
-      if U.Parent = Nil then
-         T.Root := V;
-      elsif U = U.Parent.Left then
-         U.Parent.Left := V;
-      else
-         U.Parent.Right := V;
-      end if;
-      V.Parent := U.Parent;
-   end Transplant;
-
-   ----------
-   --  Public subprograms, spec order
-
-   overriding procedure Finalize (Object : in out Tree)
-   is begin
-      if Object.Root /= null then
-         if Object.Root = Object.Nil then
-            Free (Object.Nil);
-            Object.Root := null;
-         else
-            Free_Tree (Object.Root, Object.Nil);
-            Free (Object.Nil);
-         end if;
-      end if;
-   end Finalize;
-
-   overriding procedure Initialize (Object : in out Tree)
-   is begin
-      Object.Nil       := new Node;
-      Object.Nil.Color := Black;
-      Object.Root      := Object.Nil;
-   end Initialize;
-
-   function Has_Element (Cursor : in Pkg.Cursor) return Boolean
-   is begin
-      return Cursor.Node /= null;
-   end Has_Element;
-
-   function Constant_Reference
-     (Container : aliased in Tree;
-      Position  :         in Cursor)
-     return Constant_Reference_Type
-   is
-      pragma Unreferenced (Container);
-   begin
-      return (Element => Position.Node.all.Element'Access, Dummy => 1);
-   end Constant_Reference;
-
-   function Constant_Reference
-     (Container : aliased in Tree;
-      Key       :         in Key_Type)
-     return Constant_Reference_Type
-   is
-      Node : constant Node_Access := Find (Container.Root, Key, Container.Nil);
-   begin
-      if Node = null then
-         raise Not_Found;
-      else
-         --  WORKAROUND: GNAT Community 2019 requires .all here, GNAT Pro 21.0w
-         --  20200426 requires it _not_ be here. The code is technically legal
-         --  either way, so both compilers have a bug. Keeping .all for now;
-         --  just delete it if you are using 21.0w. Hopefully 21 will fix the
-         --  bug. AdaCore ticket T503-001 on Eurocontrol support contract.
-         return (Element => Node.all.Element'Access, Dummy => 1);
-      end if;
-   end Constant_Reference;
-
-   function Variable_Reference
-     (Container : aliased in Tree;
-      Position  :         in Cursor)
-     return Variable_Reference_Type
-   is
-      pragma Unreferenced (Container);
-   begin
-      --  WORKAROUND: see note in Constant_Reference
-      return (Element => Position.Node.all.Element'Access, Dummy => 1);
-   end Variable_Reference;
-
-   function Variable_Reference
-     (Container : aliased in Tree;
-      Key       :         in Key_Type)
-     return Variable_Reference_Type
-   is
-      Node : constant Node_Access := Find (Container.Root, Key, Container.Nil);
-   begin
-      if Node = null then
-         raise Not_Found;
-      else
-         --  WORKAROUND: see note in Constant_Reference
-         return (Element => Node.all.Element'Access, Dummy => 1);
-      end if;
-   end Variable_Reference;
-
-   function Iterate (Tree : in Pkg.Tree'Class) return Iterator
-   is begin
-      return (Tree.Root, Tree.Nil);
-   end Iterate;
-
-   overriding function First (Iterator : in Pkg.Iterator) return Cursor
-   is
-      Nil  : Node_Access renames Iterator.Nil;
-      Node : Node_Access := Iterator.Root;
-   begin
-      if Node = Nil then
-         return
-           (Node       => null,
-            Direction  => Unknown,
-            Left_Done  => True,
-            Right_Done => True);
-      else
-         loop
-            exit when Node.Left = Nil;
-            Node := Node.Left;
-         end loop;
-
-         return
-           (Node       => Node,
-            Direction  => Ascending,
-            Left_Done  => True,
-            Right_Done => False);
-      end if;
-
-   end First;
-
-   overriding function Next (Iterator : in Pkg.Iterator; Position : in Cursor) 
return Cursor
-   is
-      Nil : Node_Access renames Iterator.Nil;
-   begin
-      if Position.Direction /= Ascending then
-         raise Programmer_Error;
-      end if;
-
-      if Position.Node = null then
-         return
-           (Node       => null,
-            Direction  => Unknown,
-            Left_Done  => True,
-            Right_Done => True);
-
-      elsif Position.Left_Done or Position.Node.Left = Nil then
-         if Position.Right_Done or Position.Node.Right = Nil then
-            if Position.Node.Parent = Nil then
-               return
-                 (Node       => null,
-                  Direction  => Unknown,
-                  Left_Done  => True,
-                  Right_Done => True);
-            else
-               declare
-                  Node : constant Node_Access := Position.Node.Parent;
-                  Temp : constant Cursor      :=
-                    (Node       => Node,
-                     Direction  => Ascending,
-                     Left_Done  => Node.Right = Position.Node or Node.Left = 
Position.Node,
-                     Right_Done => Node.Right = Position.Node);
-               begin
-                  if Temp.Right_Done then
-                     return Next (Iterator, Temp);
-                  else
-                     return Temp;
-                  end if;
-               end;
-            end if;
-         else
-            declare
-               Node : constant Node_Access := Position.Node.Right;
-               Temp : constant Cursor      :=
-                 (Node       => Node,
-                  Direction  => Ascending,
-                  Left_Done  => Node.Left = Nil,
-                  Right_Done => False);
-            begin
-               if Temp.Left_Done then
-                  return Temp;
-               else
-                  return Next (Iterator, Temp);
-               end if;
-            end;
-         end if;
-      else
-         declare
-            Node : constant Node_Access := Position.Node.Left;
-            Temp : constant Cursor      :=
-              (Node       => Node,
-               Direction  => Ascending,
-               Left_Done  => Node.Left = Nil,
-               Right_Done => False);
-         begin
-            if Temp.Left_Done then
-               return Temp;
-            else
-               return Next (Iterator, Temp);
-            end if;
-         end;
-      end if;
-   end Next;
-
-   overriding function Last (Iterator : in Pkg.Iterator) return Cursor
-   is
-      Nil  : Node_Access renames Iterator.Nil;
-      Node : Node_Access := Iterator.Root;
-   begin
-      if Node = Nil then
-         return
-           (Node       => null,
-            Direction  => Unknown,
-            Left_Done  => True,
-            Right_Done => True);
-      else
-         loop
-            exit when Node.Right = Nil;
-            Node := Node.Right;
-         end loop;
-         return
-           (Node       => Node,
-            Direction  => Descending,
-            Right_Done => True,
-            Left_Done  => False);
-      end if;
-   end Last;
-
-   overriding function Previous (Iterator : in Pkg.Iterator; Position : in 
Cursor) return Cursor
-   is
-      Nil : Node_Access renames Iterator.Nil;
-   begin
-      if Position.Direction /= Descending then
-         raise Programmer_Error;
-      end if;
-
-      if Position.Node = null then
-         return
-           (Node       => null,
-            Direction  => Unknown,
-            Left_Done  => True,
-            Right_Done => True);
-
-      elsif Position.Right_Done or Position.Node.Right = Nil then
-         if Position.Left_Done or Position.Node.Left = Nil then
-            if Position.Node.Parent = Nil then
-               return
-                 (Node       => null,
-                  Direction  => Unknown,
-                  Left_Done  => True,
-                  Right_Done => True);
-            else
-               declare
-                  Node : constant Node_Access := Position.Node.Parent;
-                  Temp : constant Cursor      :=
-                    (Node       => Node,
-                     Direction  => Descending,
-                     Right_Done => Node.Left = Position.Node or Node.Right = 
Position.Node,
-                     Left_Done  => Node.Left = Position.Node);
-               begin
-                  if Temp.Left_Done then
-                     return Previous (Iterator, Temp);
-                  else
-                     return Temp;
-                  end if;
-               end;
-            end if;
-         else
-            declare
-               Node : constant Node_Access := Position.Node.Left;
-               Temp : constant Cursor      :=
-                 (Node       => Node,
-                  Direction  => Descending,
-                  Right_Done => Node.Right = Nil,
-                  Left_Done  => False);
-            begin
-               if Temp.Right_Done then
-                  return Temp;
-               else
-                  return Previous (Iterator, Temp);
-               end if;
-            end;
-         end if;
-      else
-         declare
-            Node : constant Node_Access := Position.Node.Right;
-            Temp : constant Cursor      :=
-              (Node       => Node,
-               Direction  => Descending,
-               Right_Done => Node.Right = Nil,
-               Left_Done  => False);
-         begin
-            if Temp.Right_Done then
-               return Temp;
-            else
-               return Previous (Iterator, Temp);
-            end if;
-         end;
-      end if;
-   end Previous;
-
-   function Previous (Iterator : in Pkg.Iterator; Key : in Key_Type) return 
Cursor
-   is
-      Nil  : Node_Access renames Iterator.Nil;
-      Node : Node_Access := Iterator.Root;
-   begin
-      while Node /= Nil loop
-         declare
-            Current_Key : Key_Type renames Pkg.Key (Node.Element);
-         begin
-            case Key_Compare (Key, Current_Key) is
-            when Equal =>
-                  return Previous (Iterator, (Node, Descending, Right_Done => 
True, Left_Done => False));
-
-            when Less =>
-               if Node.Left = Nil then
-                  return Previous (Iterator, (Node, Descending, Right_Done => 
True, Left_Done => True));
-               else
-                  Node := Node.Left;
-               end if;
-
-            when Greater =>
-               if Node.Right = Nil then
-                  return (Node, Descending, Right_Done => True, Left_Done => 
False);
-               else
-                  Node := Node.Right;
-               end if;
-            end case;
-         end;
-      end loop;
-
-      return
-        (Node       => null,
-         Direction  => Unknown,
-         Left_Done  => True,
-         Right_Done => True);
-   end Previous;
-
-   function Find
-     (Iterator  : in Pkg.Iterator;
-      Key       : in Key_Type;
-      Direction : in Direction_Type := Ascending)
-     return Cursor
-   is
-      Nil  : Node_Access renames Iterator.Nil;
-      Node : constant Node_Access := Find (Iterator.Root, Key, Nil);
-   begin
-      if Node = null then
-         return
-           (Node       => null,
-            Direction  => Unknown,
-            Left_Done  => True,
-            Right_Done => True);
-      else
-         return
-           (Node       => Node,
-            Direction  => Direction,
-            Left_Done  =>
-              (case Direction is
-               when Ascending | Unknown => True,
-               when Descending => Node.Left = Nil),
-            Right_Done =>
-              (case Direction is
-               when Ascending => Node.Right = Nil,
-               when Descending | Unknown => True));
-      end if;
-   end Find;
-
-   function Find_In_Range
-     (Iterator    : in Pkg.Iterator;
-      Direction   : in Known_Direction_Type;
-      First, Last : in Key_Type)
-     return Cursor
-   is
-      Nil       : Node_Access renames Iterator.Nil;
-      Node      : Node_Access := Iterator.Root;
-      Candidate : Node_Access := null; -- best result found so far
-   begin
-      while Node /= Nil loop
-         declare
-            Current_Key : Key_Type renames Key (Node.Element);
-         begin
-            case Direction is
-            when Ascending =>
-               case Key_Compare (First, Current_Key) is
-               when Equal =>
-                     return (Node, Ascending, Right_Done => False, Left_Done 
=> True);
-
-               when Less =>
-                  if Node.Left = Nil then
-                     case Key_Compare (Current_Key, Last) is
-                     when Less | Equal =>
-                        return (Node, Ascending, Right_Done => False, 
Left_Done => True);
-                     when Greater =>
-                        if Candidate = null then
-                           return No_Element;
-                        else
-                           return (Candidate, Ascending, Right_Done => False, 
Left_Done => True);
-                        end if;
-                     end case;
-                  else
-                     case Key_Compare (Last, Current_Key) is
-                     when Greater | Equal =>
-                        Candidate := Node;
-                     when Less =>
-                        null;
-                     end case;
-                     Node := Node.Left;
-                  end if;
-
-               when Greater =>
-                  if Node.Right = Nil then
-                     if Candidate = null then
-                        return No_Element;
-                     else
-                        return (Candidate, Ascending, Right_Done => False, 
Left_Done => True);
-                     end if;
-                  else
-                     Node := Node.Right;
-                  end if;
-               end case;
-
-            when Descending =>
-               if Last = Current_Key then
-                  return (Node, Descending, Right_Done => True, Left_Done => 
False);
-
-               else
-                  case Key_Compare (Last, Current_Key) is
-                  when Greater =>
-                     if Node.Right = Nil then
-                        case Key_Compare (Current_Key, First) is
-                        when Greater | Equal =>
-                           return (Node, Descending, Right_Done => True, 
Left_Done => False);
-                        when Less =>
-                           if Candidate = null then
-                              return No_Element;
-                           else
-                              return (Candidate, Ascending, Right_Done => 
False, Left_Done => True);
-                           end if;
-                        end case;
-                     else
-                        case Key_Compare (First, Current_Key) is
-                        when Less | Equal =>
-                           Candidate := Node;
-                        when Greater =>
-                           null;
-                        end case;
-                        Node := Node.Right;
-                     end if;
-                  when Equal | Less =>
-                     if Node.Left = Nil then
-                        if Candidate = null then
-                           return No_Element;
-                        else
-                           return (Candidate, Ascending, Right_Done => False, 
Left_Done => True);
-                        end if;
-                     else
-                        Node := Node.Left;
-                     end if;
-                  end case;
-               end if;
-            end case;
-         end;
-      end loop;
-
-      return No_Element;
-   end Find_In_Range;
-
-   function Count (Tree : in Pkg.Tree) return Ada.Containers.Count_Type
-   is begin
-      if Tree.Root = Tree.Nil then
-         return 0;
-      else
-         return Count_Tree (Tree.Root, Tree.Nil);
-      end if;
-   end Count;
-
-   function Present (Container : in Tree; Key : in Key_Type) return Boolean
-   is
-      Nil  : Node_Access renames Container.Nil;
-      Node : Node_Access := Container.Root;
-   begin
-      while Node /= Nil loop
-         case Key_Compare (Key, Pkg.Key (Node.Element)) is
-         when Equal =>
-            return True;
-         when Less =>
-            Node := Node.Left;
-         when Greater =>
-            Node := Node.Right;
-         end case;
-      end loop;
-      return False;
-   end Present;
-
-   function Insert (Tree : in out Pkg.Tree; Element : in Element_Type) return 
Cursor
-   is
-      --  [1] 13.3 RB-Insert (T, z)
-      Nil   : Node_Access renames Tree.Nil;
-      Z     : Node_Access       := new Node'(Element, Nil, Nil, Nil, Red);
-      Key_Z : constant Key_Type := Key (Z.Element);
-      Y     : Node_Access       := Nil;
-      X     : Node_Access       := Tree.Root;
-
-      Result      : Node_Access;
-      Compare_Z_Y : Compare_Result;
-   begin
-      Nil.Parent := null;
-      Nil.Left   := null;
-      Nil.Right  := null;
-
-      while X /= Nil loop
-         Y := X;
-         Compare_Z_Y := Key_Compare (Key_Z, Key (X.Element));
-         case Compare_Z_Y is
-         when Less =>
-            X := X.Left;
-         when Equal | Greater =>
-            X := X.Right;
-         end case;
-      end loop;
-
-      Z.Parent := Y;
-      if Y = Nil then
-         Tree.Root := Z;
-      else
-         case Compare_Z_Y is
-         when Less =>
-            Y.Left := Z;
-         when Equal | Greater =>
-            Y.Right := Z;
-         end case;
-      end if;
-
-      Result := Z;
-      if Z = Tree.Root then
-         Z.Color := Black;
-      else
-         Insert_Fixup (Tree, Z);
-      end if;
-
-      return
-        (Node       => Result,
-         Direction  => Unknown,
-         Left_Done  => True,
-         Right_Done => True);
-   end Insert;
-
-   procedure Insert (Tree : in out Pkg.Tree; Element : in Element_Type)
-   is
-      Temp : Cursor := Insert (Tree, Element);
-      pragma Unreferenced (Temp);
-   begin
-      null;
-   end Insert;
-
-   procedure Delete (Tree : in out Pkg.Tree; Position : in out Cursor)
-   is
-      Nil          : Node_Access renames Tree.Nil;
-      T            : Pkg.Tree renames Tree;
-      Z            : constant Node_Access :=
-        (if Position.Node = null then raise Parameter_Error else 
Position.Node);
-      Y            : Node_Access          := Z;
-      Y_Orig_Color : Color                := Y.Color;
-      X            : Node_Access;
-   begin
-      --  Catch logic errors in use of Nil
-      Nil.Parent := null;
-      Nil.Left   := null;
-      Nil.Right  := null;
-
-      --  [1] 13.4 RB-Delete.
-      if Z.Left = Nil then
-         X := Z.Right;
-         Transplant (T, Z, Z.Right);
-
-      elsif Z.Right = Nil then
-         X := Z.Left;
-         Transplant (T, Z, Z.Left);
-
-      else
-         Y            := Minimum (Z.Right, Nil);
-         Y_Orig_Color := Y.Color;
-         X            := Y.Right;
-         if Y.Parent = Z then
-            X.Parent := Y;
-            --  This is already true unless X = Nil, in which case delete_fixup
-            --  needs the info.
-         else
-            Transplant (T, Y, Y.Right);
-            Y.Right := Z.Right;
-
-            Y.Right.Parent := Y;
-            --  This is already true unless Y.Right = Nil, in which case
-            --  delete_fixup needs the info.
-         end if;
-
-         Transplant (T, Z, Y);
-         Y.Left := Z.Left;
-
-         Y.Left.Parent := Y;
-         --  This is already true unless Y.Left = Nil, in which case
-         --  delete_fixup needs the info.
-
-         Y.Color := Z.Color;
-      end if;
-
-      if Y_Orig_Color = Black then
-         Delete_Fixup (T, X);
-      end if;
-
-      Free (Position.Node);
-   end Delete;
-
-end SAL.Gen_Unbounded_Definite_Red_Black_Trees;
diff --git a/packages/wisi/sal-gen_unbounded_definite_red_black_trees.ads 
b/packages/wisi/sal-gen_unbounded_definite_red_black_trees.ads
deleted file mode 100644
index f886ed9..0000000
--- a/packages/wisi/sal-gen_unbounded_definite_red_black_trees.ads
+++ /dev/null
@@ -1,198 +0,0 @@
---  Abstract :
---
---  Generic unbounded red-black tree with definite elements, definite
---  or indefinite key.
---
---  References :
---
---  [1] Introduction to Algorithms, Thomas H. Cormen, Charles E.
---  Leiserson, Ronald L. Rivest, Clifford Stein.
---
---  Copyright (C) 2017 - 2020 Free Software Foundation, Inc.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-with Ada.Finalization;
-with Ada.Iterator_Interfaces;
-with Ada.Unchecked_Deallocation;
-generic
-   type Element_Type is private;
-   type Key_Type (<>) is private;
-   with function Key (Element : in Element_Type) return Key_Type is <>;
-   with function Key_Compare (Left, Right : in Key_Type) return Compare_Result 
is <>;
-package SAL.Gen_Unbounded_Definite_Red_Black_Trees is
-
-   package Pkg renames Gen_Unbounded_Definite_Red_Black_Trees;
-
-   type Tree is new Ada.Finalization.Limited_Controlled with private
-   with
-     Constant_Indexing => Constant_Reference,
-     Variable_Indexing => Variable_Reference,
-     Default_Iterator  => Iterate,
-     Iterator_Element  => Element_Type;
-
-   overriding procedure Finalize (Object : in out Tree);
-   overriding procedure Initialize (Object : in out Tree);
-
-   type Direction_Type is (Ascending, Descending, Unknown);
-   subtype Known_Direction_Type is Direction_Type range Ascending .. 
Descending;
-   --  Direction of Iterators.
-   --  If Ascending, Next may be called.
-   --  If Descending, Previous may be called.
-   --  If Unknown, neither.
-
-   type Cursor is private;
-
-   No_Element : constant Cursor;
-
-   function Has_Element (Cursor : in Pkg.Cursor) return Boolean;
-
-   type Constant_Reference_Type (Element : not null access constant 
Element_Type) is private with
-     Implicit_Dereference => Element;
-
-   function Constant_Reference
-     (Container : aliased in Tree;
-      Position  :         in Cursor)
-     return Constant_Reference_Type with
-     Inline, Pre => Has_Element (Position);
-
-   function Constant_Reference
-     (Container : aliased in Tree;
-      Key       :         in Key_Type)
-     return Constant_Reference_Type with
-     Inline;
-   --  Raises Not_Found if Key not found in Container.
-
-   type Variable_Reference_Type (Element : not null access Element_Type) is 
private with
-     Implicit_Dereference => Element;
-
-   function Variable_Reference
-     (Container : aliased in Tree;
-      Position  :         in Cursor)
-     return Variable_Reference_Type with
-     Inline, Pre => Has_Element (Position);
-
-   function Variable_Reference
-     (Container : aliased in Tree;
-      Key       :         in Key_Type)
-     return Variable_Reference_Type with
-     Inline;
-   --  Raises Not_Found if Key not found in Container.
-
-   package Iterators is new Ada.Iterator_Interfaces (Cursor, Has_Element);
-
-   type Iterator is new Iterators.Reversible_Iterator with private;
-
-   function Iterate (Tree : in Pkg.Tree'Class) return Iterator;
-
-   overriding function First (Iterator : in Pkg.Iterator) return Cursor;
-   overriding function Next (Iterator : in Pkg.Iterator; Position : in Cursor) 
return Cursor;
-   overriding function Last (Iterator : in Pkg.Iterator) return Cursor;
-   overriding function Previous (Iterator : in Pkg.Iterator; Position : in 
Cursor) return Cursor;
-
-   function Previous (Iterator : in Pkg.Iterator; Key : in Key_Type) return 
Cursor;
-   --  Initialise Iterator to descending, starting at element with
-   --  largest key < Key. Has_Element (result) is False if there is no
-   --  such element.
-
-   function Find
-     (Iterator  : in Pkg.Iterator;
-      Key       : in Key_Type;
-      Direction : in Direction_Type := Ascending)
-     return Cursor;
-   --  Has_Element is False if Key is not in Container.
-
-   function Find_In_Range
-     (Iterator    : in Pkg.Iterator;
-      Direction   : in Known_Direction_Type;
-      First, Last : in Key_Type)
-     return Cursor;
-   --  Find first element with key in range First .. Last. If Direction
-   --  is Ascending, start at First, otherwise start at Last.
-   --
-   --  Has_Element (result) is False if there is no such element.
-   --
-   --  The Iterator does not remember First, Last; the user must check
-   --  those for any element that Next or Previous returns.
-
-   function Count (Tree : in Pkg.Tree) return Ada.Containers.Count_Type;
-
-   function Present (Container : in Tree; Key : in Key_Type) return Boolean;
-
-   procedure Insert (Tree : in out Pkg.Tree; Element : in Element_Type);
-   function Insert (Tree : in out Pkg.Tree; Element : in Element_Type) return 
Cursor;
-   --  Result points to newly inserted element.
-
-   procedure Delete (Tree : in out Pkg.Tree; Position : in out Cursor);
-   --  Delete element at Position, set Position to No_Element.
-private
-
-   type Node;
-   type Node_Access is access Node;
-
-   type Color is (Red, Black);
-
-   type Node is record
-      Element : aliased Element_Type;
-      Parent  : Node_Access;
-      Left    : Node_Access;
-      Right   : Node_Access;
-      Color   : Pkg.Color;
-   end record;
-
-   procedure Free is new Ada.Unchecked_Deallocation (Node, Node_Access);
-
-   type Tree is new Ada.Finalization.Limited_Controlled with record
-      Root : Node_Access;
-      Nil  : Node_Access;
-      --  Nil is the node pointed to by all links that would otherwise be
-      --  'null'. This simplifies several algorithm (for example,
-      --  Node.Left.Color is always valid). Its parent, left, right links
-      --  are used as temp storage for some algorithms (especially Delete).
-      --  Nil.Color is Black.
-   end record;
-
-   type Cursor is record
-      Node : Node_Access := null;
-
-      Direction  : Direction_Type := Unknown;
-      --  Set in First or Last, enforced in next/prev (cannot change 
direction).
-
-      Left_Done  : Boolean := True;
-      Right_Done : Boolean := True;
-   end record;
-
-   type Constant_Reference_Type (Element : not null access constant 
Element_Type) is
-   record
-      Dummy : Integer := raise Program_Error with "uninitialized reference";
-   end record;
-
-   type Variable_Reference_Type (Element : not null access Element_Type) is
-   record
-      Dummy : Integer := raise Program_Error with "uninitialized reference";
-   end record;
-
-   No_Element : constant Cursor :=
-     (Node       => null,
-      Direction  => Unknown,
-      Left_Done  => True,
-      Right_Done => True);
-
-   type Iterator is new Iterators.Reversible_Iterator with
-   record
-      Root : Node_Access;
-      Nil  : Node_Access;
-   end record;
-
-end SAL.Gen_Unbounded_Definite_Red_Black_Trees;
diff --git a/packages/wisi/sal-gen_unbounded_definite_stacks-gen_image_aux.adb 
b/packages/wisi/sal-gen_unbounded_definite_stacks-gen_image_aux.adb
deleted file mode 100644
index c4b52a6..0000000
--- a/packages/wisi/sal-gen_unbounded_definite_stacks-gen_image_aux.adb
+++ /dev/null
@@ -1,42 +0,0 @@
---  Abstract :
---
---  See spec.
---
---  Copyright (C) 2018 Free Software Foundation, Inc.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-with Ada.Strings.Unbounded;
-function SAL.Gen_Unbounded_Definite_Stacks.Gen_Image_Aux
-  (Item  : in Stack;
-   Aux   : in Aux_Data;
-   Depth : in SAL.Base_Peek_Type := 0)
-  return String
-is
-   use Ada.Strings.Unbounded;
-   Result : Unbounded_String        := To_Unbounded_String ("(");
-   Last   : constant Base_Peek_Type :=
-     (if Depth = 0
-      then Item.Top
-      else Base_Peek_Type'Min (Depth, Item.Top));
-begin
-   for I in 1 .. Last loop
-      Result := Result & Element_Image (Item.Peek (I), Aux);
-      if I /= Last then
-         Result := Result & ", ";
-      end if;
-   end loop;
-   Result := Result & ")";
-   return To_String (Result);
-end SAL.Gen_Unbounded_Definite_Stacks.Gen_Image_Aux;
diff --git a/packages/wisi/sal-gen_unbounded_definite_stacks-gen_image_aux.ads 
b/packages/wisi/sal-gen_unbounded_definite_stacks-gen_image_aux.ads
deleted file mode 100644
index 801ffd3..0000000
--- a/packages/wisi/sal-gen_unbounded_definite_stacks-gen_image_aux.ads
+++ /dev/null
@@ -1,27 +0,0 @@
---  Abstract :
---
---  Image with auxiliary data for instantiations of parent.
---
---  Copyright (C) 2018 Free Software Foundation, Inc.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-generic
-   type Aux_Data (<>) is private;
-   with function Element_Image (Item : in Element_Type; Aux : in Aux_Data) 
return String;
-function SAL.Gen_Unbounded_Definite_Stacks.Gen_Image_Aux
-  (Item  : in Stack;
-   Aux   : in Aux_Data;
-   Depth : in SAL.Base_Peek_Type := 0)
-  return String;
diff --git a/packages/wisi/sal-gen_unbounded_definite_stacks.adb 
b/packages/wisi/sal-gen_unbounded_definite_stacks.adb
deleted file mode 100644
index 072c104..0000000
--- a/packages/wisi/sal-gen_unbounded_definite_stacks.adb
+++ /dev/null
@@ -1,219 +0,0 @@
---  Abstract:
---
---  see spec
---
---  Copyright (C) 1998, 2003, 2009, 2015, 2017 - 2020 Free Software 
Foundation, Inc.
---
---  SAL is free software; you can redistribute it and/or modify it
---  under terms of the GNU General Public License as published by the
---  Free Software Foundation; either version 3, or (at your option)
---  any later version. SAL 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 distributed
---  with SAL; see file COPYING. If not, write to the Free Software
---  Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
---  USA.
---
---  As a special exception, if other files instantiate generics from
---  SAL, or you link SAL object files with other files to produce an
---  executable, that does not by itself cause the resulting executable
---  to be covered by the GNU General Public License. This exception
---  does not however invalidate any other reasons why the executable
---  file might be covered by the GNU Public License.
-
-pragma License (Modified_GPL);
-
-package body SAL.Gen_Unbounded_Definite_Stacks is
-
-   ----------
-   --  local subprogram bodies
-
-   procedure Grow (Stack : in out Sguds.Stack; Desired_Size : in 
Base_Peek_Type)
-   is
-      New_Data : constant Element_Array_Access := new Element_Array (1 .. 
Desired_Size);
-   begin
-      New_Data (1 .. Stack.Top) := Stack.Data (1 .. Stack.Top);
-      Free (Stack.Data);
-      Stack.Data := New_Data;
-   end Grow;
-
-   ----------
-   --  Spec visible subprograms
-   overriding procedure Finalize (Stack : in out Sguds.Stack)
-   is begin
-      if Stack.Data /= null then
-         Free (Stack.Data);
-         Stack.Top := Invalid_Peek_Index;
-      end if;
-   end Finalize;
-
-   overriding procedure Adjust (Stack : in out Sguds.Stack)
-   is begin
-      if Stack.Data /= null then
-         Stack.Data := new Element_Array'(Stack.Data.all);
-      end if;
-   end Adjust;
-
-   overriding
-   function "=" (Left, Right : in Sguds.Stack) return Boolean
-   is begin
-      if Left.Data = null then
-         return Right.Data = null;
-      elsif Left.Top /= Right.Top then
-         return False;
-      else
-         --  Assume stacks differ near top.
-         for I in reverse 1 .. Left.Top loop
-            if Left.Data (I) /= Right.Data (I) then
-               return False;
-            end if;
-         end loop;
-         return True;
-      end if;
-   end "=";
-
-   procedure Clear (Stack : in out Sguds.Stack)
-   is begin
-      --  We don't change the reserved capacity, on the assumption the
-      --  stack will be used again.
-      Stack.Top := 0;
-   end Clear;
-
-   function Depth (Stack : in Sguds.Stack) return Base_Peek_Type
-   is begin
-      return Stack.Top;
-   end Depth;
-
-   function Is_Empty (Stack : in Sguds.Stack) return Boolean
-   is begin
-      return Stack.Top = 0;
-   end Is_Empty;
-
-   function Peek
-     (Stack : in Sguds.Stack;
-      Index : in Peek_Type := 1)
-     return Element_Type
-   is begin
-      return Stack.Data (Stack.Top - Index + 1);
-   end Peek;
-
-   procedure Pop (Stack : in out Sguds.Stack; Count : in Base_Peek_Type := 1)
-   is begin
-      if Stack.Top < Count then
-         raise Container_Empty;
-      else
-         Stack.Top := Stack.Top - Count;
-      end if;
-   end Pop;
-
-   function Pop (Stack : in out Sguds.Stack) return Element_Type
-   is begin
-      if Stack.Top = 0 then
-         raise Container_Empty;
-      else
-         return Result : constant Element_Type := Stack.Peek (1)
-         do
-            Stack.Top := Stack.Top - 1;
-         end return;
-      end if;
-   end Pop;
-
-   procedure Push (Stack : in out Sguds.Stack; Item : in Element_Type)
-   is begin
-      if Stack.Data = null then
-         --  Adding a generic parameter for a reasonably large default initial
-         --  size here makes Wisitoken McKenzie recover slightly slower,
-         --  presumably due to increased cache thrashing.
-         Stack.Data := new Element_Array (1 .. 2);
-      elsif Stack.Top = Stack.Data'Last then
-         Grow (Stack, Desired_Size => 2 * Stack.Data'Last);
-      end if;
-      Stack.Top := Stack.Top + 1;
-      Stack.Data (Stack.Top) := Item;
-   end Push;
-
-   function Top (Stack : in Sguds.Stack) return Element_Type
-   is begin
-      if Stack.Top < 1 then
-         raise SAL.Container_Empty;
-      else
-         return Peek (Stack, 1);
-      end if;
-   end Top;
-
-   procedure Set_Depth
-     (Stack : in out Sguds.Stack;
-      Depth : in     Peek_Type)
-   is begin
-      if Stack.Data = null then
-         Stack.Data := new Element_Array (1 .. 2 * Depth);
-      elsif Depth > Stack.Data'Last then
-         Grow (Stack, Desired_Size => 2 * Depth);
-      end if;
-   end Set_Depth;
-
-   procedure Set
-     (Stack   : in out Sguds.Stack;
-      Index   : in     Peek_Type;
-      Depth   : in     Peek_Type;
-      Element : in     Element_Type)
-   is begin
-      --  Same Position algorithm as in Peek
-      Stack.Top := Depth;
-      Stack.Data (Depth - Index + 1) := Element;
-   end Set;
-
-   function Constant_Reference
-     (Container : aliased in Stack'Class;
-      Position  :         in Peek_Type)
-     return Constant_Reference_Type
-   is begin
-      return
-        (Element => Container.Data (Container.Top - Position + 1)'Access,
-         Dummy => 1);
-   end Constant_Reference;
-
-   function Constant_Reference
-     (Container : aliased in Stack'Class;
-      Position  :         in Cursor)
-     return Constant_Reference_Type
-   is begin
-      return
-        (Element => Container.Data (Container.Top - Position.Ptr + 1)'Access,
-         Dummy => 1);
-   end Constant_Reference;
-
-   function Has_Element (Position : in Cursor) return Boolean
-   is begin
-      return Position.Container.Depth >= Position.Ptr;
-   end Has_Element;
-
-   type Iterator (Container : not null access constant Stack) is new 
Iterator_Interfaces.Forward_Iterator with
-   null record;
-
-   overriding function First (Object : Iterator) return Cursor;
-
-   overriding function Next
-     (Object   : Iterator;
-      Position : Cursor) return Cursor;
-
-   function Iterate (Container : aliased in Stack) return 
Iterator_Interfaces.Forward_Iterator'Class
-   is begin
-      return Iterator'(Container => Container'Access);
-   end Iterate;
-
-   overriding function First (Object : Iterator) return Cursor
-   is begin
-      return (Object.Container, 1);
-   end First;
-
-   overriding function Next (Object : in Iterator; Position : in Cursor) 
return Cursor
-   is
-      pragma Unreferenced (Object);
-   begin
-      return (Position.Container, Position.Ptr + 1);
-   end Next;
-
-end SAL.Gen_Unbounded_Definite_Stacks;
diff --git a/packages/wisi/sal-gen_unbounded_definite_stacks.ads 
b/packages/wisi/sal-gen_unbounded_definite_stacks.ads
deleted file mode 100644
index 3d1e1e7..0000000
--- a/packages/wisi/sal-gen_unbounded_definite_stacks.ads
+++ /dev/null
@@ -1,158 +0,0 @@
---  Abstract:
---
---  Stack implementation.
---
---  Copyright (C) 1998-2000, 2002-2003, 2009, 2015, 2017 - 2020 Free Software 
Foundation, Inc.
---
---  SAL is free software; you can redistribute it and/or modify it
---  under terms of the GNU General Public License as published by the
---  Free Software Foundation; either version 3, or (at your option)
---  any later version. SAL 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 distributed
---  with SAL; see file COPYING. If not, write to the Free Software
---  Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
---  USA.
---
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-with Ada.Finalization;
-with Ada.Iterator_Interfaces;
-with Ada.Unchecked_Deallocation;
-generic
-   type Element_Type is private;
-package SAL.Gen_Unbounded_Definite_Stacks is
-
-   package Sguds renames SAL.Gen_Unbounded_Definite_Stacks;
-
-   type Stack is new Ada.Finalization.Controlled with private
-   with
-     Constant_Indexing => Constant_Reference,
-     Default_Iterator  => Iterate,
-     Iterator_Element  => Element_Type;
-
-   Empty_Stack : constant Stack;
-
-   overriding procedure Finalize (Stack : in out Sguds.Stack);
-   overriding procedure Adjust (Stack : in out Sguds.Stack);
-
-   overriding function "=" (Left, Right : in Sguds.Stack) return Boolean;
-
-   procedure Clear (Stack : in out Sguds.Stack);
-   --  Empty Stack of all items.
-
-   function Depth (Stack : in Sguds.Stack) return Base_Peek_Type;
-   --  Returns current count of items in the Stack
-
-   function Is_Empty (Stack : in Sguds.Stack) return Boolean;
-   --  Returns true iff no items are in Stack.
-
-   function Peek
-     (Stack : in Sguds.Stack;
-      Index : in Peek_Type := 1)
-     return Element_Type with Inline;
-   --  Return the Index'th item from the top of Stack; the Item is _not_ 
removed.
-   --  Top item has index 1.
-   --
-   --  Raises Constraint_Error if Index > Depth.
-   --
-   --  See also Constant_Ref, implicit indexing
-
-   procedure Pop (Stack : in out Sguds.Stack; Count : in Base_Peek_Type := 1);
-   --  Remove Count Items from the top of Stack, discard them.
-   --
-   --  Raises Container_Empty if there are fewer than Count items on
-   --  Stack.
-
-   function Pop (Stack : in out Sguds.Stack) return Element_Type;
-   --  Remove Item from the top of Stack, and return it.
-   --
-   --  Raises Container_Empty if Is_Empty.
-
-   procedure Push (Stack : in out Sguds.Stack; Item : in Element_Type);
-   --  Add Item to the top of Stack.
-   --
-   --  May raise Container_Full.
-
-   function Top (Stack : in Sguds.Stack) return Element_Type;
-   --  Return the item at the top of Stack; the Item is _not_ removed.
-   --  Same as Peek (Stack, 1).
-   --
-   --  Raises Container_Empty if Is_Empty.
-
-   procedure Set_Depth
-     (Stack : in out Sguds.Stack;
-      Depth : in     Peek_Type);
-   --  Empty Stack, set its Depth to Depth. Must be followed by Set
-   --  for each element.
-   --
-   --  Useful when creating a stack from pre-existing data.
-
-   procedure Set
-     (Stack   : in out Sguds.Stack;
-      Index   : in     Peek_Type;
-      Depth   : in     Peek_Type;
-      Element : in     Element_Type);
-   --  Set a Stack element. Index is the same as Peek Index; Depth is
-   --  used to compute the index in the underlying array.
-   --
-   --  Stack must have been initialized by Set_Depth.
-   --
-   --  Useful when creating a stack from pre-existing data.
-
-   type Constant_Reference_Type (Element : not null access constant 
Element_Type) is private with
-     Implicit_Dereference => Element;
-
-   function Constant_Reference
-     (Container : aliased in Stack'Class;
-      Position  :         in Peek_Type)
-     return Constant_Reference_Type
-   with Inline, Pre => Position in 1 .. Container.Depth;
-
-   type Cursor (<>) is private;
-
-   function Constant_Reference
-     (Container : aliased in Stack'Class;
-      Position  :         in Cursor)
-     return Constant_Reference_Type
-   with Inline, Pre => Has_Element (Position);
-
-   function Has_Element (Position : in Cursor) return Boolean;
-
-   package Iterator_Interfaces is new Ada.Iterator_Interfaces (Cursor, 
Has_Element);
-
-   function Iterate (Container : aliased in Stack) return 
Iterator_Interfaces.Forward_Iterator'Class;
-
-private
-
-   type Element_Array is array (Peek_Type range <>) of aliased Element_Type;
-   type Element_Array_Access is access Element_Array;
-   procedure Free is new Ada.Unchecked_Deallocation (Element_Array, 
Element_Array_Access);
-
-   type Stack is new Ada.Finalization.Controlled with record
-      Top  : Base_Peek_Type := Invalid_Peek_Index; -- empty
-      Data : Element_Array_Access;
-
-      --  Top of stack is at Data (Top).
-      --  Data (1 .. Top) has been set at some point.
-   end record;
-
-   type Constant_Reference_Type (Element : not null access constant 
Element_Type) is
-   record
-      Dummy : Integer := raise Program_Error with "uninitialized reference";
-   end record;
-
-   Empty_Stack : constant Stack := (Ada.Finalization.Controlled with 
Invalid_Peek_Index, null);
-
-   type Cursor (Container : not null access constant Stack) is
-   record
-      Ptr : Peek_Type;
-   end record;
-
-end SAL.Gen_Unbounded_Definite_Stacks;
diff --git 
a/packages/wisi/sal-gen_unbounded_definite_vectors-gen_comparable.adb 
b/packages/wisi/sal-gen_unbounded_definite_vectors-gen_comparable.adb
deleted file mode 100644
index 16c1fe8..0000000
--- a/packages/wisi/sal-gen_unbounded_definite_vectors-gen_comparable.adb
+++ /dev/null
@@ -1,73 +0,0 @@
---  Abstract :
---
---  See spec.
---
---  Copyright (C) 2018 Free Software Foundation, Inc.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-package body SAL.Gen_Unbounded_Definite_Vectors.Gen_Comparable is
-
-   function Compare (Left, Right : in Vector) return Compare_Result
-   is
-      use all type Ada.Containers.Count_Type;
-   begin
-      if Left.Length = 0 then
-         if Right.Length = 0 then
-            return Equal;
-         else
-            --  null is less than non-null
-            return Less;
-         end if;
-
-      elsif Right.Length = 0 then
-         return Greater;
-
-      else
-         declare
-            I : Base_Peek_Type := To_Peek_Type (Left.First);
-            J : Base_Peek_Type := To_Peek_Type (Right.First);
-
-            Left_Last  : constant Base_Peek_Type := To_Peek_Type (Left.Last);
-            Right_Last : constant Base_Peek_Type := To_Peek_Type (Right.Last);
-         begin
-            loop
-               exit when I > Left_Last or J > Right_Last;
-
-               case Element_Compare (Left.Elements (I), Right.Elements (J)) is
-               when Less =>
-                  return Less;
-               when Equal =>
-                  I := I + 1;
-                  J := J + 1;
-               when Greater =>
-                  return Greater;
-               end case;
-            end loop;
-            if I > Left_Last then
-               if J > Right_Last then
-                  return Equal;
-               else
-                  --  right is longer
-                  return Less;
-               end if;
-            else
-               --  left is longer
-               return Greater;
-            end if;
-         end;
-      end if;
-   end Compare;
-
-end SAL.Gen_Unbounded_Definite_Vectors.Gen_Comparable;
diff --git 
a/packages/wisi/sal-gen_unbounded_definite_vectors-gen_comparable.ads 
b/packages/wisi/sal-gen_unbounded_definite_vectors-gen_comparable.ads
deleted file mode 100644
index 56d84c0..0000000
--- a/packages/wisi/sal-gen_unbounded_definite_vectors-gen_comparable.ads
+++ /dev/null
@@ -1,30 +0,0 @@
---  Abstract :
---
---  Add "<" to parent
---
---  Copyright (C) 2018 Free Software Foundation, Inc.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-generic
-   with function Element_Compare (Left, Right : in Element_Type) return 
Compare_Result;
-package SAL.Gen_Unbounded_Definite_Vectors.Gen_Comparable is
-
-   type Vector is new SAL.Gen_Unbounded_Definite_Vectors.Vector with null 
record;
-
-   function Compare (Left, Right : in Vector) return Compare_Result;
-   --  Similar to Ada "<" for arrays; Ada Reference Manual
-   --  section 4.5.2 para 26/3.
-
-end SAL.Gen_Unbounded_Definite_Vectors.Gen_Comparable;
diff --git a/packages/wisi/sal-gen_unbounded_definite_vectors-gen_image.adb 
b/packages/wisi/sal-gen_unbounded_definite_vectors-gen_image.adb
deleted file mode 100644
index 929994a..0000000
--- a/packages/wisi/sal-gen_unbounded_definite_vectors-gen_image.adb
+++ /dev/null
@@ -1,50 +0,0 @@
---  Abstract :
---
---  See spec.
---
---  Copyright (C) 2018 Free Software Foundation, Inc.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-with Ada.Strings.Fixed;
-with Ada.Strings.Unbounded;
-function SAL.Gen_Unbounded_Definite_Vectors.Gen_Image (Item : in Vector; 
Strict : in Boolean := False) return String
-is
-   use all type Ada.Containers.Count_Type;
-   use Ada.Strings;
-   use Ada.Strings.Fixed;
-   use Ada.Strings.Unbounded;
-   Result : Unbounded_String        := To_Unbounded_String ("(");
-   First  : constant Base_Peek_Type := To_Peek_Type (Item.First_Index);
-   Last   : constant Base_Peek_Type := To_Peek_Type (Item.Last_Index);
-begin
-   if Strict and Item.Length = 0 then
-      return "(" & Trim (Index_Type'Image (Index_Type'First), Left) & " .. " &
-        Trim (Index_Type'Image (Extended_Index'First), Left) & " => <>)";
-
-   elsif Strict and Item.Length = 1 then
-      return "(" & Trim (Index_Type'Image (Index_Type'First), Left) & " => " &
-        Element_Image (Item.Elements (First)) & ")";
-
-   else
-      for I in First .. Last loop
-         Result := Result & Element_Image (Item.Elements (I));
-         if I /= Last then
-            Result := Result & ", ";
-         end if;
-      end loop;
-      Result := Result & ")";
-      return To_String (Result);
-   end if;
-end SAL.Gen_Unbounded_Definite_Vectors.Gen_Image;
diff --git a/packages/wisi/sal-gen_unbounded_definite_vectors-gen_image.ads 
b/packages/wisi/sal-gen_unbounded_definite_vectors-gen_image.ads
deleted file mode 100644
index 274e1f1..0000000
--- a/packages/wisi/sal-gen_unbounded_definite_vectors-gen_image.ads
+++ /dev/null
@@ -1,24 +0,0 @@
---  Abstract :
---
---  Image of parent.
---
---  Copyright (C) 2018 Free Software Foundation, Inc.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-generic
-   with function Element_Image (Item : in Element_Type) return String;
-function SAL.Gen_Unbounded_Definite_Vectors.Gen_Image (Item : in Vector; 
Strict : in Boolean := False) return String;
---  Image of Item, in Ada aggregate syntax. If Strict, use correct
---  syntax for 0 and 1 item; otherwise, use () and (item).
diff --git a/packages/wisi/sal-gen_unbounded_definite_vectors-gen_image_aux.adb 
b/packages/wisi/sal-gen_unbounded_definite_vectors-gen_image_aux.adb
deleted file mode 100644
index e0d90a6..0000000
--- a/packages/wisi/sal-gen_unbounded_definite_vectors-gen_image_aux.adb
+++ /dev/null
@@ -1,43 +0,0 @@
---  Abstract :
---
---  See spec.
---
---  Copyright (C) 2018 - 2019 Stephen Leake All Rights Reserved.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-with Ada.Strings.Unbounded;
-function SAL.Gen_Unbounded_Definite_Vectors.Gen_Image_Aux
-  (Item        : in Vector;
-   Aux         : in Aux_Data;
-   Association : in Boolean := False)
-  return String
-is
-   use Ada.Strings.Unbounded;
-   Result : Unbounded_String        := To_Unbounded_String ("(");
-   First  : constant Base_Peek_Type := To_Peek_Type (Item.First_Index);
-   Last   : constant Base_Peek_Type := To_Peek_Type (Item.Last_Index);
-begin
-   for I in First .. Last loop
-      if Association then
-         Result := Result & Index_Trimmed_Image (To_Index_Type (I)) & " => ";
-      end if;
-      Result := Result & Element_Image (Item.Elements (I), Aux);
-      if I /= Last then
-         Result := Result & ", ";
-      end if;
-   end loop;
-   Result := Result & ")";
-   return To_String (Result);
-end SAL.Gen_Unbounded_Definite_Vectors.Gen_Image_Aux;
diff --git a/packages/wisi/sal-gen_unbounded_definite_vectors-gen_image_aux.ads 
b/packages/wisi/sal-gen_unbounded_definite_vectors-gen_image_aux.ads
deleted file mode 100644
index eb8a89a..0000000
--- a/packages/wisi/sal-gen_unbounded_definite_vectors-gen_image_aux.ads
+++ /dev/null
@@ -1,28 +0,0 @@
---  Abstract :
---
---  Image with auxiliary data for instantiations of parent.
---
---  Copyright (C) 2018 - 2019 Stephen Leake All Rights Reserved.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-generic
-   type Aux_Data (<>) is private;
-   with function Index_Trimmed_Image (Item : in Index_Type) return String;
-   with function Element_Image (Item : in Element_Type; Aux : in Aux_Data) 
return String;
-function SAL.Gen_Unbounded_Definite_Vectors.Gen_Image_Aux
-  (Item        : in Vector;
-   Aux         : in Aux_Data;
-   Association : in Boolean := False)
-  return String;
diff --git a/packages/wisi/sal-gen_unbounded_definite_vectors.adb 
b/packages/wisi/sal-gen_unbounded_definite_vectors.adb
deleted file mode 100644
index 9e1c189..0000000
--- a/packages/wisi/sal-gen_unbounded_definite_vectors.adb
+++ /dev/null
@@ -1,585 +0,0 @@
---  Abstract :
---
---  See spec.
---
---  Copyright (C) 2018 - 2020 Free Software Foundation, Inc.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-package body SAL.Gen_Unbounded_Definite_Vectors is
-
-   function To_Peek_Type (Item : in Extended_Index) return Base_Peek_Type
-   is begin
-      return Base_Peek_Type'Base (Item - Index_Type'First) + Peek_Type'First;
-   end To_Peek_Type;
-
-   function To_Index_Type (Item : in Base_Peek_Type) return Extended_Index
-   is begin
-      return Extended_Index (Item - Peek_Type'First) + Index_Type'First;
-   end To_Index_Type;
-
-   procedure Grow (Elements : in out Array_Access; Index : in Base_Peek_Type)
-   is
-      --  Reallocate Elements so Elements (Index) is a valid element.
-
-      Old_First  : constant Peek_Type := Elements'First;
-      Old_Last   : constant Peek_Type := Elements'Last;
-      New_First  : Peek_Type          := Old_First;
-      New_Last   : Peek_Type          := Old_Last;
-      New_Length : Peek_Type          := Elements'Length;
-
-      New_Array : Array_Access;
-   begin
-      loop
-         exit when New_First <= Index;
-         New_Length := New_Length * 2;
-         New_First  := Peek_Type'Max (Peek_Type'First, Old_Last - New_Length + 
1);
-      end loop;
-      loop
-         exit when New_Last >= Index;
-         New_Length := New_Length * 2;
-         New_Last   := Peek_Type'Min (Peek_Type'Last, New_First + New_Length - 
1);
-      end loop;
-
-      New_Array := new Array_Type (New_First .. New_Last);
-
-      --  We'd like to use this:
-      --
-      --  New_Array (New_First .. Old_First - 1) := (others => <>);
-      --
-      --  but that can overflow the stack, since the aggregate is allocated
-      --  on the stack.
-
-      for I in New_First .. Old_First - 1 loop
-         New_Array (I .. I) := (others => <>);
-      end loop;
-
-      New_Array (Old_First .. Old_Last) := Elements.all;
-
-      for I in Old_Last + 1 .. New_Last loop
-         New_Array (I .. I) := (others => <>);
-      end loop;
-
-      Free (Elements);
-      Elements := New_Array;
-   end Grow;
-
-   ----------
-   --  public subprograms
-
-   overriding procedure Finalize (Container : in out Vector)
-   is begin
-      Free (Container.Elements);
-      Container.First := No_Index;
-      Container.Last  := No_Index;
-   end Finalize;
-
-   overriding procedure Adjust (Container : in out Vector)
-   is begin
-      if Container.Elements /= null then
-         Container.Elements := new Array_Type'(Container.Elements.all);
-      end if;
-   end Adjust;
-
-   function Length (Container : in Vector) return Ada.Containers.Count_Type
-   is begin
-      --  We assume the type ranges are sensible, so no exceptions occur
-      --  here.
-      if Container.Elements = null then
-         return 0;
-      else
-         return Ada.Containers.Count_Type (To_Peek_Type (Container.Last) - 
Container.Elements'First + 1);
-      end if;
-   end Length;
-
-   function Capacity (Container : in Vector) return Ada.Containers.Count_Type
-   is begin
-      if Container.Elements = null then
-         return 0;
-      else
-         return Ada.Containers.Count_Type (Container.Elements'Length);
-      end if;
-   end Capacity;
-
-   procedure Set_Capacity
-     (Container : in out Vector;
-      First     : in     Index_Type;
-      Last      : in     Extended_Index)
-   is
-      First_Peek : constant Peek_Type := To_Peek_Type (First);
-      Last_Peek  : constant Peek_Type := To_Peek_Type (Last);
-   begin
-      if Container.Elements = null then
-         Container.Elements := new Array_Type (First_Peek .. Last_Peek);
-      else
-         if First_Peek < Container.Elements'First then
-            Grow (Container.Elements, First_Peek);
-         end if;
-         if Last_Peek < Container.Elements'Last then
-            Grow (Container.Elements, Last_Peek);
-         end if;
-      end if;
-   end Set_Capacity;
-
-   function Element (Container : Vector; Index : Index_Type) return 
Element_Type
-   is begin
-      return Container.Elements (To_Peek_Type (Index));
-   end Element;
-
-   procedure Replace_Element (Container : Vector; Index : Index_Type; New_Item 
: in Element_Type)
-   is begin
-      Container.Elements (To_Peek_Type (Index)) := New_Item;
-   end Replace_Element;
-
-   function First_Index (Container : Vector) return Extended_Index
-   is begin
-      if Container.First = No_Index then
-         return No_Index + 1;
-      else
-         return Container.First;
-      end if;
-   end First_Index;
-
-   function Last_Index (Container : Vector) return Extended_Index
-   is begin
-      return Container.Last;
-   end Last_Index;
-
-   procedure Append (Container : in out Vector; New_Item : in Element_Type)
-   is begin
-      if Container.First = No_Index then
-         Container.First := Index_Type'First;
-         Container.Last  := Index_Type'First;
-      else
-         Container.Last := Container.Last + 1;
-      end if;
-
-      declare
-         J : constant Base_Peek_Type := To_Peek_Type (Container.Last);
-      begin
-         if Container.Elements = null then
-            Container.Elements := new Array_Type (J .. J);
-
-         elsif J > Container.Elements'Last then
-            Grow (Container.Elements, J);
-         end if;
-
-         Container.Elements (J) := New_Item;
-      end;
-   end Append;
-
-   procedure Append (Container : in out Vector; New_Items : in Vector)
-   is
-      use all type Ada.Containers.Count_Type;
-      Old_Last : Extended_Index := Container.Last;
-   begin
-      if New_Items.Length = 0 then
-         return;
-      end if;
-
-      if Container.First = No_Index then
-         Container.First := Index_Type'First;
-         Old_Last        := Container.First - 1;
-         Container.Last  := Container.First + Extended_Index 
(New_Items.Length) - 1;
-      else
-         Container.Last := Container.Last + Extended_Index (New_Items.Length);
-      end if;
-
-      declare
-         I : constant Peek_Type := To_Peek_Type (Old_Last + 1);
-         J : constant Peek_Type := To_Peek_Type (Container.Last);
-      begin
-         if Container.Elements = null then
-            Container.Elements := new Array_Type (I .. J);
-         elsif J > Container.Elements'Last then
-            Grow (Container.Elements, J);
-         end if;
-
-         Container.Elements (I .. J) := New_Items.Elements
-           (To_Peek_Type (New_Items.First) .. To_Peek_Type (New_Items.Last));
-      end;
-   end Append;
-
-   procedure Prepend (Container : in out Vector; New_Item : in Element_Type)
-   is begin
-      if Container.First = No_Index then
-         Container.First := Index_Type'First;
-         Container.Last  := Index_Type'First;
-      else
-         Container.First := Container.First - 1;
-      end if;
-
-      declare
-         J : constant Peek_Type := To_Peek_Type (Container.First);
-      begin
-         if Container.Elements = null then
-            Container.Elements := new Array_Type (J .. J);
-
-         elsif J < Container.Elements'First then
-            Grow (Container.Elements, J);
-         end if;
-
-         Container.Elements (J) := New_Item;
-      end;
-   end Prepend;
-
-   procedure Prepend
-     (Target       : in out Vector;
-      Source       : in     Vector;
-      Source_First : in     Index_Type;
-      Source_Last  : in     Index_Type)
-   is
-      Source_I : constant Peek_Type := To_Peek_Type (Source_First);
-      Source_J : constant Peek_Type := To_Peek_Type (Source_Last);
-   begin
-      if Target.Elements = null then
-         Target.Elements := new Array_Type'(Source.Elements (Source_I .. 
Source_J));
-         Target.First    := Source_First;
-         Target.Last     := Source_Last;
-      else
-         declare
-            New_First : constant Index_Type := Target.First - (Source_Last - 
Source_First + 1);
-            I         : constant Peek_Type  := To_Peek_Type (New_First);
-            J         : constant Peek_Type  := To_Peek_Type (Target.First - 1);
-         begin
-            if Target.Elements'First > I then
-               Grow (Target.Elements, I);
-            end if;
-            Target.Elements (I .. J) := Source.Elements (Source_I .. Source_J);
-            Target.First := New_First;
-         end;
-      end if;
-   end Prepend;
-
-   procedure Insert
-     (Container : in out Vector;
-      Element   : in     Element_Type;
-      Before    : in     Index_Type)
-   is
-      use all type Ada.Containers.Count_Type;
-   begin
-      if Container.Length = 0 then
-         Container.Append (Element);
-      else
-         Container.Last := Container.Last + 1;
-
-         declare
-            J : constant Peek_Type := To_Peek_Type (Before);
-            K : constant Base_Peek_Type := To_Peek_Type (Container.Last);
-         begin
-            if K > Container.Elements'Last then
-               Grow (Container.Elements, K);
-            end if;
-
-            Container.Elements (J + 1 .. K) := Container.Elements (J .. K - 1);
-            Container.Elements (J) := Element;
-         end;
-      end if;
-   end Insert;
-
-   procedure Merge
-     (Target : in out Vector;
-      Source : in out Vector)
-   is
-      use all type Ada.Containers.Count_Type;
-   begin
-      if Source.Length = 0 then
-         Source.Clear;
-
-      elsif Target.Length = 0 then
-         Target := Source;
-         Source.Clear;
-
-      else
-         declare
-            New_First : constant Index_Type := Extended_Index'Min 
(Target.First, Source.First);
-            New_Last  : constant Index_Type := Extended_Index'Max 
(Target.Last, Source.Last);
-            New_I     : constant Peek_Type  := To_Peek_Type (New_First);
-            New_J     : constant Base_Peek_Type  := To_Peek_Type (New_Last);
-         begin
-            if New_I < Target.Elements'First then
-               Grow (Target.Elements, New_I);
-            end if;
-            if New_J > Target.Elements'Last then
-               Grow (Target.Elements, New_J);
-            end if;
-
-            Target.Elements (To_Peek_Type (Source.First) .. To_Peek_Type 
(Source.Last)) := Source.Elements
-              (To_Peek_Type (Source.First) .. To_Peek_Type (Source.Last));
-
-            Target.First := New_First;
-            Target.Last  := New_Last;
-
-            Source.Clear;
-         end;
-      end if;
-   end Merge;
-
-   function To_Vector (Item : in Element_Type; Count : in 
Ada.Containers.Count_Type := 1) return Vector
-   is begin
-      return Result : Vector do
-         for I in 1 .. Count loop
-            Result.Append (Item);
-         end loop;
-      end return;
-   end To_Vector;
-
-   function "+" (Element : in Element_Type) return Vector
-   is begin
-      return Result : Vector do
-         Result.Append (Element);
-      end return;
-   end "+";
-
-   function "&" (Left, Right : in Element_Type) return Vector
-   is begin
-      return Result : Vector do
-         Result.Append (Left);
-         Result.Append (Right);
-      end return;
-   end "&";
-
-   function "&" (Left : in Vector; Right : in Element_Type) return Vector
-   is begin
-      return Result : Vector := Left do
-         Result.Append (Right);
-      end return;
-   end "&";
-
-   procedure Set_First (Container : in out Vector; First : in Index_Type)
-   is
-      J : constant Peek_Type := To_Peek_Type (First);
-   begin
-      Container.First := First;
-      if Container.Last = No_Index then
-         Container.Last := First - 1;
-      end if;
-
-      if Container.Last >= First then
-         if Container.Elements = null then
-            Container.Elements := new Array_Type'(J .. To_Peek_Type 
(Container.Last) => Default_Element);
-
-         elsif Container.Elements'First > J then
-            Grow (Container.Elements, J);
-         end if;
-      end if;
-   end Set_First;
-
-   procedure Set_Last (Container : in out Vector; Last : in Extended_Index)
-   is
-      J : constant Base_Peek_Type := To_Peek_Type (Last);
-   begin
-      Container.Last := Last;
-      if Container.First = No_Index then
-         Container.First := Last + 1;
-      end if;
-
-      if Last >= Container.First then
-         if Container.Elements = null then
-            Container.Elements := new Array_Type'(To_Peek_Type 
(Container.First) .. J => Default_Element);
-
-         elsif Container.Elements'Last < J then
-            Grow (Container.Elements, J);
-         end if;
-      end if;
-   end Set_Last;
-
-   procedure Set_First_Last
-     (Container : in out Vector;
-      First     : in     Index_Type;
-      Last      : in     Extended_Index)
-   is begin
-      Set_First (Container, First);
-      Set_Last (Container, Last);
-   end Set_First_Last;
-
-   procedure Delete (Container : in out Vector; Index : in Index_Type)
-   is
-      J : constant Peek_Type := To_Peek_Type (Index);
-   begin
-      Container.Elements (J .. J) := (J => <>);
-      if Index = Container.Last then
-         Container.Last := Container.Last - 1;
-      end if;
-   end Delete;
-
-   function Contains (Container : in Vector; Element : in Element_Type) return 
Boolean
-   is
-      use all type Ada.Containers.Count_Type;
-   begin
-      if Container.Length = 0 then
-         return False;
-      else
-         for It of Container.Elements.all loop
-            if It = Element then
-               return True;
-            end if;
-         end loop;
-         return False;
-      end if;
-   end Contains;
-
-   function Element (Position : Cursor) return Element_Type
-   is begin
-      return Position.Container.Elements (Position.Index);
-   end Element;
-
-   function First (Container : aliased in Vector) return Cursor
-   is
-      use all type Ada.Containers.Count_Type;
-   begin
-      if Container.Length = 0 then
-         return (Container'Access, Invalid_Peek_Index);
-      else
-         return (Container'Access, To_Peek_Type (Container.First));
-      end if;
-   end First;
-
-   function Next (Position : in Cursor) return Cursor
-   is begin
-      if Position.Index = Invalid_Peek_Index then
-         return (Position.Container, Invalid_Peek_Index);
-      elsif Position.Index < To_Peek_Type (Position.Container.Last) then
-         return (Position.Container, Position.Index + 1);
-      else
-         return (Position.Container, Invalid_Peek_Index);
-      end if;
-   end Next;
-
-   procedure Next (Position : in out Cursor)
-   is begin
-      if Position.Index = Invalid_Peek_Index then
-         null;
-      elsif Position.Index < To_Peek_Type (Position.Container.Last) then
-         Position.Index := Position.Index + 1;
-      else
-         Position := (Position.Container, Invalid_Peek_Index);
-      end if;
-   end Next;
-
-   function Prev (Position : in Cursor) return Cursor
-   is begin
-      if Position.Index = Invalid_Peek_Index then
-         return (Position.Container, Invalid_Peek_Index);
-      elsif Position.Index > To_Peek_Type (Position.Container.First) then
-         return (Position.Container, Position.Index - 1);
-      else
-         return (Position.Container, Invalid_Peek_Index);
-      end if;
-   end Prev;
-
-   procedure Prev (Position : in out Cursor)
-   is begin
-      if Position.Index = Invalid_Peek_Index then
-         null;
-      elsif Position.Index > To_Peek_Type (Position.Container.First) then
-         Position.Index := Position.Index - 1;
-      else
-         Position := (Position.Container, Invalid_Peek_Index);
-      end if;
-   end Prev;
-
-   function To_Cursor
-     (Container : aliased in Vector;
-      Index     :         in Extended_Index)
-     return Cursor
-   is begin
-      return (Container'Access, To_Peek_Type (Index));
-   end To_Cursor;
-
-   function To_Index (Position : in Cursor) return Extended_Index
-   is begin
-      if Position.Index = Invalid_Peek_Index then
-         return No_Index;
-      else
-         return To_Index_Type (Position.Index);
-      end if;
-   end To_Index;
-
-   function Constant_Ref (Container : aliased Vector; Index : in Index_Type) 
return Constant_Reference_Type
-   is
-      J : constant Peek_Type := To_Peek_Type (Index);
-   begin
-      return (Element => Container.Elements (J)'Access, Dummy => 1);
-   end Constant_Ref;
-
-   function Variable_Ref
-     (Container : aliased in Vector;
-      Index     :         in Index_Type)
-     return Variable_Reference_Type
-   is
-      J : constant Peek_Type := To_Peek_Type (Index);
-   begin
-      return (Element => Container.Elements (J)'Access, Dummy => 1);
-   end Variable_Ref;
-
-   overriding function First (Object : Iterator) return Cursor
-   is
-      use all type Ada.Containers.Count_Type;
-   begin
-      if Object.Container.Length = 0 then
-         return (Object.Container, Invalid_Peek_Index);
-      else
-         return (Object.Container, To_Peek_Type (Object.Container.First));
-      end if;
-   end First;
-
-   overriding function Last  (Object : Iterator) return Cursor
-   is
-      use all type Ada.Containers.Count_Type;
-   begin
-      if Object.Container.Length = 0 then
-         return (Object.Container, Invalid_Peek_Index);
-      else
-         return (Object.Container, To_Peek_Type (Object.Container.Last));
-      end if;
-   end Last;
-
-   overriding function Next (Object : in Iterator; Position : in Cursor) 
return Cursor
-   is begin
-      if Position.Index = To_Peek_Type (Object.Container.Last) then
-         return (Object.Container, Invalid_Peek_Index);
-      else
-         return (Object.Container, Position.Index + 1);
-      end if;
-   end Next;
-
-   overriding function Previous (Object : in Iterator; Position : in Cursor) 
return Cursor
-   is begin
-      if Position.Index = To_Peek_Type (Index_Type'First) then
-         return (Object.Container, Invalid_Peek_Index);
-      else
-         return (Object.Container, Position.Index - 1);
-      end if;
-   end Previous;
-
-   function Iterate (Container : aliased in Vector) return 
Iterator_Interfaces.Reversible_Iterator'Class
-   is begin
-      return Iterator'(Container => Container'Access);
-   end Iterate;
-
-   function Constant_Ref (Container : aliased Vector; Position : in Cursor) 
return Constant_Reference_Type
-   is begin
-      return (Element => Container.Elements (Position.Index)'Access, Dummy => 
1);
-   end Constant_Ref;
-
-   function Variable_Ref
-     (Container : aliased in Vector;
-      Position  :         in Cursor)
-     return Variable_Reference_Type
-   is begin
-      return (Element => Container.Elements (Position.Index)'Access, Dummy => 
1);
-   end Variable_Ref;
-
-end SAL.Gen_Unbounded_Definite_Vectors;
diff --git a/packages/wisi/sal-gen_unbounded_definite_vectors.ads 
b/packages/wisi/sal-gen_unbounded_definite_vectors.ads
deleted file mode 100644
index 29ecae0..0000000
--- a/packages/wisi/sal-gen_unbounded_definite_vectors.ads
+++ /dev/null
@@ -1,252 +0,0 @@
---  Abstract :
---
---  A simple unbounded vector of definite items, intended to be faster
---  than Ada.Containers.Vectors.
---
---  Prepend is as fast (in amortized time) as Append.
---
---  It provides no checking of cursor tampering; higher level code
---  must ensure that.
---
---  Design:
---
---  See ARM 3.10.2 "explicitly aliased" for why we need 'aliased' in
---  several subprogram argument modes, and why Container must be an
---  access discriminant in Cursor and Iterator.
---
---  Copyright (C) 2018 - 2020 Free Software Foundation, Inc.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-with Ada.Finalization;
-with Ada.Iterator_Interfaces;
-with Ada.Unchecked_Deallocation;
-generic
-   type Index_Type is range <>;
-   type Element_Type is private;
-   Default_Element : in Element_Type;
-package SAL.Gen_Unbounded_Definite_Vectors is
-
-   subtype Extended_Index is Index_Type'Base
-     range Index_Type'First - 1 ..
-           Index_Type'Min (Index_Type'Base'Last - 1, Index_Type'Last) + 1;
-
-   No_Index : constant Extended_Index := Extended_Index'First;
-
-   type Vector is new Ada.Finalization.Controlled with private with
-     Constant_Indexing => Constant_Ref,
-     Variable_Indexing => Variable_Ref,
-     Default_Iterator  => Iterate,
-     Iterator_Element  => Element_Type;
-
-   Empty_Vector : constant Vector;
-
-   overriding procedure Finalize (Container : in out Vector);
-   overriding procedure Adjust (Container : in out Vector);
-
-   overriding function "=" (Left, Right : in Vector) return Boolean is
-     (raise Programmer_Error);
-   --  Use Gen_Comparable child.
-
-   function Length (Container : in Vector) return Ada.Containers.Count_Type;
-   function Capacity (Container : in Vector) return Ada.Containers.Count_Type;
-
-   procedure Set_Capacity
-     (Container : in out Vector;
-      First     : in     Index_Type;
-      Last      : in     Extended_Index);
-   --  Allocates memory, but does not change Container.First, Container.Last.
-
-   procedure Clear (Container : in out Vector)
-   renames Finalize;
-
-   function First_Index (Container : Vector) return Extended_Index;
-   --  No_Index + 1 when Container is empty, so "for I in C.First_Index
-   --  .. C.Last_Index loop" works.
-   --
-   --  If you need No_Index for an empty Container, use To_Index 
(Container.First).
-
-   function Last_Index (Container : Vector) return Extended_Index;
-   --  No_Index when Container is empty.
-
-   function Element (Container : Vector; Index : Index_Type) return 
Element_Type
-   with Pre => Index >= Container.First_Index and Index <= 
Container.Last_Index;
-
-   procedure Replace_Element (Container : Vector; Index : Index_Type; New_Item 
: in Element_Type);
-
-   procedure Append (Container : in out Vector; New_Item : in Element_Type);
-   --  Insert New_Item at end of Container.
-   --
-   --  Raises Constraint_Error if index of new item would be greater than
-   --  Index_Type'Last.
-
-   procedure Append (Container : in out Vector; New_Items : in Vector);
-   --  Insert all elements of New_Items at end of Container.
-
-   procedure Prepend (Container : in out Vector; New_Item : in Element_Type);
-   --  Insert New_Item at beginning of Container.
-   --
-   --  Raises Constraint_Error if index of new item would be less than
-   --  Index_Type'First.
-
-   procedure Prepend
-     (Target       : in out Vector;
-      Source       : in     Vector;
-      Source_First : in     Index_Type;
-      Source_Last  : in     Index_Type);
-   --  Copy Source (Source_First .. Source_Last) to Target, before
-   --  Target.First_Index.
-
-   procedure Insert
-     (Container : in out Vector;
-      Element   : in     Element_Type;
-      Before    : in     Index_Type);
-   --  Existing elements at Before and after are slid to higher indices.
-
-   procedure Merge
-     (Target : in out Vector;
-      Source : in out Vector);
-   --  Copy all elements from Source to Target, to the same index range,
-   --  deleting them from Source, and overwriting overlapping ranges.
-
-   function To_Vector (Item : in Element_Type; Count : in 
Ada.Containers.Count_Type := 1) return Vector;
-
-   function "+" (Element : in Element_Type) return Vector;
-
-   function "&" (Left, Right : in Element_Type) return Vector;
-   function "&" (Left : in Vector; Right : in Element_Type) return Vector;
-
-   procedure Set_First_Last
-     (Container : in out Vector;
-      First     : in     Index_Type;
-      Last      : in     Extended_Index);
-   --  Elements in First .. Last that have not been set have
-   --  Default_Element value.
-
-   procedure Delete (Container : in out Vector; Index : in Index_Type);
-   --  Replace Index element contents with default. If Index =
-   --  Container.Last_Index, Container.Last_Index is decremented.
-
-   function Contains (Container : in Vector; Element : in Element_Type) return 
Boolean;
-   --  Return True if Element is in Container, False if not.
-
-   type Constant_Reference_Type (Element : not null access constant 
Element_Type) is private with
-     Implicit_Dereference => Element;
-
-   function Constant_Ref (Container : aliased in Vector; Index : in 
Index_Type) return Constant_Reference_Type
-   with Inline, Pre => Index in Container.First_Index .. Container.Last_Index;
-
-   type Variable_Reference_Type (Element : not null access Element_Type) is 
private with
-     Implicit_Dereference => Element;
-
-   function Variable_Ref (Container : aliased in Vector; Index : in 
Index_Type) return Variable_Reference_Type
-   with Inline, Pre => Index in Container.First_Index .. Container.Last_Index;
-
-   type Cursor (<>) is private;
-
-   function Has_Element (Position : Cursor) return Boolean;
-   function Element (Position : Cursor) return Element_Type
-   with Pre => Has_Element (Position);
-   function First (Container : aliased in Vector) return Cursor;
-   function Next (Position : in Cursor) return Cursor;
-   procedure Next (Position : in out Cursor);
-   function Prev (Position : in Cursor) return Cursor;
-   procedure Prev (Position : in out Cursor);
-
-   function To_Cursor
-     (Container : aliased in Vector;
-      Index     :         in Extended_Index)
-     return Cursor
-   with Pre => Index = No_Index or Index in Container.First_Index .. 
Container.Last_Index;
-
-   function To_Index (Position : in Cursor) return Extended_Index;
-
-   package Iterator_Interfaces is new Ada.Iterator_Interfaces (Cursor, 
Has_Element);
-
-   function Iterate (Container : aliased in Vector) return 
Iterator_Interfaces.Reversible_Iterator'Class;
-
-   function Constant_Ref (Container : aliased in Vector; Position : in Cursor) 
return Constant_Reference_Type
-   with Pre => Has_Element (Position) and then
-               To_Index (Position) in Container.First_Index .. 
Container.Last_Index;
-
-   function Variable_Ref (Container : aliased in Vector; Position  : in 
Cursor) return Variable_Reference_Type
-   with Pre => Has_Element (Position) and then
-               To_Index (Position) in Container.First_Index .. 
Container.Last_Index;
-   pragma Inline (Variable_Ref);
-
-private
-
-   type Array_Type is array (SAL.Peek_Type range <>) of aliased Element_Type;
-   type Array_Access is access Array_Type;
-   procedure Free is new Ada.Unchecked_Deallocation (Array_Type, Array_Access);
-
-   type Vector is new Ada.Finalization.Controlled with
-   record
-      Elements : Array_Access;
-      --  Elements may be non-null with First = No_Index, after
-      --  Set_Capacity. If First /= No_Index and Last >= First, Elements /=
-      --  null. First > Last means Vector is empty.
-      First    : Extended_Index := No_Index;
-      Last     : Extended_Index := No_Index;
-   end record;
-
-   type Vector_Access is access constant Vector;
-   for Vector_Access'Storage_Size use 0;
-
-   type Cursor (Container : not null access constant Vector) is
-   record
-      Index : Base_Peek_Type := Invalid_Peek_Index;
-   end record;
-
-   type Iterator (Container : not null access constant Vector) is new 
Iterator_Interfaces.Reversible_Iterator with
-     null record;
-
-   overriding function First (Object : Iterator) return Cursor;
-   overriding function Last  (Object : Iterator) return Cursor;
-
-   overriding function Next
-     (Object   : Iterator;
-      Position : Cursor) return Cursor;
-
-   overriding function Previous
-     (Object   : Iterator;
-      Position : Cursor) return Cursor;
-
-   type Constant_Reference_Type (Element : not null access constant 
Element_Type) is
-   record
-      Dummy : Integer := raise Program_Error with "uninitialized reference";
-   end record;
-
-   type Variable_Reference_Type (Element : not null access Element_Type) is
-   record
-      Dummy : Integer := raise Program_Error with "uninitialized reference";
-   end record;
-
-   Empty_Vector : constant Vector := (Ada.Finalization.Controlled with others 
=> <>);
-
-   ----------
-   --  Visible for contracts/SPARK
-
-   function Has_Element (Position : Cursor) return Boolean
-     is (Position.Index /= Invalid_Peek_Index);
-
-   ----------
-   --  Visible for child package
-
-   function To_Peek_Type (Item : in Extended_Index) return Base_Peek_Type with 
Inline;
-   function To_Index_Type (Item : in Base_Peek_Type) return Extended_Index;
-
-   procedure Grow (Elements : in out Array_Access; Index : in Base_Peek_Type);
-
-end SAL.Gen_Unbounded_Definite_Vectors;
diff --git a/packages/wisi/sal-gen_unbounded_definite_vectors_sorted.adb 
b/packages/wisi/sal-gen_unbounded_definite_vectors_sorted.adb
deleted file mode 100644
index 8e40695..0000000
--- a/packages/wisi/sal-gen_unbounded_definite_vectors_sorted.adb
+++ /dev/null
@@ -1,374 +0,0 @@
---  Abstract :
---
---  See spec.
---
---  Copyright (C) 2019 - 2020 Free Software Foundation, Inc.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-package body SAL.Gen_Unbounded_Definite_Vectors_Sorted is
-
-   ----------
-   --  Body subprograms, arbitrary order
-
-   procedure Grow (Elements : in out Array_Access; Index : in Base_Peek_Type)
-   is
-      --  Reallocate Elements so Elements (Index) is a valid element.
-
-      Old_First  : constant Peek_Type := Elements'First;
-      Old_Last   : constant Peek_Type := Elements'Last;
-      New_First  : Peek_Type          := Old_First;
-      New_Last   : Peek_Type          := Old_Last;
-      New_Length : Peek_Type          := Elements'Length;
-
-      New_Array : Array_Access;
-   begin
-      loop
-         exit when New_First <= Index;
-         New_Length := New_Length * 2;
-         New_First  := Peek_Type'Max (Peek_Type'First, Old_Last - New_Length + 
1);
-      end loop;
-      loop
-         exit when New_Last >= Index;
-         New_Length := New_Length * 2;
-         New_Last   := Peek_Type'Min (Peek_Type'Last, New_First + New_Length - 
1);
-      end loop;
-
-      New_Array := new Array_Type (New_First .. New_Last);
-
-      --  We'd like to use this:
-      --
-      --  New_Array (New_First .. Old_First - 1) := (others => <>);
-      --
-      --  but that can overflow the stack, since the aggregate is allocated
-      --  on the stack.
-
-      for I in New_First .. Old_First - 1 loop
-         New_Array (I .. I) := (others => <>);
-      end loop;
-
-      New_Array (Old_First .. Old_Last) := Elements.all;
-
-      for I in Old_Last + 1 .. New_Last loop
-         New_Array (I .. I)   := (others => <>);
-      end loop;
-
-      Free (Elements);
-      Elements := New_Array;
-   end Grow;
-
-   procedure Find
-     (Container : in     Vector;
-      Key       : in     Key_Type;
-      Found     :    out Boolean;
-      At_After  :    out Base_Peek_Type)
-   with Pre => Container.Last /= No_Index
-   is
-      --  If Found is True, item is at At_After. If False, item should be
-      --  inserted after At_After.
-      Low  : Base_Peek_Type := Peek_Type'First - 1;
-      High : Base_Peek_Type := Container.Last + 1;
-      I    : Base_Peek_Type := Low + High / 2;
-   begin
-      loop
-         case Key_Compare (Key, To_Key (Container.Elements (I))) is
-         when Less =>
-            High := I;
-            if I = Low then
-               Found    := False;
-               At_After := I;
-               return;
-
-            elsif I - 1 = Low then
-               Found    := False;
-               At_After := I - 1;
-               return;
-
-            else
-               I := I - (I - Low) / 2;
-            end if;
-
-         when Equal =>
-            Found    := True;
-            At_After := I;
-            return;
-
-         when Greater =>
-            Low := I;
-            if I = High then
-               Found    := False;
-               At_After := I - 1;
-               return;
-
-            elsif I + 1 = High then
-               Found    := False;
-               At_After := I;
-               return;
-
-            else
-               I := I + (High - I) / 2;
-            end if;
-         end case;
-      end loop;
-   end Find;
-
-   ----------
-   --  Public subprograms
-
-   overriding procedure Finalize (Container : in out Vector)
-   is begin
-      Free (Container.Elements);
-      Container.Last := No_Index;
-   end Finalize;
-
-   overriding procedure Adjust (Container : in out Vector)
-   is begin
-      if Container.Elements /= null then
-         Container.Elements := new Array_Type'(Container.Elements.all);
-      end if;
-   end Adjust;
-
-   function Length (Container : in Vector) return Ada.Containers.Count_Type
-   is begin
-      --  We assume the type ranges are sensible, so no exceptions occur
-      --  here.
-      if Container.Elements = null then
-         return 0;
-      else
-         return Ada.Containers.Count_Type (Container.Last - 
Container.Elements'First + 1);
-      end if;
-   end Length;
-
-   function Capacity (Container : in Vector) return Ada.Containers.Count_Type
-   is begin
-      if Container.Elements = null then
-         return 0;
-      else
-         return Ada.Containers.Count_Type (Container.Elements'Length);
-      end if;
-   end Capacity;
-
-   procedure Set_Capacity
-     (Container : in out Vector;
-      Length    : in     Ada.Containers.Count_Type)
-   is
-      First_Peek : constant Peek_Type      := Peek_Type'First;
-      Last_Peek  : constant Base_Peek_Type := Base_Peek_Type (Length);
-   begin
-      if Length = 0 then
-         return;
-      elsif Container.Elements = null then
-         Container.Elements := new Array_Type (First_Peek .. Last_Peek);
-      else
-         if First_Peek < Container.Elements'First then
-            Grow (Container.Elements, First_Peek);
-         end if;
-         if Last_Peek < Container.Elements'Last then
-            Grow (Container.Elements, Last_Peek);
-         end if;
-      end if;
-   end Set_Capacity;
-
-   function Has_Element (Position : Cursor) return Boolean is
-   begin
-      return Position.Index /= Invalid_Peek_Index;
-   end Has_Element;
-
-   function "&" (Left, Right : in Element_Type) return Vector
-   is begin
-      return Result : Vector do
-         Result.Insert (Left);
-         Result.Insert (Right);
-      end return;
-   end "&";
-
-   function "&" (Left : in Vector; Right : in Element_Type) return Vector
-   is begin
-      return Result : Vector := Left do
-         Result.Insert (Right);
-      end return;
-   end "&";
-
-   function Contains (Container : in Vector; Key : in Key_Type) return Boolean
-   is
-      Found : Boolean;
-      I     : Base_Peek_Type;
-   begin
-      if Container.Last = No_Index then
-         return False;
-      end if;
-      Find (Container, Key, Found, I);
-      return Found;
-   end Contains;
-
-   procedure Insert
-     (Container : in out Vector;
-      New_Item  : in     Element_Type)
-   is
-      New_Key : constant Key_Type       := To_Key (New_Item);
-      J       : constant Peek_Type      := Peek_Type'First;
-      K       : constant Base_Peek_Type := Container.Last;
-      I       : Base_Peek_Type          := K;
-   begin
-      if Container.Last = No_Index then
-         Container.Last := Peek_Type'First;
-         I              := Container.Last;
-
-         if Container.Elements = null then
-            Container.Elements := new Array_Type (I .. I);
-            --  else Set_Capacity called.
-         end if;
-         Container.Elements (I) := New_Item;
-         return;
-
-      else
-         Container.Last := Container.Last + 1;
-      end if;
-
-      pragma Assert (Container.Elements /= null);
-
-      if I + 1 > Container.Elements'Last then
-         Grow (Container.Elements, I + 1);
-      end if;
-
-      loop
-         exit when I < J;
-
-         case Key_Compare (New_Key, To_Key (Container.Elements (I))) is
-         when Less =>
-            --  Linear search is simple, we assume insert is used far less 
often
-            --  than Find. And this is optimal when inserting in Key order.
-            I :=  I - 1;
-         when Equal =>
-            --  Insert after I
-            exit;
-         when Greater =>
-            --  Insert after I
-            exit;
-         end case;
-      end loop;
-
-      if I < J then
-         --  Insert before all
-         Container.Elements (J + 1 .. K + 1) := Container.Elements (J .. K);
-         Container.Elements (J) := New_Item;
-      else
-         --  Insert after I
-         Container.Elements (I + 2 .. K + 1) := Container.Elements (I + 1 .. 
K);
-         Container.Elements (I + 1) := New_Item;
-      end if;
-   end Insert;
-
-   function Find
-     (Container : aliased in Vector;
-      Key       :         in Key_Type)
-     return Find_Reference_Type
-   is
-      Found : Boolean;
-      I     : Base_Peek_Type;
-   begin
-      if Container.Last = No_Index then
-         return (Element => null, Dummy => 1);
-      end if;
-      Find (Container, Key, Found, I);
-      if Found then
-         return (Element => Container.Elements (I)'Access, Dummy => 1);
-      else
-         return (Element => null, Dummy => 1);
-      end if;
-   end Find;
-
-   function Find_Constant
-     (Container : aliased in Vector;
-      Key       :         in Key_Type)
-     return Find_Reference_Constant_Type
-   is
-      Found : Boolean;
-      I     : Base_Peek_Type;
-   begin
-      if Container.Last = No_Index then
-         return (Element => null, Dummy => 1);
-      end if;
-      Find (Container, Key, Found, I);
-      if Found then
-         return (Element => Container.Elements (I)'Access, Dummy => 1);
-      else
-         return (Element => null, Dummy => 1);
-      end if;
-   end Find_Constant;
-
-   overriding function First (Object : Iterator) return Cursor
-   is begin
-      if Object.Container.Elements = null then
-         return (Index => Invalid_Peek_Index);
-      else
-         return (Index => Peek_Type'First);
-      end if;
-   end First;
-
-   overriding function Last  (Object : Iterator) return Cursor
-   is begin
-      if Object.Container.Elements = null then
-         return (Index => Invalid_Peek_Index);
-      else
-         return (Index => Object.Container.Last);
-      end if;
-   end Last;
-
-   overriding function Next (Object : in Iterator; Position : in Cursor) 
return Cursor
-   is begin
-      if Position.Index = Object.Container.Last then
-         return (Index => Invalid_Peek_Index);
-      else
-         return (Index => Position.Index + 1);
-      end if;
-   end Next;
-
-   overriding function Previous (Object : in Iterator; Position : in Cursor) 
return Cursor
-   is
-      pragma Unreferenced (Object);
-   begin
-      if Position.Index = Peek_Type'First then
-         return (Index => Invalid_Peek_Index);
-      else
-         return (Index => Position.Index - 1);
-      end if;
-   end Previous;
-
-   function Iterate (Container : aliased in Vector) return 
Iterator_Interfaces.Reversible_Iterator'Class
-   is begin
-      return Iterator'(Container => Container'Access);
-   end Iterate;
-
-   function Constant_Ref (Container : aliased Vector; Position : in Cursor) 
return Constant_Reference_Type
-   is begin
-      return (Element => Container.Elements (Position.Index)'Access, Dummy => 
1);
-   end Constant_Ref;
-
-   function Last_Index (Container : in Vector) return Base_Peek_Type
-   is begin
-      return Container.Last;
-   end Last_Index;
-
-   function To_Index (Position : in Cursor) return Base_Peek_Type
-   is begin
-      return Position.Index;
-   end To_Index;
-
-   function Constant_Ref (Container : aliased Vector; Index : in Peek_Type) 
return Constant_Reference_Type
-   is begin
-      return (Element => Container.Elements (Index)'Access, Dummy => 1);
-   end Constant_Ref;
-
-end SAL.Gen_Unbounded_Definite_Vectors_Sorted;
diff --git a/packages/wisi/sal-gen_unbounded_definite_vectors_sorted.ads 
b/packages/wisi/sal-gen_unbounded_definite_vectors_sorted.ads
deleted file mode 100644
index 2a52c74..0000000
--- a/packages/wisi/sal-gen_unbounded_definite_vectors_sorted.ads
+++ /dev/null
@@ -1,172 +0,0 @@
---  Abstract :
---
---  A simple unbounded sorted vector of definite items.
---
---  Copyright (C) 2019 - 2020 Free Software Foundation, Inc.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-with Ada.Finalization;
-with Ada.Iterator_Interfaces;
-with Ada.Unchecked_Deallocation;
-generic
-   type Element_Type is private;
-   type Key_Type is private;
-   with function To_Key (Item : in Element_Type) return Key_Type;
-   with function Key_Compare (Left, Right : in Key_Type) return Compare_Result;
-package SAL.Gen_Unbounded_Definite_Vectors_Sorted is
-
-   use all type Ada.Containers.Count_Type;
-
-   type Vector is new Ada.Finalization.Controlled with private with
-      Constant_Indexing => Constant_Ref,
-      Default_Iterator  => Iterate,
-      Iterator_Element  => Element_Type;
-
-   Empty_Vector : constant Vector;
-
-   overriding procedure Finalize (Container : in out Vector);
-   overriding procedure Adjust (Container : in out Vector);
-
-   procedure Clear (Container : in out Vector)
-   renames Finalize;
-
-   function Length (Container : in Vector) return Ada.Containers.Count_Type;
-   function Capacity (Container : in Vector) return Ada.Containers.Count_Type;
-
-   procedure Set_Capacity
-     (Container : in out Vector;
-      Length    : in     Ada.Containers.Count_Type);
-   --  Allocates uninitialized memory; does not change Container.First,
-   --  Container.Last.
-
-   function "&" (Left, Right : in Element_Type) return Vector;
-   function "&" (Left : in Vector; Right : in Element_Type) return Vector;
-
-   function Contains (Container : in Vector; Key : in Key_Type) return Boolean;
-
-   procedure Insert
-     (Container : in out Vector;
-      New_Item  : in     Element_Type);
-   --  Insert New_Item in sorted position. Items are sorted in increasing
-   --  order according to Element_Compare.
-   --
-   --  Raises Duplicate_Key if To_Key (New_Item) is already in Container.
-
-   type Find_Reference_Type (Element : access Element_Type) is private with
-     Implicit_Dereference => Element;
-
-   function Find
-     (Container : aliased in Vector;
-      Key       :         in Key_Type)
-     return Find_Reference_Type;
-   --  Result.Element is null if Key not in Container. User must not modify 
Key.
-
-   type Find_Reference_Constant_Type (Element : access constant Element_Type) 
is private with
-     Implicit_Dereference => Element;
-
-   function Find_Constant
-     (Container : aliased in Vector;
-      Key       : in Key_Type)
-     return Find_Reference_Constant_Type;
-   --  Result.Element is null if Key not in Container.
-
-   type Cursor is private;
-
-   No_Element : constant Cursor;
-
-   function Has_Element (Position : Cursor) return Boolean;
-
-   package Iterator_Interfaces is new Ada.Iterator_Interfaces (Cursor, 
Has_Element);
-
-   function Iterate (Container : aliased in Vector) return 
Iterator_Interfaces.Reversible_Iterator'Class;
-
-   type Constant_Reference_Type (Element : not null access constant 
Element_Type) is private with
-     Implicit_Dereference => Element;
-
-   function Constant_Ref (Container : aliased Vector; Position : in Cursor) 
return Constant_Reference_Type
-   with Inline,
-     Pre => To_Index (Position) in Container.First_Index .. 
Container.Last_Index;
-
-   function First_Index (Container : in Vector) return Peek_Type is 
(Peek_Type'First);
-   function Last_Index (Container : in Vector) return Base_Peek_Type
-   with Inline;
-   function To_Index (Position : in Cursor) return Base_Peek_Type;
-   function Constant_Ref (Container : aliased Vector; Index : in Peek_Type) 
return Constant_Reference_Type
-   with Inline,
-     Pre => Index in Container.First_Index .. Container.Last_Index;
-
-private
-
-   type Array_Type is array (SAL.Peek_Type range <>) of aliased Element_Type;
-   type Array_Access is access Array_Type;
-   procedure Free is new Ada.Unchecked_Deallocation (Array_Type, Array_Access);
-
-   No_Index : constant Base_Peek_Type := 0;
-
-   type Vector is new Ada.Finalization.Controlled with
-   record
-      Elements : Array_Access;
-      --  Elements may be non-null with First = No_Index, after
-      --  Set_Capacity. If First /= No_Index and Last >= First, Elements /=
-      --  null.
-      Last     : Base_Peek_Type := No_Index;
-   end record;
-
-   type Vector_Access is access constant Vector;
-   for Vector_Access'Storage_Size use 0;
-
-   type Cursor is record
-      Index : Base_Peek_Type := No_Index;
-   end record;
-
-   type Iterator (Container : not null access constant Vector) is new 
Iterator_Interfaces.Reversible_Iterator
-     with null record;
-
-   overriding function First (Object : Iterator) return Cursor;
-   overriding function Last  (Object : Iterator) return Cursor;
-
-   overriding function Next
-     (Object   : Iterator;
-      Position : Cursor) return Cursor;
-
-   overriding function Previous
-     (Object   : Iterator;
-      Position : Cursor) return Cursor;
-
-   type Find_Reference_Type (Element : access Element_Type) is
-   record
-      Dummy : Integer := raise Program_Error with "uninitialized reference";
-   end record;
-
-   type Find_Reference_Constant_Type (Element : access constant Element_Type) 
is
-   record
-      Dummy : Integer := raise Program_Error with "uninitialized reference";
-   end record;
-
-   type Constant_Reference_Type (Element : not null access constant 
Element_Type) is
-   record
-      Dummy : Integer := raise Program_Error with "uninitialized reference";
-   end record;
-
-   Empty_Vector : constant Vector := (Ada.Finalization.Controlled with others 
=> <>);
-
-   No_Element : constant Cursor := (others => <>);
-
-   ----------
-   --  Visible for child package
-
-   procedure Grow (Elements : in out Array_Access; Index : in Base_Peek_Type);
-
-end SAL.Gen_Unbounded_Definite_Vectors_Sorted;
diff --git a/packages/wisi/sal-gen_unconstrained_array_image.adb 
b/packages/wisi/sal-gen_unconstrained_array_image.adb
deleted file mode 100644
index 7ea1c83..0000000
--- a/packages/wisi/sal-gen_unconstrained_array_image.adb
+++ /dev/null
@@ -1,34 +0,0 @@
---  Abstract :
---
---  See spec.
---
---  Copyright (C) 2019 Free Software Foundation, Inc.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-with Ada.Strings.Unbounded; use Ada.Strings.Unbounded;
-function SAL.Gen_Unconstrained_Array_Image (Item : in Array_Type) return String
-is
-   Result : Unbounded_String := To_Unbounded_String ("(");
-begin
-   for I in Item'Range loop
-      Result := Result & Element_Image (Item (I));
-      if I = Item'Last then
-         Result := Result & ")";
-      else
-         Result := Result & ", ";
-      end if;
-   end loop;
-   return To_String (Result);
-end SAL.Gen_Unconstrained_Array_Image;
diff --git a/packages/wisi/sal-gen_unconstrained_array_image.ads 
b/packages/wisi/sal-gen_unconstrained_array_image.ads
deleted file mode 100644
index 226ba00..0000000
--- a/packages/wisi/sal-gen_unconstrained_array_image.ads
+++ /dev/null
@@ -1,24 +0,0 @@
---  Abstract :
---
---  Image for unconstrained Ada array types
---
---  Copyright (C) 2019 Free Software Foundation, Inc.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-generic
-   type Index_Type is (<>);
-   type Element_Type is private;
-   type Array_Type is array (Index_Type range <>) of Element_Type;
-   with function Element_Image (Item : in Element_Type) return String;
-function SAL.Gen_Unconstrained_Array_Image (Item : in Array_Type) return 
String;
diff --git a/packages/wisi/sal-gen_unconstrained_array_image_aux.adb 
b/packages/wisi/sal-gen_unconstrained_array_image_aux.adb
deleted file mode 100644
index 9e4c5cd..0000000
--- a/packages/wisi/sal-gen_unconstrained_array_image_aux.adb
+++ /dev/null
@@ -1,33 +0,0 @@
---  Abstract :
---
---  See spec.
---
---  Copyright (C) 2019, 2020 Free Software Foundation, Inc.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-with Ada.Strings.Unbounded; use Ada.Strings.Unbounded;
-function SAL.Gen_Unconstrained_Array_Image_Aux (Item : in Array_Type; Aux : in 
Aux_Data) return String
-is
-   Result : Unbounded_String := To_Unbounded_String ("(");
-begin
-   for I in Item'Range loop
-      Result := Result & Element_Image (Item (I), Aux);
-      if I < Item'Last then
-         Result := Result & ", ";
-      end if;
-   end loop;
-   Result := Result & ")";
-   return To_String (Result);
-end SAL.Gen_Unconstrained_Array_Image_Aux;
diff --git a/packages/wisi/sal-gen_unconstrained_array_image_aux.ads 
b/packages/wisi/sal-gen_unconstrained_array_image_aux.ads
deleted file mode 100644
index ad2b9cb..0000000
--- a/packages/wisi/sal-gen_unconstrained_array_image_aux.ads
+++ /dev/null
@@ -1,25 +0,0 @@
---  Abstract :
---
---  Image for unconstrained Ada array types
---
---  Copyright (C) 2019, 2020 Free Software Foundation, Inc.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-generic
-   type Index_Type is (<>);
-   type Element_Type is private;
-   type Array_Type is array (Index_Type range <>) of Element_Type;
-   type Aux_Data (<>) is private;
-   with function Element_Image (Item : in Element_Type; Aux : in Aux_Data) 
return String;
-function SAL.Gen_Unconstrained_Array_Image_Aux (Item : in Array_Type; Aux : in 
Aux_Data) return String;
diff --git a/packages/wisi/sal-generic_decimal_image.adb 
b/packages/wisi/sal-generic_decimal_image.adb
deleted file mode 100644
index 2699277..0000000
--- a/packages/wisi/sal-generic_decimal_image.adb
+++ /dev/null
@@ -1,48 +0,0 @@
---  Abstract:
---
---  see spec
---
---  Copyright (C) 2005, 2006, 2009 Stephen Leake.  All Rights Reserved.
---
---  This library is free software; you can redistribute it and/or
---  modify it under terms of the GNU General Public License as
---  published by the Free Software Foundation; either version 3, or (at
---  your option) any later version. This library 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
---  distributed with this program; see file COPYING. If not, write to
---  the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
---  MA 02111-1307, USA.
---
---  As a special exception, if other files instantiate generics from
---  this unit, or you link this unit with other files to produce an
---  executable, this  unit  does not  by itself cause  the resulting
---  executable to be covered by the GNU General Public License. This
---  exception does not however invalidate any other reasons why the
---  executable file  might be covered by the  GNU Public License.
-
-pragma License (Modified_GPL);
-
-function SAL.Generic_Decimal_Image
-  (Item  : in Number_Type;
-   Width : in Natural)
-  return String
-is
-   pragma Warnings (Off);
-   --  Avoid warning about "abs applied to non-negative value has no
-   --  effect" for some instantiations.
-   Temp : Integer := abs Integer (Item);
-   --  IMPROVEME: need test for Decimal_Image, include constrained positive 
number_type
-   pragma Warnings (On);
-   Digit : Integer;
-   Image : String (1 .. Width);
-begin
-   for I in reverse Image'Range loop
-      Digit     := Temp mod 10;
-      Temp      := Temp / 10;
-      Image (I) := Character'Val (Character'Pos ('0') + Digit);
-   end loop;
-   return Image;
-end SAL.Generic_Decimal_Image;
diff --git a/packages/wisi/sal-generic_decimal_image.ads 
b/packages/wisi/sal-generic_decimal_image.ads
deleted file mode 100644
index ec749f6..0000000
--- a/packages/wisi/sal-generic_decimal_image.ads
+++ /dev/null
@@ -1,37 +0,0 @@
---  Abstract:
---
---  Generic leading zero unsigned decimal image
---
---  Copyright (C) 2004, 2009, 2019 Free Software Foundation.  All Rights 
Reserved.
---
---  This library is free software; you can redistribute it and/or
---  modify it under terms of the GNU General Public License as
---  published by the Free Software Foundation; either version 3, or (at
---  your option) any later version. This library 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
---  distributed with this program; see file COPYING. If not, write to
---  the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
---  MA 02111-1307, USA.
---
---  As a special exception, if other files instantiate generics from
---  this unit, or you link this unit with other files to produce an
---  executable, this  unit  does not  by itself cause  the resulting
---  executable to be covered by the GNU General Public License. This
---  exception does not however invalidate any other reasons why the
---  executable file  might be covered by the  GNU Public License.
-
-pragma License (Modified_GPL);
-
-generic
-   type Number_Type is range <>;
-function SAL.Generic_Decimal_Image
-  (Item  : in Number_Type;
-   Width : in Natural)
-  return String;
---  Return a decimal unsigned image of Item, padded with leading zeros
---  to Width. If Width is too small for Item, leading digits are
---  silently truncated.
-pragma Pure (SAL.Generic_Decimal_Image);
diff --git a/packages/wisi/sal.adb b/packages/wisi/sal.adb
deleted file mode 100644
index 6265651..0000000
--- a/packages/wisi/sal.adb
+++ /dev/null
@@ -1,32 +0,0 @@
---  Abstract:
---
---  See spec.
---
---  Copyright (C) 1997 - 2004, 2006, 2009, 2019, 2020 Free Software 
Foundation, Inc.
---
---  SAL is free software; you can redistribute it and/or modify it
---  under terms of the GNU General Public License as published by the
---  Free Software Foundation; either version 3, or (at your option) any
---  later version. SAL 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 distributed with SAL; see
---  file COPYING. If not, write to the Free Software Foundation, 59
---  Temple Place - Suite 330, Boston, MA 02111-1307, USA.
---
---  As a special exception, if other files instantiate generics from
---  SAL, or you link SAL object files with other files to produce
---  an executable, that does not by itself cause the resulting
---  executable to be covered by the GNU General Public License. This
---  exception does not however invalidate any other reasons why the
---  executable file might be covered by the GNU Public License.
---
-package body SAL is
-
-   function Version return String is
-   begin
-      return "SAL 3.5";
-   end Version;
-
-end SAL;
diff --git a/packages/wisi/sal.ads b/packages/wisi/sal.ads
deleted file mode 100644
index 1e63dbc..0000000
--- a/packages/wisi/sal.ads
+++ /dev/null
@@ -1,75 +0,0 @@
---  Abstract:
---
---  Root package for Stephe's Ada Library packages.
---
---  See sal.html for more information.
---
---  See http://stephe-leake.org/ada/sal.html for the
---  latest version.
---
---  Contact Stephe at stephen_leake@stephe-leake.org.
---
---  Copyright (C) 1997 - 2004, 2008, 2009, 2015, 2017, 2018 Free Software 
Foundation, Inc.
---
---  SAL is free software; you can redistribute it and/or modify it
---  under terms of the GNU General Public License as published by the
---  Free Software Foundation; either version 3, or (at your option) any
---  later version. SAL 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 distributed with SAL; see
---  file COPYING. If not, write to the Free Software Foundation, 59
---  Temple Place - Suite 330, Boston, MA 02111-1307, USA.
---
---  As a special exception, if other files instantiate generics from
---  SAL, or you link SAL object files with other files to produce
---  an executable, that does not by itself cause the resulting
---  executable to be covered by the GNU General Public License. This
---  exception does not however invalidate any other reasons why the
---  executable file might be covered by the GNU Public License.
-
-pragma License (Modified_GPL);
-
-with Ada.Containers;
-
-package SAL is
-   pragma Pure;
-
-   function Version return String;
-   --  Returns string with format "SAL x.xx".
-
-   Container_Empty                  : exception;
-   Container_Full                   : exception;
-   Config_File_Error                : exception;
-   Domain_Error                     : exception;
-   Duplicate_Key                    : exception;
-   Initialization_Error             : exception;
-   Invalid_Format                   : exception;
-   Invalid_Limit                    : exception;
-   Invalid_Operation                : exception;
-   Invalid_Range                    : exception;
-   Iterator_Error                   : exception;
-   Not_Found                        : exception;
-   Not_Implemented                  : exception;
-   Parameter_Error                  : exception;
-   Programmer_Error                 : exception;
-   Range_Error                      : exception;
-
-   --------------
-   --  General options
-
-   type Direction_Type is (Forward, Backward);
-
-   type Duplicate_Action_Type is (Allow, Ignore, Error);
-
-   type Overflow_Action_Type is (Overwrite, Error);
-
-   --  We use a new type for Peek_Type, not just
-   --  Ada.Containers.Count_Type, to enforce Peek_Type'First = top/first.
-   type Base_Peek_Type is new Ada.Containers.Count_Type range 0 .. 
Ada.Containers.Count_Type'Last;
-   subtype Peek_Type is Base_Peek_Type range 1 .. Base_Peek_Type'Last;
-   Invalid_Peek_Index : constant Base_Peek_Type := 0;
-
-   type Compare_Result is (Less, Equal, Greater);
-end SAL;
diff --git a/packages/wisi/standard_common.gpr 
b/packages/wisi/standard_common.gpr
deleted file mode 100644
index ce019c7..0000000
--- a/packages/wisi/standard_common.gpr
+++ /dev/null
@@ -1,152 +0,0 @@
---  Abstract :
---
---  Standard settings for all of Stephe's Ada projects.
---
---  Copyright (C) 2018 - 2020 Free Software Foundation, Inc.
---
---  This program is free software; you can redistribute it and/or
---  modify it under terms of the GNU General Public License as
---  published by the Free Software Foundation; either version 3, 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
---  distributed with this program; see file COPYING. If not, write to
---  the Free Software Foundation, 51 Franklin Street, Suite 500, Boston,
---  MA 02110-1335, USA.
-
-project Standard_Common is
-   for Source_Dirs use ();
-
-   type Build_Type is ("Debug", "Normal");
-   Build : Build_Type := External ("Standard_Common_Build", "Normal");
-
-   type Profile_Type is ("On", "Off");
-   Profile : Profile_Type := External ("Standard_Common_Profile", "Off");
-
-   type Mem_Check_Type is ("On", "Off");
-   Mem_Check : Profile_Type := External ("Standard_Common_Mem_Check", "Off");
-   --  Note that Mem_Check requires Build_Type = Debug to be useful
-
-   -- In main project file, add:
-   -- case Standard_Common.Mem_Check is
-   -- when "On" =>
-   --    for Runtime ("Ada") use "adalib_debug";
-   -- when "Off" =>
-   --    null;
-   -- end case;
-
-   package Compiler is
-      -- Switches for gcc
-
-      Base_Style_Checks := "-gnaty3abcefhiklnOprtx";
-      Line_Length := "-gnatyM120";
-
-      Style_Checks := (Base_Style_Checks, Line_Length);
-
-      Common_Switches :=
-        (
-         "-fstack-check",
-         "-g",
-         "-gnat2012",
-         "-gnatfqQ", -- f = all error messages, qQ = process semantics, 
generate .ali if syntax errors
-         "-gnatw.d", -- warnings about tags
-         "-gnatwaBCeJL", -- wa = most warnings, wB = no warn on bad fixed 
values, wC = no warn on conditionals
-                         -- we = error on warning, wJ = no warn on 
obsolescent, wL = no warn on elaboration
-         "-gnatyO" -- warn on overriding
-        );
-
-      --  -gnatVa causes some inline procedures to be non-inlineable;
-      --  suppress that warning with -gnatwP.
-      Debug_Switches := Common_Switches &
-        (
-         "-O0", --  we don't use -Og because that causes gdb to report 
incorrect results in some cases in Ada.
-         "-gnata",  -- assertions, pre/post-conditions
-         "-gnatVa", -- validity checks
-         "-gnateE", -- extra info in exceptions
-         "-gnatwaP" -- no warn on Inline
-        );
-
-      --  -O3 is measurably faster than -O2 for wisitoken generate
-      --  LR1. We include -fstack-check because it catches
-      --  hard-to-find bugs, and the processors are so fast.
-      --  -fno-var-tracking-assignments speeds compiling of large
-      --  files; var tracking is only useful for debugging.
-      Base_Release_Switches := Common_Switches &
-        (
-         "-O3",
-         "-fno-var-tracking-assignments",
-         "-gnatyO"
-        );
-
-      Inlining := ("-gnatn");
-
-      Release_Switches := Base_Release_Switches & Inlining;
-
-      -- No -ansi; GNAT 7.1 compiler C header files are mingw 64, which don't 
support -ansi
-      Debug_Switches_C := ("-Wall", "-Wstrict-prototypes", "-pedantic", 
"-Werror", "-g", "-O0", "-funwind-tables");
-      Debug_Switches_C_Non_Pedantic := ("-Wall", "-Wstrict-prototypes", 
"-Werror", "-g", "-O0", "-funwind-tables");
-      Release_Switches_C := ("-Wall", "-Wstrict-prototypes", "-pedantic", 
"-Werror", "-g", "-O2", "-funwind-tables");
-      Release_Switches_C_Non_Pedantic := ("-Wall", "-Wstrict-prototypes", 
"-Werror", "-g", "-O2", "-funwind-tables");
-
-   end Compiler;
-
-   --  In project files, normally use this:
-   --  package Compiler is
-   --  for Default_Switches ("Ada") use
-   --     Standard_Common.Compiler.Release_Switches &
-   --     Standard_Common.Compiler.Style_Checks;
-   --  end Compiler;
-
-   package Builder is
-      --  Switches for gnatmake
-      for Default_Switches ("Ada") use ("-C");
-
-      case Profile is
-      when "On" =>
-         for Global_Compilation_Switches ("Ada") use ("-pg");
-      when "Off" =>
-         null;
-      end case;
-   end Builder;
-
-   --  In project files, normally use this:
-   --  package Builder is
-   --     for Default_Switches ("Ada") use 
Standard_Common.Builder'Default_Switches ("Ada");
-   --  end Builder;
-
-   package Binder is
-      --  Switches for gnatbind
-      for Default_Switches ("Ada") use ("-E");
-
-      Debug_Configuration_Pragmas := "Normalize_Scalars";
-   end Binder;
-
-   --  In project files, normally use this:
-   --  package Binder is
-   --     for Default_Switches ("Ada") use 
Standard_Common.Binder'Default_Switches ("Ada");
-   --  end Binder;
-
-   package Linker is
-      case Profile is
-      when "On" =>
-         case Mem_Check is
-         when "On" =>
-            for Linker_Options use ("-pg", "-lgmem");
-         when "Off" =>
-            for Linker_Options use ("-pg");
-         end case;
-
-      when "Off" =>
-         case Mem_Check is
-         when "On" =>
-            for Linker_Options use ("-lgmem");
-         when "Off" =>
-            null;
-         end case;
-      end case;
-   end Linker;
-
-   --  In project files, no linker package is needed.
-end Standard_Common;
diff --git a/packages/wisi/wisi-fringe.el b/packages/wisi/wisi-fringe.el
deleted file mode 100644
index 2194b09..0000000
--- a/packages/wisi/wisi-fringe.el
+++ /dev/null
@@ -1,152 +0,0 @@
-;;; wisi-fringe.el --- show approximate error locations in the fringe
-;;
-;; Copyright (C) 2018 - 2019  Free Software Foundation, Inc.
-;;
-;; This file is part of GNU Emacs.
-;;
-;; GNU Emacs 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 3 of the License, or
-;; (at your option) any later version.
-;;
-;; GNU Emacs 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 GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.
-;;
-;; Design:
-;;
-;; Bitmaps are displayed in the fringe by putting a 'display property
-;; on buffer text. However, just doing that also hides the buffer
-;; text. To avoid that, we put the ’display property on a string, and
-;; then an overlay containing that string as ’before-string or
-;; ’after-string on the newline of a buffer line.
-;;
-;; We show approximate error positions in the entire buffer with
-;; single-pixel lines in the right fringe, and mark error lines with
-;; ’!!’ in the left fringe.
-
-(defun wisi-fringe-create-bitmaps ()
-  "Return an array of bitmap symbols containing the fringe bitmaps."
-  ;; First create the ’!!’ bitmap.
-  (define-fringe-bitmap 'wisi-fringe--double-exclaim-bmp
-    (vector
-     #b00000000
-     #b01100110
-     #b01100110
-     #b01100110
-     #b01100110
-     #b01100110
-     #b00000000
-     #b01100110
-     #b01010110
-     #b00000000))
-
-  ;; In condensing the entire buffer to the current window height, we
-  ;; assume a 10 point font, which allows 6 distinct line positions
-  ;; each one pixel high, with one blank pixel between.
-
-  (let ((result (make-vector 64 nil))
-       (i 1))
-    (while (<= i (length result))
-      (aset result (1- i)
-           (define-fringe-bitmap (intern (format "wisi-fringe--line-%d-bmp" i))
-             (vector
-              (if (>= i 32) #b11111111 #b00000000)
-              #b00000000
-              (if (>= (% i 32) 16) #b11111111 #b00000000)
-              #b00000000
-              (if (>= (% i 16) 8) #b11111111 #b00000000)
-              #b00000000
-              (if (>= (% i 8) 4) #b11111111 #b00000000)
-              #b00000000
-              (if (>= (% i 4) 2) #b11111111 #b00000000)
-              #b00000000
-              (if (>= (% i 2) 1) #b11111111 #b00000000)
-              )))
-      (setq i (1+ i)))
-    result))
-
-(defconst wisi-fringe-bitmaps (wisi-fringe-create-bitmaps)
-  "Array of 64 bitmap symbols.")
-
-(defun wisi-fringe--put-right (line bitmap-index)
-  (save-excursion
-    (goto-char (point-min))
-    (forward-line (1- line))
-    (let* ((endpos (line-end-position))
-          (ov (make-overlay endpos (1+ endpos)))
-          (bmp (aref wisi-fringe-bitmaps bitmap-index)))
-      (overlay-put ov 'after-string (propertize "-" 'display (list 
'right-fringe bmp 'compilation-error)))
-      (overlay-put ov 'wisi-fringe t)
-      )))
-
-(defun wisi-fringe--put-left (line)
-  (save-excursion
-    (goto-char (point-min))
-    (forward-line (1- line))
-    (let* ((endpos (line-end-position))
-          (ov (make-overlay endpos (1+ endpos)))
-          (bmp 'wisi-fringe--double-exclaim-bmp))
-      (overlay-put ov 'before-string (propertize "-" 'display (list 
'left-fringe bmp 'compilation-error)))
-      (overlay-put ov 'wisi-fringe t)
-      )))
-
-(defun wisi-fringe--scale (error-line buffer-lines window-line-first 
window-lines)
-  "Return a cons (LINE . BIN) for ERROR-LINE,
-where LINE is the line to display the error bar on, and BIN is a
-6-bit bit vector giving the relative position in that line.
-BUFFER-LINES is the count of lines in the buffer.
-WINDOW-LINE-FIRST is the first and last lines of the buffer
-visible in the window. WINDOW-LINES is the count of lines visible
-in the window."
-  ;; If the end of buffer is inside the window, and this calculation
-  ;; puts a mark after that, it will actually be put on the last real
-  ;; line. That’s good enough for our purposes.
-
-  ;; partial-lines / window-line = 6
-  ;; buffer-lines / window-line = 1/scale
-  ;; buffer-lines / partial-line  = (window-line / partial-lines) * 
(buffer-lines / window-line) = 1/6 * 1/scale
-  (let* ((scale (/ window-lines (float buffer-lines)))
-        (line (floor (* scale error-line)))
-        (rem (- error-line (floor (/ line scale)))))
-    (cons (+ window-line-first line) (lsh 1 (min 5 (floor (* rem (* 6 
scale))))))))
-
-(defun wisi-fringe-clean ()
-  "Remove all wisi-fringe marks."
-  (remove-overlays (point-min) (point-max) 'wisi-fringe t))
-
-(defun wisi-fringe-display-errors (positions)
-  "Display markers in the left and right fringe for each buffer position in 
POSITIONS.
-The buffer containing POSITIONS must be current, and the window
-displaying that buffer must be current."
-  ;; We don't recompute fringe display on scroll, because the user
-  ;; will probably have edited the code by then, triggering a new
-  ;; parse.
-  (wisi-fringe-clean)
-  (let (scaled-posns
-       (buffer-lines (line-number-at-pos (point-max)))
-       (window-lines (window-height))
-       (window-pos-first (window-start))
-       (window-pos-last  (window-end))
-       (window-line-first (line-number-at-pos (window-start))))
-    (dolist (pos positions)
-      (let* ((line (line-number-at-pos pos))
-            (scaled-pos (wisi-fringe--scale line buffer-lines 
window-line-first window-lines)))
-       (when (and (>= pos window-pos-first)
-                  (<= pos window-pos-last))
-         (wisi-fringe--put-left line))
-       (if (and scaled-posns
-                (= (caar scaled-posns) (car scaled-pos)))
-           (setcdr (car scaled-posns) (logior (cdar scaled-posns) (cdr 
scaled-pos)))
-         (push scaled-pos scaled-posns))
-       ))
-
-    (dolist (pos scaled-posns)
-      (wisi-fringe--put-right (car pos) (1- (cdr pos))))
-    ))
-
-(provide 'wisi-fringe)
diff --git a/packages/wisi/wisi-parse-common.el 
b/packages/wisi/wisi-parse-common.el
deleted file mode 100644
index 2140b50..0000000
--- a/packages/wisi/wisi-parse-common.el
+++ /dev/null
@@ -1,403 +0,0 @@
-;;; wisi-parse-common.el --- declarations used by wisi-parse.el, 
wisi-ada-parse.el, and wisi.el -*- lexical-binding:t -*-
-;;
-;; Copyright (C) 2014, 2015, 2017 - 2019  Free Software Foundation, Inc.
-;;
-;; Author: Stephen Leake <stephen_leake@member.fsf.org>
-;;
-;; This file is part of GNU Emacs.
-;;
-;; GNU Emacs 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 3 of the License, or
-;; (at your option) any later version.
-;;
-;; GNU Emacs 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 GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.
-
-;;; Code:
-
-(defcustom wisi-partial-parse-threshold 100001
-  "Minimum size that will be parsed by each call to the parser.
-A parse is always requested at a point (or on a region); the
-point is first expanded to a start point before the region and an
-end point after the region, that the parser can gracefully
-handle. If the final region covers the entire buffer, a complete
-parse is done. Indent assumes the start point of the parse region
-is properly indented. Most navigate parses ignore this setting
-and parse the whole buffer."
-  :type 'integer
-  :group 'wisi
-  :safe 'integerp)
-(make-variable-buffer-local 'wisi-partial-parse-threshold)
-
-(cl-defstruct (wisi--lexer-error)
-  pos ;; position (integer) in buffer where error was detected.
-  message  ;; string error message
-  inserted ;; char inserted after pos.
-  )
-
-(cl-defstruct (wisi--parse-error-repair)
-  pos ;; position (integer) in buffer where insert/delete is done.
-  inserted ;; list of token IDs that were inserted before pos
-  deleted  ;; list of token IDs that were deleted after pos
-  deleted-region ;; buffer (cons FIRST LAST) region deleted
-  )
-
-(cl-defstruct (wisi--parse-error)
-  ;; Includes information derived from compiler error recovery to edit
-  ;; text to fix one error. Used by ’wisi-repair-error’ to edit buffer.
-  pos      ;; position (integer or marker) in buffer where error was detected.
-  message  ;; string error message
-  repair   ;; list of wisi--parse-error-repair.
-  )
-
-(cl-defstruct wisi-parser
-  ;; Separate lists for lexer and parse errors, because lexer errors
-  ;; must be repaired first, before parse errors can be repaired. And
-  ;; they have different structures.
-  lexer-errors
-  ;; list of wisi--lexer-errors from last parse.  Can be more than one if
-  ;; lexer supports error recovery.
-  parse-errors
-  ;; List of wisi--parse-errors from last parse. Can be more than one if
-  ;; parser supports error recovery.
-
-  repair-image
-  ;; alist of (TOKEN-ID . STRING); used by repair error
-)
-
-(cl-defgeneric wisi-parse-format-language-options ((parser wisi-parser))
-  "Return a string to be sent to the parser, containing settings
-for the language-specific parser options."
-  )
-
-(cl-defgeneric wisi-parse-expand-region ((_parser wisi-parser) begin end)
-  "Return a cons SEND-BEGIN . SEND-END that is an expansion of
-region BEGIN END that starts and ends at points the parser can
-handle gracefully."
-  (cons begin end))
-
-(defvar-local wisi--parser nil
-  "The current wisi parser; a ‘wisi-parser’ object.")
-
-(defun wisi-read-parse-action ()
-  "Read a parse action symbol from the minibuffer."
-  (intern-soft (completing-read "parse action (indent): " '(face navigate 
indent) nil t nil nil 'indent)))
-
-(defun wisi-search-backward-skip (regexp skip-p)
-  "Search backward for REGEXP. If SKIP-P returns non-nil, search again.
-SKIP-P is a function taking no parameters.
-Return nil if no match found before bob."
-  (let ((maybe-found-p (search-backward-regexp regexp nil t)))
-    (while (and maybe-found-p
-               (funcall skip-p)
-               (setq maybe-found-p (search-backward-regexp regexp nil t))))
-    maybe-found-p))
-
-(defun wisi-search-forward-skip (regexp skip-p)
-  "Search forward for REGEXP. If SKIP-P returns non-nil, search again.
-SKIP-P is a function taking no parameters.
-Return nil if no match found before eob."
-  (let ((maybe-found-p (search-forward-regexp regexp nil t)))
-    (while (and maybe-found-p
-               (funcall skip-p)
-               (setq maybe-found-p (search-forward-regexp regexp nil t))))
-    maybe-found-p))
-
-(defun wisi-show-expanded-region ()
-  "For debugging. Expand currently selected region."
-  (interactive)
-  (let ((region (wisi-parse-expand-region wisi--parser (region-beginning) 
(region-end))))
-    (message "pre (%d . %d) post %s" (region-beginning) (region-end) region)
-    (set-mark (car region))
-    (goto-char (cdr region))
-    ))
-
-(cl-defgeneric wisi-parse-adjust-indent ((_parser wisi-parser) indent _repair)
-  "Adjust INDENT for REPAIR (a wisi--parse-error-repair struct). Return new 
indent."
-  indent)
-
-(cl-defgeneric wisi-parse-current ((parser wisi-parser) begin send-end 
parse-end)
-  "Parse current buffer starting at BEGIN, continuing at least thru PARSE-END.
-If using an external parser, send it BEGIN thru SEND-END.")
-
-(cl-defgeneric wisi-refactor ((parser wisi-parser) refactor-action parse-begin 
parse-end edit-begin)
-  "Send parser command to perform REFACTOR-ACTION on region PARSE-BEGIN 
PARSE-END at point EDIT_BEGIN.
-The parse region is not expanded first; it must be the statement
-or declaration containing EDIT_BEGIN.")
-
-(cl-defgeneric wisi-parse-kill ((parser wisi-parser))
-  "Kill any external process associated with parser.")
-
-(cl-defgeneric wisi-parse-find-token ((parser wisi-parser) token-symbol)
-  "Find token with TOKEN-SYMBOL on current parser stack, return token struct.
-For use in grammar actions.")
-
-(cl-defgeneric wisi-parse-stack-peek ((parser wisi-parser) n)
-  "Return the Nth token on the parse stack.
-For use in grammar actions.")
-
-(cl-defstruct
-  (wisi-cache
-   (:constructor wisi-cache-create)
-   (:copier nil))
-  nonterm;; nonterminal from parse
-
-  token
-  ;; terminal symbol from wisi-keyword-table or
-  ;; wisi-punctuation-table, or lower-level nonterminal from parse
-
-  last ;; pos of last char in token, relative to first (0 indexed)
-
-  class ;; one of wisi-class-list
-
-  containing
-  ;; Marker at the start of the containing statement for this token.
-  ;; nil for outermost containing.
-
-  prev ;; marker at previous motion token in statement; nil if none
-  next ;; marker at next motion token in statement; nil if none
-  end  ;; marker at token at end of current statement
-  )
-
-(defun wisi-get-cache (pos)
-  "Return `wisi-cache' struct from the `wisi-cache' text property at POS."
-  (get-text-property pos 'wisi-cache))
-
-(defun wisi-backward-cache ()
-  "Move point backward to the beginning of the first token preceding point 
that has a cache.
-Returns cache, or nil if at beginning of buffer."
-  ;; If point is not near cache, p-s-p-c will return pos just after
-  ;; cache, so 1- is the beginning of cache.
-  ;;
-  ;; If point is just after end of cache, p-s-p-c will return pos at
-  ;; start of cache.
-  ;;
-  ;; So we test for the property before subtracting 1.
-  (let ((pos (previous-single-property-change (point) 'wisi-cache))
-       cache)
-    (cond
-     ((null pos)
-      (goto-char (point-min))
-      nil)
-
-     ((setq cache (get-text-property pos 'wisi-cache))
-      (goto-char pos)
-      cache)
-
-     (t
-      (setq pos (1- pos))
-      (setq cache (get-text-property pos 'wisi-cache))
-      (goto-char pos)
-      cache)
-     )))
-
-(defun wisi-forward-cache ()
-  "Move point forward to the beginning of the first token after point that has 
a cache.
-Returns cache, or nil if at end of buffer."
-  (let (cache pos)
-    (when (get-text-property (point) 'wisi-cache)
-      ;; on a cache; get past it
-      (goto-char (1+ (point))))
-
-    (setq cache (get-text-property (point) 'wisi-cache))
-    (if cache
-       nil
-
-      (setq pos (next-single-property-change (point) 'wisi-cache))
-      (if pos
-         (progn
-           (goto-char pos)
-           (setq cache (get-text-property pos 'wisi-cache)))
-       ;; at eob
-       (goto-char (point-max))
-       (setq cache nil))
-      )
-    cache
-    ))
-
-(defun wisi-cache-region (cache &optional start)
-  "Return region designated by START (default point) to cache last."
-  (unless start (setq start (point)))
-  (cons start (+ start (wisi-cache-last cache))))
-
-(defvar wisi-debug 0
-  "wisi debug mode:
-0 : normal - ignore parse errors, for indenting new code
-1 : report parse errors (for running tests)
-2 : show parse states, position point at parse errors
-3 : also show top 10 items of parser stack.")
-
-;; The following parameters are easily changeable for debugging.
-(defvar wisi-action-disable nil
-  "If non-nil, disable all elisp actions during parsing.
-Allows timing parse separate from actions.")
-
-(defvar-local wisi-trace-mckenzie 0
-  "McKenzie trace level; 0 for none")
-
-(defvar-local wisi-trace-action 0
-  "Parse action trace level; 0 for none")
-
-(defvar-local wisi-mckenzie-disable nil
-  "If non-nil, disable McKenzie error recovery. Otherwise, use parser 
default.")
-
-(defcustom wisi-mckenzie-task-count nil
-  "If integer, sets McKenzie error recovery task count.
-Higher value (up to system processor limit) runs error recovery
-faster, but may encounter race conditions.  Using only one task
-makes error recovery repeatable; useful for tests.  If nil, uses
-value from grammar file."
-  :type 'integer
-  :group 'wisi
-  :safe 'integerp)
-(make-variable-buffer-local 'wisi-mckenzie-task-count)
-
-(defcustom wisi-mckenzie-check-limit nil
-  "If integer, sets McKenzie error recovery algorithm token check limit.
-This sets the number of tokens past the error point that must be
-parsed successfully for a solution to be deemed successful.
-Higher value gives better solutions, but may fail if there are
-two errors close together.  If nil, uses value from grammar
-file."
-  :type 'integer
-  :group 'wisi
-  :safe 'integerp)
-(make-variable-buffer-local 'wisi-mckenzie-check-limit)
-
-(defcustom wisi-mckenzie-enqueue-limit nil
-  "If integer, sets McKenzie error recovery algorithm enqueue limit.
-This sets the maximum number of solutions that will be considered.
-Higher value has more recover power, but will be slower to fail.
-If nil, uses value from grammar file."
-  :type 'integer
-  :group 'wisi
-  :safe 'integerp)
-(make-variable-buffer-local 'wisi-mckenzie-enqueue-limit)
-
-(defcustom wisi-parse-max-parallel 15
-  "Maximum number of parallel parsers during regular parsing.
-Parallel parsers are used to resolve redundancy in the grammar.
-If a file needs more than this, it's probably an indication that
-the grammar is excessively redundant."
-  :type 'integer
-  :group 'wisi
-  :safe 'integerp)
-
-(defvar wisi-parse-max-stack-size 500
-  "Maximum parse stack size.
-Larger stack size allows more deeply nested constructs.")
-;; end of easily changeable parameters
-
-(defvar wisi--parse-action nil
-  ;; not buffer-local; only let-bound in wisi-indent-region, 
wisi-validate-cache
-  "Reason current parse is begin run; one of
-{indent, face, navigate}.")
-
-(defvar-local wisi-indent-comment-col-0 nil
-  "If non-nil, comments currently starting in column 0 are left in column 0.
-Otherwise, they are indented with previous comments or code.
-Normally set from a language-specific option.")
-
-(defvar-local wisi-end-caches nil
-  "List of buffer positions of caches in current statement that need 
wisi-cache-end set.")
-
-(defconst wisi-eoi-term 'Wisi_EOI
-  ;; must match FastToken wisi-output_elisp.adb EOI_Name, which must
-  ;; be part of a valid Ada identifer.
-  "End Of Input token.")
-
-(defconst wisi-class-list
-  [motion ;; motion-action
-   statement-end
-   statement-override
-   statement-start
-   misc ;; other stuff
-   ]
-  "array of valid token classes; checked in wisi-statement-action, used in 
wisi-process-parse.")
-
-(defun wisi-error-msg (message &rest args)
-  (let ((line (line-number-at-pos))
-       (col (- (point) (line-beginning-position))))
-    (format
-     "%s:%d:%d: %s"
-       (buffer-name) ;; buffer-file-name is sometimes nil here!?
-       line col
-       (apply 'format message args))))
-
-(defvar wisi-parse-error nil)
-(put 'wisi-parse-error
-     'error-conditions
-     '(error wisi-parse-error))
-(put 'wisi-parse-error
-     'error-message
-     "wisi parse error")
-
-(cl-defstruct wisi-tok
-  token  ;; symbol from a token table ;; IMPROVEME: rename to ’id’?
-  region ;; cons giving buffer region containing token text
-
-  nonterminal ;; t if a nonterminal
-
-  line ;; Line number at start of token. Nil for empty nonterminals
-
-  first
-  ;; For terminals, t if token is the first token on a line.
-  ;;
-  ;; For nonterminals, line number of first contained line (not
-  ;; including trailing comments) that needs indenting; it is a
-  ;; comment, or begins with a contained token.
-  ;;
-  ;; Otherwise nil.
-
-  ;; The following are non-nil if token (terminal or non-terminal) is
-  ;; followed by blank or comment lines
-  comment-line ;; first blank or comment line following token
-  comment-end ;; position at end of blank or comment lines
-  )
-
-(defun wisi-token-text (token)
-  "Return buffer text from token range."
-  (let ((region (wisi-tok-region token)))
-    (and region
-       (buffer-substring-no-properties (car region) (cdr region)))))
-
-(defun wisi-and-regions (left right)
-  "Return region enclosing both LEFT and RIGHT."
-  (if left
-      (if right
-         (cons (min (car left) (car right))
-               (max (cdr left) (cdr right)))
-       left)
-    right))
-
-(defun wisi--set-line-begin (line-count)
-  "Return a vector of line-beginning positions, with length LINE-COUNT."
-  (let ((result (make-vector line-count 0)))
-    (save-excursion
-      (goto-char (point-min))
-
-      (dotimes (i line-count)
-       (aset result i (point))
-       (forward-line 1)))
-    result))
-
-;;;; debugging
-(defun wisi-tok-debug-image (tok)
-  "Return id and region from TOK, as string."
-  (cond
-   ((wisi-tok-region tok)
-    (format "(%s %d . %d)"
-           (wisi-tok-token tok)
-           (car (wisi-tok-region tok))
-           (cdr (wisi-tok-region tok))))
-   (t
-    (format "(%s)" (wisi-tok-token tok)))
-   ))
-
-(provide 'wisi-parse-common)
diff --git a/packages/wisi/wisi-prj.el b/packages/wisi/wisi-prj.el
deleted file mode 100644
index 501c09f..0000000
--- a/packages/wisi/wisi-prj.el
+++ /dev/null
@@ -1,1614 +0,0 @@
-;;; wisi-prj.el --- project integration -*- lexical-binding:t -*-
-;;
-;; Copyright (C) 2019 - 2020  Free Software Foundation, Inc.
-;;
-;; Author: Stephen Leake <stephen_leake@member.fsf.org>
-;;
-;; This file is part of GNU Emacs.
-;;
-;; GNU Emacs 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 3 of the License, or
-;; (at your option) any later version.
-;;
-;; GNU Emacs 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 GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.
-
-;;; Usage:
-;;
-;; See wisi.info (compiled from wisi.texi).
-
-;;; Code:
-
-(require 'cl-lib)
-(require 'find-file)
-(require 'wisi)
-
-(cl-defstruct wisi-prj
-  name     ;; A user-friendly string, used in menus and messages.
-
-  compile-env
-  ;; List of strings NAME=VALUE for `compilation-environment'; used
-  ;; when running the compiler or makefile. Also prepended to
-  ;; `process-environment' when the project file is parsed, or when
-  ;; the project file is used by a tool in an external process.
-
-  file-env
-  ;; Environment (list of strings NAME=VALUE) set in project file;
-  ;; prepended to `process-environment' running tools in an external
-  ;; process.
-
-  compiler
-  xref
-  ;; xref functionality is often provided by the compiler. We allow
-  ;; for separate compiler and xref objects, to handle the case where
-  ;; the compiler is a cross-compiler for an embedded target, and xref
-  ;; is provided by a host compiler.
-
-  (case-exception-files nil)
-  ;; List of casing exception files; from `casing' project variable.
-  ;;
-  ;; New exceptions may be added interactively via
-  ;; `wisi-case-create-exception'.  If an exception is defined in
-  ;; multiple files, the first occurence is used.
-  ;;
-  ;; The file format is one word per line, which gives the casing to be
-  ;; used for that word in source code.  If the line starts with
-  ;; the character *, then the exception will be used for partial
-  ;; words that either start at the beginning of a word or after a _
-  ;; character, and end either at the end of the word or at a _
-  ;; character.  Characters after the first word are ignored, and not
-  ;; preserved when the list is written back to the file."
-
-  (case-full-exceptions '())
-  ;; Alist of full words that have special casing, built from
-  ;; case-exception-files. Indexed by properly cased word; value is t.
-
-  (case-partial-exceptions '())
-  ;; Alist of partial words that have special casing, built from
-  ;; project casing files list partial word exceptions. Indexed by
-  ;; properly cased word; value is t.
-
-  source-path ;; list of absolute directory file names
-
-  file-pred
-  ;; Function taking an absolute file name, returns non-nil
-  ;; if the file should be included in `project-files'.
-  )
-
-(defun wisi-prj-require-prj ()
-  "Return current `wisi-prj' object.
-Throw an error if current project is not an wisi-prj."
-  (let ((prj (project-current)))
-    (if (wisi-prj-p prj)
-       prj
-      (error "current project is not a wisi project."))))
-
-(defun wisi-prj-current-prj ()
-  "Return current `wisi-prj' object.
-If (project-current) does not return a wisi-prj, return a default prj."
-  (let ((prj (project-current)))
-    (if (wisi-prj-p prj)
-       prj
-      (make-wisi-prj :name "default"))))
-
-(defvar wisi-prj-file-extensions (list "prj")
-  "List of wisi project file extensions.
-Used when searching for project files.")
-
-(defvar wisi-prj--cache nil
-  "Alist holding currently parsed project objects.
-Indexed by absolute project file name.")
-
-(cl-defgeneric wisi-prj-default (prj)
-  "Return a project with default values.
-Used to reset a project before refreshing it.")
-
-(cl-defgeneric wisi-prj-parse-one (_project _name _value)
-  "If recognized by PROJECT, set NAME, VALUE in PROJECT, return non-nil.
-Else return nil."
-  nil)
-
-(cl-defgeneric wisi-prj-parse-final (_project _prj-file-name)
-  "Do any final processing on PROJECT
-after the project file PRJ-FILE-NAME is parsed."
-  nil)
-
-(cl-defgeneric wisi-prj-select (project)
-  "PROJECT is selected; perform any required actions.")
-
-(cl-defgeneric wisi-prj-deselect (project)
-  "PROJECT is deselected; undo any select actions.")
-
-(cl-defgeneric wisi-prj-refresh-cache (prj not-full)
-  "Reparse the project file for PRJ, refresh all cached data in PRJ.
-If NOT-FULL is non-nil, very slow refresh operations may be skipped.")
-
-(cl-defgeneric wisi-prj-identifier-ignore-case (prj)
-  "Return non-nil if case should be ignored when comparing identifiers.")
-
-;; We provide nil defaults for some methods, because some language
-;; modes don't have a language-specific compiler (eg java-wisi) or
-;; xref process (eg gpr-mode).
-
-(cl-defgeneric wisi-compiler-parse-one (compiler project name value)
-  "Set NAME, VALUE in COMPILER, if recognized by COMPILER.
-PROJECT is an `wisi-prj' object; COMPILER is `wisi-prj-compiler'.")
-
-(cl-defgeneric wisi-compiler-parse-final (_compiler _project _prj-file-name)
-  "Do any compiler-specific processing on COMPILER and PROJECT
-after the project file PRJ-FILE-NAME is parsed."
-  nil)
-
-(cl-defgeneric wisi-compiler-select-prj (_compiler _project)
-  "PROJECT has been selected; do any compiler-specific actions required."
-  nil)
-
-(cl-defgeneric wisi-compiler-deselect-prj (_compiler _project)
-  "PROJECT has been de-selected; undo any compiler-specific select actions."
-  nil)
-
-(cl-defgeneric wisi-compiler-show-prj-path (compiler)
-  "Display buffer listing project file search path.")
-
-(cl-defgeneric wisi-compiler-fix-error (compiler source-buffer)
-  "Attempt to fix a compilation error, return non-nil if fixed.
-Current buffer is compilation buffer; point is at an error message.
-SOURCE-BUFFER contains the source code referenced in the error message.")
-
-(cl-defgeneric wisi-xref-parse-one (_xref _project _name _value)
-  "If recognized by XREF, set NAME, VALUE in XREF, return non-nil.
-Else return nil."
-  nil)
-
-(cl-defgeneric wisi-xref-parse-final (_xref _project _prj-file-name)
-  "Do any xref-specific processing on XREF and PROJECT
-after the project file PRJ-FILE-NAME is parsed."
-  nil)
-
-(cl-defgeneric wisi-xref-select-prj (_xref _project)
-  "PROJECT has been selected; do any xref-specific actions required."
-  nil)
-
-(cl-defgeneric wisi-xref-deselect-prj (_xref _project)
-  "PROJECT has been de-selected; undo any xref-specific select actions."
-  nil)
-
-(cl-defgeneric wisi-xref-refresh-cache (_xref _project _no-full)
-  "Refresh cached information in XREF. If no-full is non-nil,
-slow refresh operations may be skipped."
-  nil)
-
-(cl-defgeneric wisi-xref-completion-table (xref project)
-  "Return a completion table of names defined in PROJECT, for navigating to 
the declarations.
-The table is an alist of (ANNOTATED-SYMBOL . LOC), where:
-
-- ANNOTATED-SYMBOL is the simple name and possibly annotations
-such as function arguments, controlling type, containing package,
-and line number.
-
-- LOC is the declaration of the name as a list (FILE LINE
-COLUMN).")
-
-(cl-defgeneric wisi-xref-completion-delim-regex (xref)
-  "Return the value for `completion-pcm--delim-wild-regex' to be used with 
`wisi-xref-completion-table'.")
-
-(cl-defgeneric wisi-xref-completion-regexp (xref)
-  "Return a regular expression matching the result of completing with 
`wisi-xref-completion-table'.
-Group 1 must be the simple symbol; the rest of the item may be annotations.")
-
-(cl-defgeneric wisi-xref-completion-at-point-table (xref project)
-  "Return a completion table of names defined in PROJECT, for 
`completion-at-point'.
-The table is a simple list of symbols.")
-
-(cl-defgeneric wisi-xref-definitions (xref project item)
-  "Return all definitions (classwide) of ITEM (an xref-item), as a list of 
xref-items.")
-
-(cl-defgeneric wisi-xref-references (xref project item)
-  "Return all references to ITEM (an xref-item), as a list of xref-items.")
-
-(cl-defgeneric wisi-xref-other (project &key identifier filename line column)
-  "Return cross reference information.
-PROJECT - dispatching object, normally a `wisi-prj' object.
-IDENTIFIER - an identifier or operator_symbol
-FILENAME - absolute filename containing the identifier
-LINE - line number containing the identifier (may be nil)
-COLUMN - Emacs column of the start of the identifier (may be nil)
-Point is on the start of the identifier.
-Returns a list (FILE LINE COLUMN) giving the corresponding location;
-FILE is an absolute file name.  If point is at the specification, the
-corresponding location is the
-body, and vice versa.")
-
-(defvar-local wisi-xref-full-path nil
-  "If non-nil, xref functions show full paths in results.")
-
-(defun wisi-goto-source (file line column)
-  "Find and select FILE, at LINE and COLUMN.
-FILE may be absolute, or on `compilation-search-path'.
-LINE, COLUMN are Emacs origin."
-  (let ((file-1
-        (if (file-name-absolute-p file) file
-          (ff-get-file-name compilation-search-path file))))
-    (if file-1
-       (setq file file-1)
-      (error "File %s not found; installed library, or set project?" file))
-    )
-
-  (push-mark (point) t)
-
-  (let ((buffer (get-file-buffer file)))
-    (cond
-     ((bufferp buffer)
-      ;; use pop-to-buffer, so package other-frame-window works.
-      (pop-to-buffer buffer (list #'display-buffer-same-window)))
-
-     ((file-exists-p file)
-      (find-file file))
-
-     (t
-      (error "'%s' not found" file))))
-
-  ;; move the cursor to the correct position
-  (goto-char (point-min))
-  (forward-line (1- line))
-  (forward-char column))
-
-(defun wisi-show-xref (xref)
-  "Display XREF location."
-  (let ((marker (xref-location-marker (xref-item-location xref))))
-    (push-mark)
-    (pop-to-buffer (marker-buffer marker) (list #'display-buffer-same-window))
-    (goto-char (marker-position marker))))
-
-(defun wisi-filter-table (table file)
-  "If FILE is nil, return TABLE. Otherwise return only items in TABLE with 
location FILE."
-  (cond
-   ((null file)
-    table)
-
-   (t
-    (let (result)
-      (dolist (item table)
-       (when (string= file (car (cdr item)))
-         (push item result)))
-      result))))
-
-(defun wisi-get-identifier (prompt)
-  "Get identifier at point, or, if no identifier at point or with user arg, 
prompt for one.
-Single user arg completes on all identifiers in project; double
-user arg limits completion to current file."
-  ;; Similar to xref--read-identifier, but uses a different completion
-  ;; table, because we want a more specific reference.
-  (let* ((prj (project-current))
-         (def (xref-backend-identifier-at-point prj)))
-
-    (cond
-     ((or current-prefix-arg
-          (not def))
-      (let* ((table (wisi-filter-table (wisi-xref-completion-table 
(wisi-prj-xref prj) prj)
-                                      (when (equal '(16) current-prefix-arg) 
(buffer-file-name))))
-            (completion-pcm--delim-wild-regex 
(wisi-xref-completion-delim-regex (wisi-prj-xref prj)))
-            (id
-             ;; Since the user decided not to use the identifier at
-             ;; point, don't use it as the default.
-              (completing-read prompt table nil nil nil 
'xref--read-identifier-history)))
-        (if (equal id "")
-            (user-error "No identifier provided")
-
-         ;; The user may have forced exit from completing-read with a
-         ;; string that is not in the table (because gpr-query is out
-         ;; of date, for example).
-          (or (and (consp (car table)) ;; alist; return key and value.
-                  (assoc id table))
-             id))))
-     (t def))))
-
-(defun wisi-goto-spec/body (identifier)
-  "Goto declaration or body for IDENTIFIER (default symbol at point).
-If no symbol at point, or with prefix arg, prompt for symbol, goto spec."
-  (interactive (list (wisi-get-identifier "Goto spec/body of: ")))
-  (let ((prj (project-current))
-       desired-loc)
-    (cond
-     ((consp identifier)
-      ;; alist element from wisi-xref-completion-table; desired
-      ;; location is primary declaration
-      (setq desired-loc
-           (xref-make (car identifier)
-                      (xref-make-file-location
-                       (nth 0 (cdr identifier)) ;; file
-                       (nth 1 (cdr identifier)) ;; line
-                       (nth 2 (cdr identifier)) ;; column
-                       ))))
-
-     ((stringp identifier)
-      ;; from xref-backend-identifier-at-point; desired location is 'other'
-      (let ((item (wisi-xref-item identifier prj)))
-       (condition-case-unless-debug err
-           (with-slots (summary location) item
-             (let ((eieio-skip-typecheck t))
-               (with-slots (file line column) location
-                 (let ((target
-                        (wisi-xref-other
-                         (wisi-prj-xref prj) prj
-                         :identifier summary
-                         :filename file
-                         :line line
-                         :column column)))
-                   (setq desired-loc
-                         (xref-make summary
-                                    (xref-make-file-location
-                                     (nth 0 target) ;; file
-                                     (nth 1 target) ;; line
-                                     (nth 2 target))) ;; column
-                         )))))
-         (user-error ;; from gpr-query; current file might be new to project, 
so try wisi-names
-          (let ((item (assoc identifier (wisi-names nil t))))
-            (if item
-                (setq desired-loc
-                      (xref-make identifier
-                                 (xref-make-file-location
-                                  (nth 1 item) ;; file
-                                  (nth 2 item) ;; line
-                                  (nth 3 item))))
-              (signal (car err) (cdr err)))))
-         )))
-
-     (t ;; something else
-      (error "unknown case in wisi-goto-spec/body")))
-    (wisi-show-xref desired-loc)
-    ))
-
-(cl-defgeneric wisi-prj-identifier-at-point (_project)
-  "Return (IDENT START END) giving the identifier and its bounds at point.
-Return nil if no identifier is at point."
-  ;; default implementation
-  (let ((bounds (bounds-of-thing-at-point 'symbol)))
-    (when bounds
-      (list (car bounds) (cdr bounds) (buffer-substring-no-properties (car 
bounds) (cdr bounds))))))
-
-(defun wisi-completion-at-point ()
-  "For `completion-at-point-functions'."
-  (let ((prj (project-current)))
-    (when (wisi-prj-p prj)
-      (save-excursion
-       (let ((table (wisi-xref-completion-at-point-table (wisi-prj-xref prj) 
prj))
-             (bounds (wisi-prj-identifier-at-point prj)))
-         (when bounds
-           ;; xref symbol table may be out of date; try dabbrevs
-           (list (nth 0 bounds) (nth 1 bounds) table :exclusive 'no))
-         )))
-    ))
-
-(defun wisi-check-current-project (file-name &optional default-prj-function)
-  "If FILE-NAME (must be absolute) is found in the current
-project source directories, return the current
-project. Otherwise, if the current project is a wisi project,
-throw an error.  If the current project is not a wisi project,
-and DEFAULT-PRJ-FUNCTION is non-nil, use it to return a default
-project. Otherwise throw an error."
-  (let ((visited-file (file-truename file-name)) ;; file-truename handles 
symbolic links
-        (project (project-current)))
-    (if (wisi-prj-p project)
-       (let ((found-file (locate-file (file-name-nondirectory visited-file)
-                                      (wisi-prj-source-path project))))
-         (unless found-file
-           (error "current file not part of current project; wrong project?"))
-
-         (setq found-file (file-truename found-file))
-
-         ;; (nth 10 (file-attributes ...)) is the inode; required when hard
-         ;; links are present.
-         (let* ((visited-file-inode (nth 10 (file-attributes visited-file)))
-                (found-file-inode (nth 10 (file-attributes found-file))))
-           (unless (equal visited-file-inode found-file-inode)
-              (error "%s (opened) and %s (found in project) are two different 
files"
-                    file-name found-file)))
-         project)
-
-      ;; create a project?
-      (if default-prj-function
-         (funcall default-prj-function nil (file-name-directory file-name))
-       (error "current project is not a wisi project."))
-      )))
-
-(cl-defgeneric wisi-xref-parents (xref project &key identifier filename line 
column)
-  "Displays parent type declarations.
-XREF    - dispatching object.
-PROJECT - a `wisi-prj' object.
-IDENTIFIER - an identifier or operator_symbol
-FILENAME - absolute filename containing the identifier
-LINE - line number containing the identifier
-COLUMN - Emacs column of the start of the identifier
-
-Displays a buffer in compilation-mode giving locations of the parent type 
declarations.")
-
-(defun wisi-show-declaration-parents ()
-  "Display the locations of the parent type declarations of the type 
identifier around point."
-  (interactive)
-  (let* ((project (wisi-check-current-project (buffer-file-name)))
-        (id (wisi-prj-identifier-at-point project)))
-    (wisi-xref-parents
-     (wisi-prj-xref project)
-     project
-     :identifier (nth 2 id)
-     :filename (file-name-nondirectory (buffer-file-name))
-     :line (line-number-at-pos)
-     :column (save-excursion (goto-char (nth 0 id)) (current-column)))
-    ))
-
-(cl-defgeneric wisi-xref-all (xref project &key identifier filename line 
column local-only append)
-  "Displays cross reference information.
-XREF    - dispatching object.
-PROJECT - a `wisi-prj' object.
-IDENTIFIER - an identifier or operator_symbol (a string).
-FILENAME - absolute filename containing the identifier
-LINE - line number containing the identifier
-COLUMN - Emacs column of the start of the identifier
-LOCAL-ONLY - if t, show references in FILE only
-APPEND - if t, keep previous output in result buffer
-Displays a buffer in compilation-mode giving locations where the
-identifier is declared or referenced.")
-
-(defun wisi-show-references (&optional append)
-  "Show all references of identifier at point.
-With prefix, keep previous references in output buffer."
-  (interactive "P")
-  (let* ((project (wisi-check-current-project (buffer-file-name)))
-        (id (wisi-prj-identifier-at-point project)))
-    (wisi-xref-all
-     (wisi-prj-xref project)
-     project
-     :identifier (nth 2 id)
-     :filename (file-name-nondirectory (buffer-file-name))
-     :line (line-number-at-pos)
-     :column (save-excursion (goto-char (nth 0 id)) (current-column))
-     :local-only nil
-     :append append)
-    ))
-
-(defun wisi-show-local-references (&optional append)
-  "Show all references of identifier at point occuring in current file.
-With prefix, keep previous references in output buffer."
-  (interactive "P")
-  (let* ((project (wisi-check-current-project (buffer-file-name)))
-        (id (wisi-prj-identifier-at-point project)))
-    (wisi-xref-all
-     (wisi-prj-xref project)
-     project
-     :identifier (nth 2 id)
-     :filename (file-name-nondirectory (buffer-file-name))
-     :line (line-number-at-pos)
-     :column (save-excursion (goto-char (nth 0 id)) (current-column))
-     :local-only t
-     :append append)
-    ))
-
-(cl-defgeneric wisi-xref-overriding (xref project &key identifier filename 
line column)
-  "Displays a buffer in compilation-mode giving locations of the overriding 
declarations.
-XREF    - dispatching object.
-PROJECT - a `wisi-prj' object.
-IDENTIFIER - an identifier or operator_symbol
-FILENAME - filename containing the identifier
-LINE - line number containing the identifier
-COLUMN - Emacs column of the start of the identifier ")
-
-(defun wisi-show-overriding ()
-  "Show all overridings of identifier at point."
-  (interactive)
-  (let* ((project (wisi-check-current-project (buffer-file-name)))
-        (id (wisi-prj-identifier-at-point project)))
-    (wisi-xref-overriding
-     (wisi-prj-xref project)
-     project
-     :identifier (nth 2 id)
-     :filename (file-name-nondirectory (buffer-file-name))
-     :line (line-number-at-pos)
-     :column (save-excursion (goto-char (nth 0 id)) (current-column)))
-    ))
-
-(cl-defgeneric wisi-xref-overridden (xref project &key identifier filename 
line column)
-  "Returns a list (FILE LINE COLUMN) giving the location of the overridden 
declaration.
-XREF    - dispatching object.
-PROJECT - a `wisi-prj' object.
-IDENTIFIER - an identifier or operator_symbol
-FILENAME - absolute filename containing the identifier
-LINE - line number containing the identifier
-COLUMN - Emacs column of the start of the identifier")
-
-(defun wisi-show-overridden ()
-  "Show the overridden declaration of identifier at point."
-  (interactive)
-  (let* ((project (wisi-check-current-project (buffer-file-name)))
-        (id (wisi-prj-identifier-at-point project))
-        (target
-         (wisi-xref-overridden
-          (wisi-prj-xref project)
-          project
-          :identifier (nth 2 id)
-          :filename (file-name-nondirectory (buffer-file-name))
-          :line (line-number-at-pos)
-          :column (save-excursion (goto-char (nth 0 id)) (current-column)))))
-
-    (wisi-goto-source (nth 0 target)
-                     (nth 1 target)
-                     (nth 2 target))
-  ))
-
-;;;; wisi-prj specific methods
-
-(cl-defmethod project-roots ((_project wisi-prj))
-  ;; Not meaningful
-  nil)
-
-(cl-defmethod project-files ((project wisi-prj) &optional dirs)
-  (let (result)
-    (dolist (dir (or dirs
-                    (wisi-prj-source-path project)))
-      (mapc
-       (lambda (absfile)
-        (when (and (not (string-equal "." (substring absfile -1)))
-                   (not (string-equal ".." (substring absfile -2)))
-                   (not (file-directory-p absfile))
-                    (or (null (wisi-prj-file-pred project))
-                       (funcall (wisi-prj-file-pred project) absfile)))
-          (push absfile result)))
-       (when (file-readable-p dir) ;; GNAT puts non-existing dirs on path.
-        (directory-files dir t))))
-    result))
-
-(defun wisi-refresh-prj-cache (not-full)
-  "Refresh all cached data in the current project, and re-select it.
-With prefix arg, very slow refresh operations may be skipped."
-  (interactive "P")
-  (let ((prj (project-current)))
-    (unless (wisi-prj-p prj)
-      (error "current project is not a wisi project"))
-    (wisi-prj-refresh-cache prj not-full)
-    (wisi-prj-select prj)))
-
-(defvar wisi-prj--current-file nil
-  "Current wisi project file (the most recently selected); an
-absolute file name.")
-
-(defun wisi-prj-clear-current ()
-  "Clear the current project selection; make no project current."
-  (interactive)
-  (setq wisi-prj--current-file nil))
-
-(defun wisi-prj-show ()
-  "Show name of current project."
-  (interactive)
-  (message
-   (cond
-    (wisi-prj--current-file
-     (wisi-prj-name (cdr (assoc wisi-prj--current-file wisi-prj--cache))))
-    (t
-     (let ((prj (project-current)))
-       (if (wisi-prj-p prj)
-          (wisi-prj-name prj)
-        "not a wisi project"))))))
-
-(cl-defmethod wisi-prj-parse-final (project _prj-file)
-  (wisi--case-read-all-exceptions project))
-
-(cl-defmethod wisi-prj-refresh-cache ((project wisi-prj) not-full)
-  (when wisi-prj--cache
-    (wisi-prj-deselect project)
-    (let ((prj-file (car (rassoc project wisi-prj--cache))))
-       (setq wisi-prj--cache (delete (cons prj-file project) wisi-prj--cache))
-       (setq project (wisi-prj-default project))
-       (wisi-prj-parse-file :prj-file prj-file :init-prj project :cache t)
-       (wisi-xref-refresh-cache (wisi-prj-xref project) project not-full)
-       (wisi-prj-select project))))
-
-(cl-defmethod wisi-prj-select ((project wisi-prj))
-  (setq compilation-search-path (wisi-prj-source-path project))
-
-  ;; ‘compilation-environment’ is buffer-local, but the user might
-  ;; delete that buffer. So set both global and local.
-  (let ((comp-env
-        (append
-         (wisi-prj-compile-env project)
-         (wisi-prj-file-env project)
-         (copy-sequence (wisi-prj-file-env project))))
-       (comp-buf (get-buffer "*compilation*")))
-    (when (buffer-live-p comp-buf)
-      (with-current-buffer comp-buf
-       (setq compilation-environment comp-env)))
-    (set-default 'compilation-environment comp-env))
-
-  (wisi-compiler-select-prj (wisi-prj-compiler project) project)
-  (wisi-xref-select-prj     (wisi-prj-xref project)     project))
-
-(cl-defmethod wisi-prj-deselect ((project wisi-prj))
-  (wisi-xref-deselect-prj (wisi-prj-xref project) project)
-  (wisi-compiler-deselect-prj (wisi-prj-compiler project) project)
-  (setq compilation-environment nil)
-  (setq compilation-search-path nil))
-
-(defvar wisi-prj-parse-hook nil
-  "Hook run at start of `wisi-prj-parse-file'.")
-
-(defvar wisi-prj-parser-alist (list (cons "prj" #'wisi-prj-parse-file-1))
-  "Alist of parsers for project files, indexed by file extension.
-Parser is called with two arguments; the project file name and
-a project. Parser should update the project with values from the file.")
-
-(cl-defmethod wisi-prj-parse-one (project name value)
-  "If NAME is a wisi-prj slot, set it to VALUE, return t.
-Else return nil."
-  (cond
-   ((string= name "casing")
-    (cl-pushnew (expand-file-name
-                 (substitute-in-file-name value))
-                (wisi-prj-case-exception-files project)
-               :test #'string-equal)
-    t)
-
-   ((string= name "src_dir")
-    (cl-pushnew (directory-file-name (expand-file-name 
(substitute-in-file-name value)))
-                (wisi-prj-source-path project)
-               :test #'string-equal)
-    t)
-
-   ((= ?$ (elt name 0))
-    ;; Process env var.
-    (setf (wisi-prj-file-env project)
-         (cons (concat (substring name 1) "=" (substitute-in-file-name value))
-               (wisi-prj-file-env project)))
-    t)
-
-   ))
-
-(defvar-local wisi-prj-parse-undefined-function nil
-  "Function called if a project file variable name is not recognized.
-Called with three args: PROJECT NAME VALUE.")
-
-(defun wisi-prj-parse-file-1 (prj-file project)
-  "Wisi project file parser."
-  (with-current-buffer (find-file-noselect prj-file)
-    (goto-char (point-min))
-
-    ;; process each line
-    (while (not (eobp))
-
-      ;; ignore lines that don't have the format "name=value", put
-      ;; 'name', 'value' in match-string.
-      (when (looking-at "^\\([^= \n]+\\)=\\(.*\\)")
-       (let ((name (match-string 1))
-             (value (match-string 2))
-             result)
-
-         ;; Both compiler and xref need to see some settings; eg gpr_file, env 
vars.
-         (when (wisi-compiler-parse-one (wisi-prj-compiler project) project 
name value)
-           (setq result t))
-         (when (wisi-xref-parse-one (wisi-prj-xref project) project name value)
-           (setq result t))
-
-         (unless result
-           (setq result (wisi-prj-parse-one project name value)))
-
-         (when (and (not result)
-                    wisi-prj-parse-undefined-function)
-           (funcall wisi-prj-parse-undefined-function project name value))
-
-          ))
-
-      (forward-line 1)
-      )
-    ))
-
-(cl-defun wisi-prj-parse-file (&key prj-file init-prj cache)
-  "Read project file PRJ-FILE with default values from INIT-PRJ.
-PRJ-FILE parser is from `wisi-prj-parser-alist'; if that yields
-no parser, no error occurs; the file is just a placeholder.  If
-CACHE is non-nil, add the project to `wisi-prj--cache'.  In any
-case, return the project."
-  (setq prj-file (expand-file-name prj-file))
-
-  (run-hooks 'wisi-prj-parse-hook)
-
-  (let* ((default-directory (file-name-directory prj-file))
-        (parser (cdr (assoc (file-name-extension prj-file) 
wisi-prj-parser-alist)))
-        (project init-prj)
-        (process-environment (append (wisi-prj-compile-env init-prj) 
process-environment)))
-
-    (when parser
-      ;; If no parser, prj-file is just a placeholder; there is no file to 
parse.
-      ;; For example, sal-android-prj has no project file.
-       (funcall parser prj-file project)
-       (wisi-prj-parse-final project prj-file)
-       (wisi-compiler-parse-final (wisi-prj-compiler project) project prj-file)
-       (wisi-xref-parse-final (wisi-prj-xref project) project prj-file))
-
-    (when cache
-      ;; Cache the project properties
-      (if (assoc prj-file wisi-prj--cache)
-         (setcdr (assoc prj-file wisi-prj--cache) project)
-       (push (cons prj-file project) wisi-prj--cache)))
-
-    project))
-
-(defun wisi-prj-show-prj-path ()
-  "Show the compiler project file search path."
-  (interactive)
-  (wisi-compiler-show-prj-path (wisi-prj-compiler (wisi-prj-require-prj))))
-
-(defun wisi-prj-show-src-path ()
-  "Show the project source file search path."
-  (interactive)
-  (if compilation-search-path
-      (progn
-       (pop-to-buffer (get-buffer-create "*source file search path*"))
-       (erase-buffer)
-       (dolist (file compilation-search-path)
-         (insert (format "%s\n" file))))
-    (message "no source file search path set")
-    ))
-
-(defun wisi-fix-compiler-error ()
-  "Attempt to fix the current compiler error.
-Point must be at the source location referenced in a compiler error.
-In `compilation-last-buffer', point must be at the compiler error.
-Leave point at fixed code."
-  (interactive)
-  (let ((source-buffer (current-buffer))
-       (line-move-visual nil)); screws up next-line otherwise
-
-    (cond
-     ((equal compilation-last-buffer wisi-error-buffer)
-      (set-buffer source-buffer)
-      (wisi-repair-error))
-
-     (t
-      (with-current-buffer compilation-last-buffer
-       (let ((comp-buf-pt (point))
-             (success
-              (wisi-compiler-fix-error
-               (wisi-prj-compiler (wisi-prj-require-prj))
-               source-buffer)))
-         ;; restore compilation buffer point
-         (set-buffer compilation-last-buffer)
-         (goto-char comp-buf-pt)
-
-         (unless success
-           (error "error not recognized"))
-         )))
-      )))
-
-;;;; auto-casing
-
-(defvar-local wisi-auto-case nil
-  "Buffer-local value indicating whether to change case while typing.
-When non-nil, automatically change case of preceding word while
-typing.  Casing of keywords is done according to
-`wisi-case-keyword', identifiers according to
-`wisi-case-identifier'."
-  ;; This is not a defcustom, because it's buffer-local.
-  )
-
-(defvar-local wisi-case-keyword 'lower-case
-  "Indicates how to adjust the case of `wisi-keywords'.
-Value is one of lower-case, upper-case."
-  ;; This is not a defcustom, because it's buffer-local
-  )
-
-(defvar-local wisi-case-identifier 'mixed-case
-  "Buffer-local value indicating how to case language keywords.
-Value is one of:
-
-- mixed-case : Mixed_Case
-- lower-case : lower_case
-- upper-case : UPPER_CASE")
-
-(defvar-local wisi-case-strict t
-  "If nil, preserve uppercase chars in identifiers.")
-
-(defvar-local wisi-language-keywords nil
-  "List of keywords for auto-case.")
-
-(defvar-local wisi-case-adjust-p-function nil
-  "Function taking one argument, the typed char; called from wisi-case-adjust.
-Return non-nil if case of symbol at point should be adjusted.
-Point is on last char of symbol.")
-
-(defun wisi-case-show-files ()
-  "Show casing files list for the current project."
-  (interactive)
-  (let ((project (project-current)))
-
-    (if (and (wisi-prj-p project)
-            (wisi-prj-case-exception-files project))
-       (progn
-         (pop-to-buffer (get-buffer-create "*casing files*"))
-         (erase-buffer)
-         (dolist (file (wisi-prj-case-exception-files project))
-           (insert (format "%s\n" file))))
-      (message "no casing files")
-      )))
-
-(defun wisi--case-save-exceptions (full-exceptions partial-exceptions 
file-name)
-  "Save FULL-EXCEPTIONS, PARTIAL-EXCEPTIONS to the file FILE-NAME."
-  ;; If there is a buffer visiting file-name, it may be out of date
-  ;; due to a previous save-exceptions, which will give a user prompt
-  ;; about editing a file that has changed on disk. Update the buffer
-  (let ((buf (get-file-buffer file-name)))
-    (when buf
-      (with-current-buffer buf
-                       (revert-buffer nil t t))))
-
-  (with-temp-file (expand-file-name file-name)
-    (mapc (lambda (x) (insert (car x) "\n"))
-         (sort (copy-sequence full-exceptions)
-               (lambda(a b) (string< (car a) (car b)))))
-    (mapc (lambda (x) (insert "*" (car x) "\n"))
-         (sort (copy-sequence partial-exceptions)
-               (lambda(a b) (string< (car a) (car b)))))
-    ))
-
-(defun wisi--case-read-exceptions (file-name)
-  "Read the content of the casing exception file FILE-NAME.
-Return (cons full-exceptions partial-exceptions)."
-  (setq file-name (expand-file-name (substitute-in-file-name file-name)))
-  (if (file-readable-p file-name)
-      (let (full-exceptions partial-exceptions word)
-       (with-temp-buffer
-         (insert-file-contents file-name)
-         (while (not (eobp))
-
-           (setq word (buffer-substring-no-properties
-                       (point) (save-excursion (skip-syntax-forward "w_") 
(point))))
-
-           (if (char-equal (string-to-char word) ?*)
-               ;; partial word exception
-               (progn
-                 (setq word (substring word 1))
-                 (unless (assoc-string word partial-exceptions t)
-                   (push (cons word t) partial-exceptions)))
-
-             ;; full word exception
-             (unless (assoc-string word full-exceptions t)
-               (push (cons word t) full-exceptions)))
-
-           (forward-line 1))
-         )
-       (cons full-exceptions partial-exceptions))
-
-    ;; else file not readable; might be a new project with no
-    ;; exceptions yet, so just return empty pair
-    (message "'%s' is not a readable file." file-name)
-    '(nil . nil)
-    ))
-
-(defun wisi--case-merge-exceptions (result new)
-  "Merge NEW exeptions into RESULT.
-An item in both lists has the RESULT value."
-  (dolist (item new)
-    (unless (assoc-string (car item) result t)
-      (push item result)))
-  result)
-
-(defun wisi--case-merge-all-exceptions (exceptions project)
-  "Merge EXCEPTIONS into PROJECT case-full-exceptions, 
case-partial-exceptions."
-  (setf (wisi-prj-case-full-exceptions project)
-       (wisi--case-merge-exceptions (wisi-prj-case-full-exceptions project)
-                                    (car exceptions)))
-  (setf (wisi-prj-case-partial-exceptions project)
-       (wisi--case-merge-exceptions (wisi-prj-case-partial-exceptions project)
-                                    (cdr exceptions))))
-
-(defun wisi--case-read-all-exceptions (project)
-  "Read case exceptions from all files in PROJECT casing files."
-  (setf (wisi-prj-case-full-exceptions project) '())
-  (setf (wisi-prj-case-partial-exceptions project) '())
-
-  (dolist (file (wisi-prj-case-exception-files project))
-    (wisi--case-merge-all-exceptions (wisi--case-read-exceptions file) 
project)))
-
-(defun wisi--case-add-exception (word exceptions)
-  "Add case exception WORD to EXCEPTIONS, replacing current entry, if any."
-  (if (assoc-string word exceptions t)
-      (setcar (assoc-string word exceptions t) word)
-    (push (cons word t) exceptions))
-  exceptions)
-
-(defun wisi-case-create-exception (&optional partial)
-  "Define a word as an auto-casing exception in the current project.
-The word is the active region, or the symbol at point.  If
-PARTIAL is non-nil, create a partial word exception.  User is
-prompted to choose a file from the project case-exception-files
-if it is a list."
-  (interactive)
-  (let* ((project (wisi-prj-require-prj))
-        (file-name
-        (cond
-          ((< 1 (length (wisi-prj-case-exception-files project)))
-           (completing-read "case exception file: " 
(wisi-prj-case-exception-files project)
-                            nil ;; predicate
-                            t   ;; require-match
-                            nil ;; initial-input
-                            nil ;; hist
-                            (car (wisi-prj-case-exception-files project)) ;; 
default
-                            ))
-
-          ((= 1 (length (wisi-prj-case-exception-files project)))
-           (car (wisi-prj-case-exception-files project)))
-
-          (t
-           (error "No exception file specified; set `casing' in project 
file."))
-          ))
-       word)
-
-    (if (use-region-p)
-       (progn
-         (setq word (buffer-substring-no-properties (region-beginning) 
(region-end)))
-         (deactivate-mark))
-      (save-excursion
-       (let ((syntax (if partial "w" "w_")))
-         (skip-syntax-backward syntax)
-         (setq word
-               (buffer-substring-no-properties
-                (point)
-                (progn (skip-syntax-forward syntax) (point))
-                )))))
-
-    (let* ((exceptions (wisi--case-read-exceptions file-name))
-          (file-full-exceptions (car exceptions))
-          (file-partial-exceptions (cdr exceptions)))
-
-      (cond
-       ((null partial)
-       (setf (wisi-prj-case-full-exceptions project)
-             (wisi--case-add-exception word (wisi-prj-case-full-exceptions 
project)))
-       (setq file-full-exceptions (wisi--case-add-exception word 
file-full-exceptions)))
-
-       (t
-       (setf (wisi-prj-case-partial-exceptions project)
-             (wisi--case-add-exception word (wisi-prj-case-partial-exceptions 
project)))
-       (setq file-partial-exceptions (wisi--case-add-exception word 
file-partial-exceptions)))
-
-       )
-      (wisi--case-save-exceptions file-full-exceptions file-partial-exceptions 
file-name)
-      (message "created %s case exception '%s' in file '%s'"
-              (if partial "partial" "full")
-              word
-              file-name)
-      )
-    ))
-
-(defun wisi-case-create-partial-exception ()
-  "Define active region or word at point as a partial word exception.
-User is prompted to choose a file from the project
-case-exception-files if it is a list."
-  (interactive)
-  (wisi-case-create-exception t))
-
-(defun wisi-after-keyword-p ()
-  "Return non-nil if point is after an element of `wisi-language-keywords'."
-  (let ((word (buffer-substring-no-properties
-              (save-excursion (skip-syntax-backward "w_") (point))
-              (point))))
-    (member (downcase word) wisi-language-keywords)))
-
-(defvar-local wisi--ret-binding #'wisi-indent-newline-indent)
-(defvar-local wisi--lfd-binding #'newline-and-indent)
-
-(defun wisi-case-keyword (beg end)
-  (cl-ecase wisi-case-keyword
-    (lower-case (downcase-region beg end))
-    (upper-case (upcase-region beg end))
-    ))
-
-(defun wisi-case-identifier (start end case-strict)
-  (cl-ecase wisi-case-identifier
-    (mixed-case (wisi-mixed-case start end case-strict))
-    (lower-case (downcase-region start end))
-    (upper-case (upcase-region start end))
-    ))
-
-(defun wisi-mixed-case (start end case-strict)
-  "Adjust case of region START END to Mixed_Case."
-  (let ((done nil)
-       next)
-    (if (or case-strict wisi-case-strict)
-       (downcase-region start end))
-    (goto-char start)
-    (while (not done)
-      (setq next
-           (or
-            (save-excursion (when (search-forward "_" end t) (point-marker)))
-            (copy-marker (1+ end))))
-
-      ;; upcase first char
-      (upcase-region (point) (1+ (point)))
-
-      (goto-char next)
-      (if (< (point) end)
-         (setq start (point))
-       (setq done t))
-      )))
-
-(defun wisi-case-adjust-identifier (&optional force-case)
-  "Adjust case of the previous word as an identifier.
-Uses `wisi-case-identifier', with exceptions defined in
-`wisi-case-full-exceptions', `wisi-case-partial-exceptions'.  If
-force-case non-nil (default prefix), treat `wisi-strict-case' as
-t."
-  (interactive "P")
-  (save-excursion
-    ;; We don't complain when there is no project; we may be editing a
-    ;; random Ada file.
-    (let ((prj (wisi-prj-current-prj))
-         (end   (point-marker))
-         (start (progn (skip-syntax-backward "w_") (point)))
-         match
-         next
-         (done nil))
-
-      (if (setq match
-               (assoc-string (buffer-substring-no-properties start end)
-                             (wisi-prj-case-full-exceptions prj)
-                             t ;; case-fold
-                             ))
-         ;; full word exception
-         (progn
-           ;; 'save-excursion' puts a marker at 'end'; if we do
-           ;; 'delete-region' first, it moves that marker to 'start',
-           ;; then 'insert' inserts replacement text after the
-           ;; marker, defeating 'save-excursion'. So we do 'insert' first.
-           (insert (car match))
-           (delete-region (point) end))
-
-       ;; else apply wisi-case-identifier
-       (wisi-case-identifier start end force-case)
-
-       ;; apply partial-exceptions
-       (goto-char start)
-       (while (not done)
-         (setq next
-               (or
-                (save-excursion (when (search-forward "_" end t) 
(point-marker)))
-                (copy-marker (1+ end))))
-
-         (when (setq match (assoc-string (buffer-substring-no-properties start 
(1- next))
-                                         (wisi-prj-case-partial-exceptions prj)
-                                         t))
-           ;; see comment above at 'full word exception' for why
-           ;; we do insert first.
-           (insert (car match))
-           (delete-region (point) (1- next)))
-
-         (goto-char next)
-         (if (< (point) end)
-             (setq start (point))
-           (setq done t))
-          ))
-      )))
-
-(defun wisi-case-adjust-keyword ()
-  "Adjust the case of the previous symbol as a keyword."
-  (save-excursion
-    (let ((end   (point-marker))
-         (start (progn (skip-syntax-backward "w_") (point))))
-      (wisi-case-keyword start end)
-    )))
-
-(defun wisi-case-adjust (&optional typed-char in-comment)
-  "Adjust the case of the symbol before point.
-When invoked interactively, TYPED-CHAR must be
-`last-command-event', and it must not have been inserted yet.  If
-IN-COMMENT is non-nil, adjust case of words in comments and
-strings as code, and treat `wisi-case-strict' as t in code."
-  (when (not (bobp))
-    (when (save-excursion
-           (forward-char -1); back to last character in symbol
-           (and (not (bobp))
-                (eq (char-syntax (char-after)) ?w); it can be capitalized
-
-                (or in-comment
-                    (not (wisi-in-string-or-comment-p)))
-
-                (or (null wisi-case-adjust-p-function)
-                    (funcall wisi-case-adjust-p-function typed-char))
-                ))
-
-      ;; The indentation engine may trigger a reparse on
-      ;; non-whitespace changes, but we know we don't need to reparse
-      ;; for this change (assuming the user has not abused case
-      ;; exceptions!).
-      (let ((inhibit-modification-hooks t))
-       (cond
-        ;; Some attributes are also keywords, but captialized as
-        ;; attributes. So check for attribute first.
-        ((and
-          (not in-comment)
-          (save-excursion
-            (skip-syntax-backward "w_")
-            (eq (char-before) ?')))
-         (wisi-case-adjust-identifier in-comment))
-
-        ((and
-          (not in-comment)
-          (not (eq typed-char ?_))
-          (wisi-after-keyword-p))
-         (wisi-case-adjust-keyword))
-
-        (t (wisi-case-adjust-identifier in-comment))
-        ))
-      )))
-
-(defun wisi-case-adjust-at-point (&optional in-comment)
-  "If ’wisi-auto-case’ is non-nil, adjust case of symbol at point.
-Also move to end of symbol.  With prefix arg, adjust case as code
-even if in comment or string; otherwise, capitalize words in
-comments and strings.  If ’wisi-auto-case’ is nil, capitalize
-current word."
-  (interactive "P")
-  (cond
-   ((or (null wisi-auto-case)
-       (and (not in-comment)
-            (wisi-in-string-or-comment-p)))
-    (skip-syntax-backward "w_")
-    (capitalize-word 1))
-
-   (t
-    (when
-       (and (not (eobp))
-            ;; We use '(syntax-after (point))' here, not '(char-syntax
-            ;; (char-after))', because the latter does not respect
-            ;; syntax-propertize functions
-            (memq (syntax-class (syntax-after (point))) '(2 3)))
-      (skip-syntax-forward "w_"))
-    (wisi-case-adjust nil in-comment))
-   ))
-
-(defun wisi-case-adjust-region (begin end)
-  "Adjust case of all words in region BEGIN END."
-  (interactive "r")
-  (narrow-to-region begin end)
-  (save-excursion
-    (goto-char begin)
-    (while (not (eobp))
-      (forward-comment (point-max))
-      (skip-syntax-forward "^w_")
-      (skip-syntax-forward "w_")
-      (wisi-case-adjust)))
-  (widen))
-
-(defun wisi-case-adjust-buffer ()
-  "Adjust case of current buffer."
-  (interactive)
-  (wisi-case-adjust-region (point-min) (point-max)))
-
-(defun wisi-case-adjust-interactive (arg)
-  "If `wisi-auto-case' is non-nil, adjust the case of the previous symbol,
-and process the character just typed.  To be bound to keys that
-should cause auto-casing.  ARG is the prefix the user entered
-with \\[universal-argument]."
-  (interactive "P")
-
-  ;; Character typed has not been inserted yet.
-  (let ((lastk last-command-event)
-       (do-adjust nil))
-    (cond
-     ((null wisi-auto-case))
-     (t
-      (setq do-adjust t)))
-
-    (cond
-     ((eq lastk ?\n)
-        (when do-adjust
-         (wisi-case-adjust lastk))
-       (funcall wisi--lfd-binding))
-
-     ((memq lastk '(?\r return))
-      (when do-adjust
-       (wisi-case-adjust lastk))
-      (funcall wisi--ret-binding))
-
-     (t
-      (when do-adjust
-       (wisi-case-adjust lastk))
-      (self-insert-command (prefix-numeric-value arg)))
-     )))
-
-(defun wisi-case-activate-keys (map)
-  "Modify the key bindings for all the keys that should adjust casing."
-  (mapc (function
-        (lambda(key)
-          (define-key
-            map
-            (char-to-string key)
-            'wisi-case-adjust-interactive)))
-       '( ?_ ?% ?& ?* ?\( ?\) ?- ?= ?+
-             ?| ?\; ?: ?' ?\" ?< ?, ?. ?> ?/ ?\n 32 ?\r ))
-  )
-
-;;;; xref backend
-
-(defconst wisi-file-line-col-regexp
-  ;; matches Gnu-style file references:
-  ;; 
C:\Projects\GDS\work_dscovr_release\common\1553\gds-mil_std_1553-utf.ads:252:25
-  ;; 
/Projects/GDS/work_dscovr_release/common/1553/gds-mil_std_1553-utf.ads:252:25
-  ;; gds-mil_std_1553-utf.ads:252:25 - when wisi-xref-full-path is nil
-  "\\(\\(?:.:\\\\\\|/\\)?[^:]*\\):\\([0-9]+\\):\\([0-9]+\\)"
-  ;; 1                              2            3
-  "Regexp matching <file>:<line>:<column> where <file> is an absolute file 
name or basename.")
-
-(defun wisi-xref-item (identifier prj)
-  "Given IDENTIFIER, return an xref-item, with line, column nil if unknown.
-IDENTIFIER is from a user prompt with completion, or from
-`xref-backend-identifier-at-point'."
-  (let* ((t-prop (get-text-property 0 'xref-identifier identifier))
-        ident file line column)
-    (cond
-     (t-prop
-      ;; IDENTIFIER is from wisi-xref-identifier-at-point.
-      (setq ident (substring-no-properties identifier 0 nil))
-      (setq file (plist-get t-prop :file))
-      (setq line (plist-get t-prop :line))
-      (setq column (plist-get t-prop :column))
-      )
-
-     ((string-match (wisi-xref-completion-regexp (wisi-prj-xref prj)) 
identifier)
-      ;; IDENTIFIER is from prompt/completion on wisi-xref-completion-table
-      (setq ident (match-string 1 identifier))
-
-      (let* ((table (wisi-xref-completion-table (wisi-prj-xref prj) prj))
-            (loc (cdr (assoc identifier table))))
-
-       (setq file (nth 0 loc))
-       (setq line (nth 1 loc))
-       (setq column (nth 2 loc))
-       ))
-
-     ((string-match wisi-names-regexp identifier)
-      ;; IDENTIFIER is from prompt/completion on wisi-names.
-      (setq ident (match-string 1 identifier))
-      (setq file (buffer-file-name))
-      (when (match-string 2 identifier)
-       (setq line (string-to-number (match-string 2 identifier))))
-      )
-
-     (t
-      ;; IDENTIFIER has no line/column info
-      (setq ident identifier)
-      (setq file (buffer-file-name)))
-     )
-
-    (unless (file-name-absolute-p file)
-      (setq file (locate-file file compilation-search-path)))
-
-    (let ((eieio-skip-typecheck t)) ;; allow line, column nil.
-      (xref-make ident (xref-make-file-location file line column)))
-    ))
-
-(cl-defmethod xref-backend-definitions ((prj wisi-prj) identifier)
-  (wisi-xref-definitions (wisi-prj-xref prj) prj (wisi-xref-item identifier 
prj)))
-
-(cl-defmethod xref-backend-identifier-at-point ((prj wisi-prj))
-  (save-excursion
-    (let ((id (wisi-prj-identifier-at-point prj)))
-      (when id
-       (put-text-property
-        0 1
-        'xref-identifier
-        (list ':file (buffer-file-name)
-              ':line (line-number-at-pos)
-              ':column (save-excursion (goto-char (nth 0 id)) 
(current-column)))
-        (nth 2 id))
-       (nth 2 id)))))
-
-(cl-defmethod xref-backend-identifier-completion-table ((prj wisi-prj))
-  (wisi-filter-table (wisi-xref-completion-table (wisi-prj-xref prj) prj)
-                    (when (equal '(16) current-prefix-arg) 
(buffer-file-name))))
-
-(cl-defmethod xref-backend-references  ((prj wisi-prj) identifier)
-  (wisi-xref-references (wisi-prj-xref prj) prj (wisi-xref-item identifier 
prj)))
-
-;;;###autoload
-(defun wisi-prj-xref-backend ()
-  "For `xref-backend-functions'; return the current wisi project."
-  ;; We return the project, not the xref object, because the
-  ;; wisi-xref-* functions need the project.
-  (let ((prj (project-current)))
-    (when (wisi-prj-p prj)
-      prj)))
-
-;;;; project-find-functions alternatives
-
-(defvar wisi-prj--dominating-alist nil
-"Alist of (DOMINATING-FILE . PRJ-FILE-NAME): DOMINATING-FILE is
-an absolute filename that can be found by
-`wisi-prj-find-dominating-cached' or
-`wisi-prj-find-dominating-cached'.  PRJ-FILE-NAME is the wisi
-project file for the project for that file.")
-
-;;;###autoload
-(defun wisi-prj-select-cache (prj-file init-prj &optional dominating-file)
-  "Select project matching PRJ-FILE in `wisi-prj--cache' as current project,
-parsing and caching if needed. Also add DOMINATING-FILE (default
-current buffer file name) to `wisi-prj--dominating-alist' (for
-`wisi-prj-select-dominating'.)"
-  (let ((old-prj (project-current)))
-    ;; If old-prj is not a wisi-prj, we don't know how to deselect it;
-    ;; just ignore that.  If prj-file is the current file, user is
-    ;; re-selecting it.
-    (when (wisi-prj-p old-prj)
-      (wisi-prj-deselect old-prj)))
-
-  (unless (or (memq #'wisi-prj-current-cached project-find-functions)
-             (memq #'wisi-prj-current-cached (default-value 
'project-find-functions)))
-    (message "wisi-prj-select-cache used without wisi-prj-current-cached in 
project-find-functions"))
-
-  (setq dominating-file (if dominating-file (expand-file-name dominating-file) 
(buffer-file-name)))
-  (setq prj-file (expand-file-name prj-file))
-  (add-to-list 'wisi-prj--dominating-alist (cons dominating-file prj-file))
-
-  (let ((new-prj (cdr (assoc prj-file wisi-prj--cache))))
-    (unless new-prj
-      (setq new-prj (wisi-prj-parse-file :prj-file prj-file :init-prj init-prj 
:cache t))
-      (unless new-prj
-       (error "parsing project file '%s' failed" prj-file)))
-
-    (setq wisi-prj--current-file prj-file)
-    (wisi-prj-select new-prj)))
-
-;;;###autoload
-(defun wisi-prj-select-dominating (&optional dominating-file)
-  "Unless it is already current, select a wisi-prj matching DOMINATING-FILE.
-DOMINATING-FILE defaults to the current buffer file name.
-Useful before running `compilation-start', to ensure the correct
-project is current."
-  (when (or dominating-file (buffer-file-name))
-    ;; buffer-file-name is nil in *compilation* buffer
-    (let ((prj-file (cdr (assoc (or dominating-file (buffer-file-name)) 
wisi-prj--dominating-alist))))
-      (unless (string-equal prj-file wisi-prj--current-file)
-       (message "Switching to project file '%s'" prj-file)
-       (let ((old-prj (cdr (assoc  wisi-prj--current-file wisi-prj--cache)))
-             (new-prj (cdr (assoc prj-file wisi-prj--cache))))
-         (when (wisi-prj-p old-prj)
-           (wisi-prj-deselect old-prj))
-         (when (wisi-prj-p new-prj)
-           (wisi-prj-select new-prj))
-         (setq wisi-prj--current-file prj-file))))))
-
-;;;###autoload
-(defun wisi-prj-current-cached (_dir)
-  "For `project-find-functions'; return the current project from 
`wisi-prj--cache'."
-  (cdr (assoc wisi-prj--current-file wisi-prj--cache)))
-
-(defvar wisi-prj--default nil
-  "Alist of (PRJ-FILE . INIT-PRJ), for `wisi-prj-parse-current'.
-PRJ-FILE is an absolute project file name; INIT-PRJ is the
-initial `wisi-prj' object for that project file.")
-
-;;;###autoload
-(defun wisi-prj-select-file (prj-file default-prj &optional dominating-file)
-  "Set PRJ-FILE as current project, add DEFAULT-PRJ to `wisi-prj--default'.
-Also add DOMINATING-FILE (default current buffer file name) to
-`wisi-prj--dominating-alist' (for `wisi-prj-select-dominating'.)"
-  (unless (or (memq #'wisi-prj-current-parse project-find-functions)
-             (memq #'wisi-prj-current-parse (default-value 
'project-find-functions)))
-    (message "wisi-prj-select-file used without wisi-prj-current-parse in 
project-find-functions"))
-
-  (setq dominating-file (if dominating-file (expand-file-name dominating-file) 
(buffer-file-name)))
-  (setq prj-file (expand-file-name prj-file))
-  (add-to-list 'wisi-prj--dominating-alist (cons dominating-file prj-file))
-  (setq wisi-prj--current-file prj-file)
-  (add-to-list 'wisi-prj--default (cons prj-file default-prj)))
-
-;;;###autoload
-(defun wisi-prj-current-parse (_dir)
-  "For `project-find-functions'; parse the current project file, select and 
return the project"
-  (let ((prj (wisi-prj-parse-file
-             :prj-file wisi-prj--current-file
-             :init-prj (cdr (assoc-string wisi-prj--current-file 
wisi-prj--default))
-             :cache nil)))
-    (wisi-prj-select prj)
-    prj))
-
-(defvar wisi-prj--dominating nil
-  "List of relative filenames for `wisi-prj-find-dominating-cached'
-and `wisi-prj-find-dominating-parse'. Set by `wisi-prj-set-dominating'.")
-
-(defun wisi-prj-reset-cache ()
-  "Delete all wisi project cached info."
-  (interactive)
-  (setq wisi-prj--cache nil)
-  (setq wisi-prj--current-file nil)
-  (setq wisi-prj--default nil)
-  (setq wisi-prj--dominating nil)
-  (setq wisi-prj--dominating-alist nil))
-
-;;;###autoload
-(defun wisi-prj-cache-dominating (prj-file default-prj &optional 
dominating-file)
-  "Parse prj-file, add to `wisi-prj--cache'.
-Also add (DOMINATING-FILE . PRJ-FILE) to `wisi-prj--dominating-alist'.
-DOMINATING-FILE defaults to (buffer-file-name). "
-  (unless (or (memq #'wisi-prj-find-dominating-cached project-find-functions)
-             (memq #'wisi-prj-find-dominating-cached (default-value 
'project-find-functions)))
-    (message "wisi-prj-cache-dominating used without 
wisi-prj-find-dominating-cached in project-find-functions"))
-
-  (setq dominating-file (if dominating-file (expand-file-name dominating-file) 
(buffer-file-name)))
-  (setq prj-file (expand-file-name prj-file))
-  (add-to-list 'wisi-prj--dominating (file-name-nondirectory dominating-file))
-  (add-to-list 'wisi-prj--dominating-alist (cons dominating-file prj-file))
-  (wisi-prj-parse-file :prj-file prj-file :init-prj default-prj :cache t)
-  nil)
-
-(defun wisi-prj--find-dominating-file (start-dir)
-  "Return the project file matching `wisi-prj--dominating'."
-  (let* (dom-file
-        (_dom-dir
-         (locate-dominating-file
-          start-dir
-          (lambda (dir)
-            (let ((names wisi-prj--dominating))
-              (while names
-                (let ((filename (expand-file-name (pop names) dir)))
-                  (when (file-exists-p filename)
-                    (setq dom-file filename)
-                    (setq names nil)))))
-            dom-file))))
-    (cdr (assoc-string dom-file wisi-prj--dominating-alist))))
-
-;;;###autoload
-(defun wisi-prj-find-dominating-cached (dir)
-  "For `project-find-functions'; return the cached project
-matching `wisi-prj--dominating' (nil if none). Select it if it is
-not the current project."
-  (let* ((prj-file (wisi-prj--find-dominating-file dir))
-        (new-prj (cdr (assoc-string prj-file wisi-prj--cache))))
-    (when prj-file
-      (unless (string= prj-file wisi-prj--current-file)
-       (let ((old-prj (cdr (assoc-string wisi-prj--current-file 
wisi-prj--cache))))
-         (when old-prj (wisi-prj-deselect old-prj))
-         (unless new-prj
-           ;; User may have used `wisi-prj-set-dominating' instead of
-           ;; `wisi-prj-cache-dominating'; parse the project file now.
-           (wisi-prj-parse-file
-            :prj-file prj-file
-            :init-prj (cdr (assoc-string prj-file wisi-prj--default))
-            :cache t))
-         (when new-prj (wisi-prj-select new-prj))))
-      new-prj)))
-
-;;;###autoload
-(defun wisi-prj-set-dominating (prj-file default-prj &optional dom-file)
-  "Add (DOM-FILE . PRJ-FILE) to `wisi-prj--dominating-alist',
-and (PRJ-FILE . DEFAULT-PRJ) to `wisi-prj--default'.
-DOM-FILE defaults to (buffer-file-name).
-For example, call this in the Local Vars of a Makefile to
-associate a project with that Makefile."
-  (unless (or (memq #'wisi-prj-find-dominating-parse project-find-functions)
-             (memq #'wisi-prj-find-dominating-parse (default-value 
'project-find-functions)))
-    (message "wisi-prj-cache-dominating used without 
wisi-prj-find-dominating-parse in project-find-functions"))
-
-  (setq dom-file (if dom-file (expand-file-name dom-file) (buffer-file-name)))
-  (setq prj-file (expand-file-name prj-file))
-  (add-to-list 'wisi-prj--dominating (file-name-nondirectory dom-file))
-  (add-to-list 'wisi-prj--dominating-alist (cons dom-file prj-file))
-  (add-to-list 'wisi-prj--default (cons prj-file default-prj))
-  nil)
-
-;;;###autoload
-(defun wisi-prj-find-dominating-parse (dir)
-  "For `project-find-functions'; parse, select, and return the project
-file matching `wisi-prj--dominating'."
-  (let ((prj-file (wisi-prj--find-dominating-file dir)))
-    (when prj-file
-      (let ((prj (wisi-prj-parse-file
-                 :prj-file prj-file
-                 :init-prj (cdr (assoc-string prj-file wisi-prj--default))
-                 :cache nil)))
-       (wisi-prj-select prj)
-       prj))))
-
-;;;###autoload
-(defun wisi-prj-dtrt-parse-file (prj-file default-prj dominating-file 
&optional dir)
-  "Depending on wisi-prj function in `project-find-functions',
-Do The Right Thing to make PRJ-FILE active and selected; return the project."
-  (cond
-   ((memq #'wisi-prj-find-dominating-parse project-find-functions)
-    (wisi-prj-set-dominating prj-file default-prj dominating-file))
-
-   ((memq #'wisi-prj-find-dominating-cached project-find-functions)
-    (wisi-prj-cache-dominating prj-file default-prj dominating-file))
-
-   ((memq #'wisi-prj-current-cached project-find-functions)
-    (wisi-prj-select-cache prj-file default-prj dominating-file))
-
-   ((memq #'wisi-prj-current-parse project-find-functions)
-    (wisi-prj-select-file prj-file default-prj dominating-file))
-
-   (t
-    (user-error "No wisi-prj function in project-find-functions"))
-   )
-  (project-current nil (or dir default-directory)))
-
-;;;###autoload
-(defun wisi-prj-find-function-set-p ()
-  "Return non-nil if a wisi-prj function is present in 
`project-find-functions'."
-  (or (memq #'wisi-prj-find-dominating-parse project-find-functions)
-      (memq #'wisi-prj-find-dominating-cached project-find-functions)
-      (memq #'wisi-prj-current-cached project-find-functions)
-      (memq #'wisi-prj-current-parse project-find-functions)))
-
-;;;; project menu
-
-(defun wisi-prj--menu-compute ()
-  "Return an easy-menu menu for `wisi-prj-menu--install'.
-Menu displays cached wisi projects."
-  (let (menu)
-    (dolist (item wisi-prj--cache)
-      (push
-       (vector
-       (concat (wisi-prj-name (cdr item))
-               (when (equal (car item) wisi-prj--current-file) "  *")) ;; 
current project
-       `(lambda () (interactive)
-          (when wisi-prj--current-file
-            (wisi-prj-deselect (cdr (assoc wisi-prj--current-file 
wisi-prj--cache))))
-          (setq wisi-prj--current-file ,(car item))
-          (wisi-prj-select ,(cdr item)))
-       t)
-       menu)
-      )
-    (nreverse menu)))
-
-(defun wisi-prj-menu-install ()
-  "Install the project menu if appropriate, to display cached wisi projects."
-  (when
-      (or (memq #'wisi-prj-find-dominating-cached project-find-functions)
-         (memq #'wisi-prj-current-cached project-find-functions))
-
-    (let ((menu (wisi-prj--menu-compute)))
-      (if menu
-         (define-key-after
-           global-map
-           [menu-bar wisi-prj-select]
-           (easy-menu-binding
-            (easy-menu-create-menu
-             "Wisi Prj Select";; EDE uses "Project" menu
-             menu))
-           (lookup-key global-map [menu-bar tools]))
-       ;; delete empty menu
-         (define-key-after
-           global-map
-           [menu-bar wisi-prj-select]
-           nil
-           (lookup-key global-map [menu-bar tools]))
-       ))
-    ))
-
-(add-hook 'menu-bar-update-hook 'wisi-prj-menu-install)
-
-(defun wisi-prj-completion-table ()
-  "Return list of names of cached projects."
-  (mapcar (lambda (item) (wisi-prj-name (cdr item))) wisi-prj--cache))
-
-(defun wisi-prj-delete (name)
-  "Delete project NAME (default prompt) from the cached projects."
-  (interactive (list (completing-read "project name: " 
(wisi-prj-completion-table))))
-  (let (pair)
-    (dolist (item wisi-prj--cache)
-      (if (string= name (wisi-prj-name (cdr item)))
-         (setq pair item)))
-
-    (setq wisi-prj--cache (delete pair wisi-prj--cache))
-
-    (setq wisi-prj--dominating-alist
-         (cl-delete-if (lambda (item)
-                         (string= (car pair) (cdr item)))
-                       wisi-prj--dominating-alist))
-    ))
-
-(provide 'wisi-prj)
-;; end wisi-prj.el
diff --git a/packages/wisi/wisi-process-parse.el 
b/packages/wisi/wisi-process-parse.el
deleted file mode 100644
index bddd033..0000000
--- a/packages/wisi/wisi-process-parse.el
+++ /dev/null
@@ -1,844 +0,0 @@
-;;; wisi-process-parse.el --- interface to external parse program
-;;
-;; Copyright (C) 2014, 2017 - 2020 Free Software Foundation, Inc.
-;;
-;; Author: Stephen Leake <stephen_leake@member.fsf.org>
-;;
-;; This file is part of GNU Emacs.
-;;
-;; GNU Emacs 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 3 of the License, or
-;; (at your option) any later version.
-;;
-;; GNU Emacs 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 GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.
-
-(require 'cl-lib)
-(require 'wisi-parse-common)
-
-(defgroup wisi nil
-  "Options for Wisi package."
-  :group 'programming)
-
-(defcustom wisi-process-time-out 5.0
-  "Time out waiting for parser response. An error occurs if there
-  is no response from the parser after waiting this amount (in
-  seconds)."
-  :type 'float
-  :safe 'numberp)
-(make-variable-buffer-local 'wisi-process-time-out)
-
-(defconst wisi-process-parse-protocol-version "5"
-  "Defines data exchanged between this package and the background process.
-Must match emacs_wisi_common_parse.ads Protocol_Version.")
-
-(defconst wisi-process-parse-prompt "^;;> "
-  "Regexp matching executable prompt; indicates previous command is complete.")
-
-(defconst wisi-process-parse-quit-cmd "004quit\n"
-  "Command to external process telling it to quit.")
-
-;;;;; sessions
-
-;; The executable builds internal parser structures on startup,
-;; then runs a loop, waiting for parse requests.
-;;
-;; We only need one process per language; there is no persistent state
-;; in the process between parses, and processes are too heavy-weight
-;; to have one per buffer. We use a global alist of parser objects to
-;; find the right one for the current buffer.
-
-(cl-defstruct (wisi-process--parser (:include wisi-parser))
-  (label nil)             ;; string uniquely identifying parser
-  language-protocol-version ;; string identifying language-specific params
-  (exec-file nil)        ;; absolute file name of executable
-  (exec-opts nil)         ;; list of process start options for executable
-  (token-table nil)       ;; vector of token symbols, indexed by integer
-  (face-table nil)       ;; vector of face symbols, indexed by integer
-  (busy nil)              ;; t while parser is active
-  (process nil)          ;; running *_wisi_parse executable
-  (buffer nil)                   ;; receives output of executable
-  line-begin              ;; vector of beginning-of-line positions in buffer
-  (total-wait-time 0.0)   ;; total time during last parse spent waiting for 
subprocess output.
-  (response-count 0)      ;; responses received from subprocess during last 
parse; for profiling.
-  end-pos                 ;; last character position parsed
-  language-action-table   ;; array of function pointers, each taking an sexp 
sent by the process
-  )
-
-(defvar wisi-process--alist nil
-  "Alist mapping string label to ‘wisi-process--session’ struct")
-
-;;;###autoload
-(defun wisi-process-parse-get (parser)
-  "Return a ‘wisi-process--parser’ object matching PARSER label.
-If label found in ‘wisi-process--alist’, return that.
-Otherwise add PARSER to ‘wisi-process--alist’, return it."
-  (or (cdr (assoc (wisi-process--parser-label parser) wisi-process--alist))
-      (let ((exec-file (locate-file (wisi-process--parser-exec-file parser) 
exec-path '("" ".exe"))))
-
-       (unless exec-file
-         (error "%s not found on `exec-path'; run 'build.sh' in the ELPA 
package."
-                (wisi-process--parser-exec-file parser)))
-
-       (push (cons (wisi-process--parser-label parser) parser) 
wisi-process--alist)
-
-       parser
-     )))
-
-(defun wisi-process-parse-set-exec (label exec-file)
-  "Change the EXEC-FILE for parsers with LABEL."
-  (let ((parser (cdr (assoc label wisi-process--alist))))
-    (when parser
-      (wisi-parse-kill parser)
-      (setf (wisi-process--parser-exec-file parser) exec-file))))
-
-(defun wisi-process-parse--check-version (parser)
-  "Verify protocol version reported by process."
-  ;; The process has just started; the first non-comment line in the
-  ;; process buffer contains the process and language protocol versions.
-  (with-current-buffer (wisi-process--parser-buffer parser)
-    (goto-char (point-min))
-    (if (search-forward-regexp "protocol: process version \\([0-9]+\\) 
language version \\([0-9]+\\)" nil t)
-       (unless (and (match-string 1)
-                    (string-equal (match-string 1) 
wisi-process-parse-protocol-version)
-                    (match-string 2)
-                    (string-equal (match-string 2) 
(wisi-process--parser-language-protocol-version parser)))
-         (wisi-parse-kill parser)
-         (error "%s parser process protocol version mismatch: elisp %s %s, 
process %s %s"
-                (wisi-process--parser-label parser)
-                wisi-process-parse-protocol-version 
(wisi-process--parser-language-protocol-version parser)
-                (match-string 1) (match-string 2)))
-      ;; Search failed
-      (error "%s parser process protocol version message not found"
-            (wisi-process--parser-label parser))
-    )))
-
-(defun wisi-process-parse--require-process (parser)
-  "Start the process for PARSER if not already started."
-  (unless (process-live-p (wisi-process--parser-process parser))
-    (let ((process-connection-type nil) ;; use a pipe, not a pty; avoid 
line-by-line reads
-         (process-name (format " *%s_wisi_parse*" (wisi-process--parser-label 
parser))))
-
-      (unless (buffer-live-p (wisi-process--parser-buffer parser))
-       ;; User may have killed buffer to kill parser.
-       (setf (wisi-process--parser-buffer parser)
-             (get-buffer-create process-name)))
-
-      (with-current-buffer (wisi-process--parser-buffer parser)
-       (erase-buffer)); delete any previous messages, prompt
-
-      (setf (wisi-process--parser-process parser)
-           (make-process
-            :name process-name
-            :buffer (wisi-process--parser-buffer parser)
-            :command (append (list (wisi-process--parser-exec-file parser))
-                             (wisi-process--parser-exec-opts parser))))
-
-      (set-process-query-on-exit-flag (wisi-process--parser-process parser) 
nil)
-
-      (wisi-process-parse--wait parser)
-      (wisi-process-parse--check-version parser)
-      )))
-
-(defun wisi-process-parse--wait (parser)
-  "Wait for the current command to complete."
-  (let ((process (wisi-process--parser-process parser))
-       (search-start (point-min))
-       (wait-count 0)
-       (found nil))
-
-    (with-current-buffer (wisi-process--parser-buffer parser)
-      (while (and (process-live-p process)
-                 (progn
-                   ;; process output is inserted before point, so move back 
over it to search it
-                   (goto-char search-start)
-                   (not (setq found (re-search-forward 
wisi-process-parse-prompt (point-max) t)))))
-       (setq search-start (point));; don't search same text again
-       (setq wait-count (1+ wait-count))
-       (accept-process-output process 0.1))
-
-      (unless found
-       (wisi-process-parse-show-buffer parser)
-       (error "%s process died" (wisi-process--parser-exec-file parser)))
-      )))
-
-(defun wisi-process-parse-show-buffer (parser)
-  "Show PARSER buffer."
-  (if (buffer-live-p (wisi-process--parser-buffer parser))
-      (pop-to-buffer (wisi-process--parser-buffer parser))
-    (error "wisi-process-parse process not active")))
-
-(defun wisi-process-parse--send-parse (parser begin send-end parse-end)
-  "Send a parse command to PARSER external process, followed by
-the content of the current buffer from BEGIN thru SEND-END.  Does
-not wait for command to complete. PARSE-END is end of desired
-parse region."
-  ;; Must match "parse" command arguments read by
-  ;; emacs_wisi_common_parse.adb Get_Parse_Params.
-  (let* ((cmd (format "parse %d \"%s\" %d %d %d %d %d %d %d %d %d %d %d %d %d 
%d %d %d %d %d %s"
-                     (cl-ecase wisi--parse-action
-                       (navigate 0)
-                       (face 1)
-                       (indent 2))
-                     (if (buffer-file-name) (file-name-nondirectory 
(buffer-file-name)) "")
-                     (position-bytes begin)
-                     (position-bytes send-end)
-                     (position-bytes parse-end)
-                     begin ;; char_pos
-                     (line-number-at-pos begin)
-                     (line-number-at-pos send-end)
-                     (save-excursion (goto-char begin) (back-to-indentation) 
(current-column));; indent-begin
-                     (if (or (and (= begin (point-min)) (= parse-end 
(point-max)))
-                             (< (point-max) wisi-partial-parse-threshold))
-                         0 1) ;; partial parse active
-                     (if (> wisi-debug 0) 1 0) ;; debug_mode
-                     (1- wisi-debug) ;; trace_parse
-                     wisi-trace-mckenzie
-                     wisi-trace-action
-                     (if wisi-mckenzie-disable 1 0)
-                     (or wisi-mckenzie-task-count -1)
-                     (or wisi-mckenzie-check-limit -1)
-                     (or wisi-mckenzie-enqueue-limit -1)
-                     (or wisi-parse-max-parallel -1)
-                     (- (position-bytes send-end) (position-bytes begin)) ;; 
send-end is after last byte
-                     (wisi-parse-format-language-options parser)
-                     ))
-        (msg (format "%03d%s" (length cmd) cmd))
-        (process (wisi-process--parser-process parser)))
-    (with-current-buffer (wisi-process--parser-buffer parser)
-      (erase-buffer))
-
-    (process-send-string process msg)
-    (process-send-string process (buffer-substring-no-properties begin 
send-end))
-
-    ;; We don’t wait for the send to complete; the external process
-    ;; may start parsing and send an error message.
-    ))
-
-(defun wisi-process-parse--send-refactor (parser refactor-action parse-begin 
parse-end edit-begin)
-  "Send a refactor command to PARSER external process, followed
-by the content of the current buffer from PARSE-BEGIN thru
-PARSE-END, wait for command to complete. PARSER will respond with
-one or more Edit messages."
-  ;; Must match "refactor" command arguments read by
-  ;; emacs_wisi_common_parse.adb Get_Refactor_Params.
-  (let* ((cmd (format "refactor %d \"%s\" %d %d %d %d %d %d %d %d %d %d %d %d"
-                     refactor-action
-                     (if (buffer-file-name) (file-name-nondirectory 
(buffer-file-name)) "")
-                     (position-bytes parse-begin)
-                     (position-bytes parse-end)
-                     (position-bytes edit-begin)
-                     parse-begin ;; char_pos
-                     (line-number-at-pos parse-begin)
-                     (line-number-at-pos parse-end)
-                     (save-excursion (goto-char parse-begin) 
(back-to-indentation) (current-column));; indent-begin
-                     (if (> wisi-debug 0) 1 0) ;; debug-mode
-                     (1- wisi-debug) ;; trace_parse
-                     wisi-trace-action
-                     (or wisi-parse-max-parallel -1)
-                     (- (position-bytes parse-end) (position-bytes 
parse-begin)) ;; parse-end is after last byte
-                     ))
-        (msg (format "%03d%s" (length cmd) cmd))
-        (process (wisi-process--parser-process parser)))
-    (with-current-buffer (wisi-process--parser-buffer parser)
-      (erase-buffer))
-
-    (process-send-string process msg)
-    (process-send-string process (buffer-substring-no-properties parse-begin 
parse-end))
-    (wisi-process-parse--wait parser)
-    ))
-
-(defun wisi-process-parse--send-noop (parser)
-  "Send a noop command to PARSER external process, followed by
-the content of the current buffer.  Does not wait for command to
-complete."
-  (let* ((cmd (format "noop %d" (1- (position-bytes (point-max)))))
-        (msg (format "%03d%s" (length cmd) cmd))
-        (process (wisi-process--parser-process parser)))
-    (with-current-buffer (wisi-process--parser-buffer parser)
-      (erase-buffer))
-
-    (process-send-string process msg)
-    (process-send-string process (buffer-substring-no-properties (point-min) 
(point-max)))
-    ))
-
-(defun wisi-process-parse--marker-or-nil (item)
-  (if (= -1 item) nil (copy-marker item t)))
-
-(defun wisi-process-parse--Navigate_Cache (parser sexp)
-  ;; sexp is [Navigate_Cache pos statement_id id length class containing_pos 
prev_pos next_pos end_pos]
-  ;; see ‘wisi-process-parse--execute’
-  (let ((pos (aref sexp 1)))
-    (with-silent-modifications
-      (put-text-property
-       pos
-       (1+ pos)
-       'wisi-cache
-       (wisi-cache-create
-       :nonterm    (aref (wisi-process--parser-token-table parser) (aref sexp 
2))
-       :token      (aref (wisi-process--parser-token-table parser) (aref sexp 
3))
-       :last       (aref sexp 4)
-       :class      (aref wisi-class-list (aref sexp 5))
-       :containing (wisi-process-parse--marker-or-nil (aref sexp 6))
-       :prev       (wisi-process-parse--marker-or-nil (aref sexp 7))
-       :next       (wisi-process-parse--marker-or-nil (aref sexp 8))
-       :end        (wisi-process-parse--marker-or-nil (aref sexp 9))
-       )))
-    ))
-
-(defun wisi-process-parse--Name_Property (parser sexp)
-  ;; sexp is [Name_Property first-pos last-pos]
-  ;; see ‘wisi-process-parse--execute’
-  ;; implements wisi-name-action
-  (with-silent-modifications
-    (put-text-property (aref sexp 1) (1+ (aref sexp 2)) 'wisi-name t)))
-
-(defun wisi-process-parse--Face_Property (parser sexp)
-  ;; sexp is [Face_Property first-pos last-pos face-index]
-  ;; see ‘wisi-process-parse--execute’
-  ;; implements wisi--face-action-1
-  (with-silent-modifications
-    (add-text-properties
-     (aref sexp 1)
-     (1+ (aref sexp 2))
-     (list 'font-lock-face (aref (wisi-process--parser-face-table parser) 
(aref sexp 3))
-          'fontified t)
-     )))
-
-(defun wisi-process-parse--Indent (parser sexp)
-  ;; sexp is [Indent line-number indent]
-  ;; see ‘wisi-process-parse--execute’
-  (let ((pos (aref (wisi-process--parser-line-begin parser) (1- (aref sexp 
1)))))
-    (with-silent-modifications
-      (when (< (point-min) pos)
-       (put-text-property
-        (1- pos)
-        pos
-        'wisi-indent
-        (aref sexp 2)))
-      )))
-
-(defun wisi-process-parse--Lexer_Error (parser sexp)
-  ;; sexp is [Lexer_Error char-position <message> <repair-char>]
-  ;; see ‘wisi-process-parse--execute’
-  (let ((pos (aref sexp 1))
-       err)
-
-    (goto-char pos);; for current-column
-
-    (setq err
-         (make-wisi--lexer-error
-          :pos (copy-marker pos)
-          :message
-          (format "%s:%d:%d: %s"
-                  (if (buffer-file-name) (file-name-nondirectory 
(buffer-file-name)) "")
-                  ;; file-name can be nil during vc-resolve-conflict
-                  (line-number-at-pos pos)
-                  (current-column)
-                  (aref sexp 2))
-          :inserted (when (= 4 (length sexp)) (aref sexp 3))))
-
-    (push err (wisi-parser-lexer-errors parser))
-    ))
-
-(defun wisi-process-parse--Parser_Error (parser sexp)
-  ;; sexp is [Parser_Error char-position <string>]
-  ;; see ‘wisi-process-parse--execute’
-  (let ((pos (aref sexp 1))
-       err)
-
-    (goto-char pos);; for current-column
-
-    (setq err
-         (make-wisi--parse-error
-          :pos (copy-marker pos)
-          :message
-          (format "%s:%d:%d: %s"
-                  (if (buffer-file-name) (file-name-nondirectory 
(buffer-file-name)) "")
-                  ;; file-name can be nil during vc-resolve-conflict
-                  (line-number-at-pos pos)
-                  (1+ (current-column))
-                  (aref sexp 2))))
-
-    (push err (wisi-parser-parse-errors parser))
-    ))
-
-(defun wisi-process-parse--Check_Error (parser sexp)
-  ;; sexp is [Check_Error code name-1-pos name-2-pos <string>]
-  ;; see ‘wisi-process-parse--execute’
-  (let* ((name-1-pos (aref sexp 2))
-       (name-1-col (1+ (progn (goto-char name-1-pos)(current-column)))) ;; 
gnat columns are 1 + emacs columns
-       (name-2-pos (aref sexp 3))
-       (name-2-col (1+ (progn (goto-char name-2-pos)(current-column))))
-       (file-name (if (buffer-file-name) (file-name-nondirectory 
(buffer-file-name)) ""))
-       ;; file-name can be nil during vc-resolve-conflict
-       (err (make-wisi--parse-error
-             :pos (copy-marker name-1-pos)
-             :message
-             (format "%s:%d:%d: %s %s:%d:%d"
-                     file-name (line-number-at-pos name-1-pos) name-1-col
-                     (aref sexp 4)
-                     file-name (line-number-at-pos name-2-pos) name-2-col)))
-       )
-
-    (push err (wisi-parser-parse-errors parser))
-    ))
-
-(defun wisi-process-parse--Recover (parser sexp)
-  ;; sexp is [Recover [pos [inserted] [deleted] deleted-region]...]
-  ;; see ‘wisi-process-parse--execute’
-  ;; convert to list of wisi--parse-error-repair, add to last error
-  (let* ((token-table (wisi-process--parser-token-table parser))
-        (last-error (car (wisi-parser-parse-errors parser))))
-    (unless (= 1 (length sexp))
-      (cl-do ((i 1 (1+ i))) ((= i (length sexp)))
-       (push
-        (make-wisi--parse-error-repair
-         :pos (copy-marker (aref (aref sexp i) 0))
-         :inserted (mapcar (lambda (id) (aref token-table id)) (aref (aref 
sexp i) 1))
-         :deleted  (mapcar (lambda (id) (aref token-table id)) (aref (aref 
sexp i) 2))
-         :deleted-region (aref (aref sexp i) 3))
-        (wisi--parse-error-repair last-error)))
-      )))
-
-(defun wisi-process-parse--End (parser sexp)
-  ;; sexp is [End pos]
-  ;; see ‘wisi-process-parse--execute’
-  (setf (wisi-process--parser-end-pos parser) (1+ (aref sexp 1))))
-
-(defun wisi-process-parse--Edit (parser sexp)
-  ;; sexp is [Edit begin end text]
-  (delete-region (aref sexp 1) (1+ (aref sexp 2)))
-  (goto-char (aref sexp 1))
-  (insert (aref sexp 3)))
-
-(defun wisi-process-parse--Language (parser sexp)
-  ;; sexp is [Language language-action ...]
-  (funcall (aref (wisi-process--parser-language-action-table parser) (aref 
sexp 1)) sexp))
-
-(defun wisi-process-parse--execute (parser sexp)
-  "Execute encoded SEXP sent from external process."
-  ;; sexp is [action arg ...]; an encoded instruction that we need to execute
-  ;;
-  ;; Actions:
-  ;;
-  ;; [Navigate_Cache pos statement_id id length class containing_pos prev_pos 
next_pos end_pos]
-  ;;    Set a wisi-cache text-property.
-  ;;    *pos          : integer buffer position; -1 if nil (not set)
-  ;;    *id           : integer index into parser-token-table
-  ;;    length        : integer character count
-  ;;    class         : integer index into wisi-class-list
-  ;;
-  ;; [Name_Property first-pos last-pos]
-  ;;
-  ;; [Face_Property first-pos last-pos face-index]
-  ;;    Set a font-lock-face text-property
-  ;;    face-index: integer index into parser-elisp-face-table
-  ;;
-  ;; [Indent line-number indent]
-  ;;    Set an indent text property
-  ;;
-  ;; [Lexer_Error char-position <message> <repair-char>]
-  ;;    The lexer detected an error at char-position.
-  ;;
-  ;;    If <repair-char> is not ASCII NUL, it was inserted immediately
-  ;;    after char-position to fix the error.
-  ;;
-  ;; [Parser_Error char-position <message>]
-  ;;    The parser detected a syntax error; save information for later
-  ;;    reporting.
-  ;;
-  ;;    If error recovery is successful, there can be more than one
-  ;;    error reported during a parse.
-  ;;
-  ;; [Check_Error code name-1-pos name-2-pos <string>]
-  ;;    The parser detected a semantic check error; save information
-  ;;    for later reporting.
-  ;;
-  ;;    If error recovery is successful, there can be more than one
-  ;;    error reported during a parse.
-  ;;
-  ;; [Recover [pos [inserted] [deleted] deleted-region]...]
-  ;;    The parser finished a successful error recovery.
-  ;;
-  ;;    pos: Buffer position
-  ;;
-  ;;    inserted: Virtual tokens (terminal or non-terminal) inserted
-  ;;    before pos.
-  ;;
-  ;;    deleted: Tokens deleted after pos.
-  ;;
-  ;;    deleted-region: source buffer region containing deleted tokens
-  ;;
-  ;;    Args are token ids; index into parser-token-table. Save the
-  ;;    information for later use by ’wisi-repair-error’.
-  ;;
-  ;; [Edit begin end text]
-  ;;    Replace region BEGIN . END with TEXT; normally the result of a
-  ;;    refactor command.
-  ;;
-  ;; [Language ...]
-  ;;    Dispatch to a language-specific action, via
-  ;;    `wisi-process--parser-language-action-table'.
-  ;;
-  ;;
-  ;; Numeric action codes are given in the case expression below
-
-  (cl-ecase (aref sexp 0)
-    (1  (wisi-process-parse--Navigate_Cache parser sexp))
-    (2  (wisi-process-parse--Face_Property parser sexp))
-    (3  (wisi-process-parse--Indent parser sexp))
-    (4  (wisi-process-parse--Lexer_Error parser sexp))
-    (5  (wisi-process-parse--Parser_Error parser sexp))
-    (6  (wisi-process-parse--Check_Error parser sexp))
-    (7  (wisi-process-parse--Recover parser sexp))
-    (8  (wisi-process-parse--End parser sexp))
-    (9  (wisi-process-parse--Name_Property parser sexp))
-    (10 (wisi-process-parse--Edit parser sexp))
-    (11 (wisi-process-parse--Language parser sexp))
-    ))
-
-;;;;; main
-
-(cl-defmethod wisi-parse-kill ((parser wisi-process--parser))
-  (when (process-live-p (wisi-process--parser-process parser))
-    ;; We used to send a quit command first, to be nice. But there's
-    ;; no timeout on that, so it would hang when the process
-    ;; executable is not reading command input.
-    (when (process-live-p (wisi-process--parser-process parser))
-      (kill-process (wisi-process--parser-process parser)))
-    )
-  (setf (wisi-process--parser-busy parser) nil))
-
-(defvar wisi--lexer nil) ;; wisi-elisp-lexer.el
-(declare-function wisi-elisp-lexer-reset "wisi-elisp-lexer")
-
-(defun wisi-process-parse--prepare (parser)
-  ;; font-lock can trigger a face parse while navigate or indent parse
-  ;; is active, due to ‘accept-process-output’ below. Signaling an
-  ;; error tells font-lock to try again later.
-  (if (wisi-process--parser-busy parser)
-      (progn
-       (setf (wisi-parser-parse-errors parser)
-             (list
-              (make-wisi--parse-error
-               :pos 0
-               :message (format "%s:%d:%d: parser busy (try 
’wisi-kill-parser’)"
-                                (if (buffer-file-name) (file-name-nondirectory 
(buffer-file-name)) "") 1 1))
-              ))
-       (error "%s parse abandoned; parser busy - use partial parse?" 
wisi--parse-action)
-       )
-
-    ;; It is not possible for a background elisp function (ie
-    ;; font-lock) to interrupt this code between checking and setting
-    ;; parser-busy; background elisp can only run when we call
-    ;; accept-process-output below.
-    (setf (wisi-process--parser-busy parser) t)
-
-    ;; If the parser process has not started yet,
-    ;; wisi-process-parse--require-process calls
-    ;; wisi-process-parse--wait, which can let font-lock invoke the
-    ;; parser again. Thus this call must be after we set
-    ;; wisi-process--parser-busy t
-    (wisi-process-parse--require-process parser)
-
-    (setf (wisi-process--parser-total-wait-time parser) 0.0)
-    (setf (wisi-parser-lexer-errors parser) nil)
-    (setf (wisi-parser-parse-errors parser) nil)
-    ))
-
-(defun wisi-process-parse--handle-messages (parser)
-  (condition-case-unless-debug err
-      (let* ((source-buffer (current-buffer))
-            (response-buffer (wisi-process--parser-buffer parser))
-            (process (wisi-process--parser-process parser))
-            (w32-pipe-read-delay 0) ;; fastest subprocess read
-            response
-            response-end
-            (response-count 0)
-            sexp-start
-            (need-more nil) ;; point-max if need more, to check for new input
-            (done nil)
-            start-wait-time)
-
-       (set-buffer response-buffer)
-       (setq sexp-start (point-min))
-
-       ;; process responses until prompt received
-       (while (not done)
-
-         ;; process all complete responses currently in buffer
-         (while (and (not need-more)
-                     (not done))
-
-           (goto-char sexp-start)
-
-           (cond
-            ((eobp)
-             (setq need-more (point-max)))
-
-            ((looking-at wisi-process-parse-prompt)
-             (setq done t))
-
-            ((or (looking-at "\\[") ;; encoded action
-                 (looking-at "(")) ;; error or other elisp expression to eval
-             (condition-case nil
-                 (setq response-end (scan-sexps (point) 1))
-               (error
-                ;; incomplete response
-                (setq need-more (point-max))
-                nil))
-
-             (unless need-more
-               (setq response-count (1+ response-count))
-               (setq response (car (read-from-string 
(buffer-substring-no-properties (point) response-end))))
-               (goto-char response-end)
-               (forward-line 1)
-               (setq sexp-start (point))
-
-               (set-buffer source-buffer) ;; for put-text-property in actions
-               (cond
-                ((listp response)
-                 ;; non-syntax error of some sort
-                 (cond
-                  ((equal '(parse_error) response)
-                   ;; Parser detected a syntax error, and recovery failed, so 
signal it.
-
-                   (when (> wisi-debug 0)
-                     ;; Save a copy of parser output; may be overwritten by 
subsequent parse face attempts.
-                     (set-buffer response-buffer)
-                     (let ((content (buffer-substring-no-properties 
(point-min) (point-max)))
-                           (buf-name (concat (buffer-name) "-save-error")))
-                       (set-buffer (get-buffer-create buf-name))
-                       (insert content)))
-
-                   (if (wisi-parser-parse-errors parser)
-                       (signal 'wisi-parse-error
-                               (wisi--parse-error-message (car 
(wisi-parser-parse-errors parser))))
-
-                     ;; can have no errors when testing a new parser
-                     (push
-                      (make-wisi--parse-error :pos 0 :message "parser failed 
with no message")
-                      (wisi-parser-parse-errors parser))
-                     (signal 'wisi-parse-error "parser failed with no 
message")))
-
-                  ((equal 'parse_error (car response))
-                   ;; Parser detected some other error non-fatal error, so 
signal it.
-                   (push
-                    (make-wisi--parse-error :pos 0 :message (cadr response))
-                    (wisi-parser-parse-errors parser))
-                   (signal 'wisi-parse-error (cdr response)))
-
-                  ((and (eq 'error (car response))
-                        (string-prefix-p "bad command:" (cadr response)))
-                   ;; Parser dropped bytes, is treating buffer
-                   ;; content bytes as commands. Kill the process
-                   ;; to kill the pipes; there is no other way to
-                   ;; flush them.
-                   (kill-process (wisi-process--parser-process parser))
-                   (signal 'wisi-parse-error "parser lost sync; killed"))
-
-                  (t
-                   ;; Some other error
-                   (condition-case-unless-debug err
-                       (eval response)
-                     (error
-                      (push (make-wisi--parse-error :pos (point) :message 
(cadr err)) (wisi-parser-parse-errors parser))
-                      (signal (car err) (cdr err)))))
-                  ))
-
-                ((arrayp response)
-                 ;; encoded action
-                 (condition-case-unless-debug err
-                     (wisi-process-parse--execute parser response)
-                   (wisi-parse-error
-                    (push (make-wisi--parse-error :pos (point) :message (cadr 
err)) (wisi-parser-parse-errors parser))
-                    (signal (car err) (cdr err)))
-
-                   (error ;; ie from un-commented 
[C:\Windows\system32\KERNEL32.DLL], or bug in action code above.
-                    (set-buffer response-buffer)
-                    (let ((content (buffer-substring-no-properties (point-min) 
(point-max)))
-                          (buf-name (concat (buffer-name) "-save-error")))
-                      (set-buffer (get-buffer-create buf-name))
-                      (insert content)
-                      (insert (format "%s" err))
-                      (error "parser failed; error messages in %s" buf-name)))
-                   ))
-                )
-
-               (set-buffer response-buffer)
-               ))
-
-            (t
-             ;; debug output
-             (forward-line 1)
-             (setq sexp-start (point)))
-            )
-             )
-
-           (unless done
-             ;; end of response buffer
-             (unless (process-live-p process)
-               (set-buffer response-buffer)
-               (let ((content (buffer-substring-no-properties (point-min) 
(point-max)))
-                     (buf-name (concat (buffer-name) "-save-error")))
-                 (set-buffer (get-buffer-create buf-name))
-                 (insert content)
-                 (error "parser failed; error messages in %s" buf-name)))
-
-             (setq start-wait-time (float-time))
-
-             ;; If we specify no time-out here, we get messages about
-             ;; "blocking call with quit inhibited", when this is
-             ;; called by font-lock from the display engine.
-             ;;
-             ;; Specifying just-this-one t prevents C-q from
-             ;; interrupting this?
-             (accept-process-output
-              process
-              wisi-process-time-out
-              nil ;; milliseconds
-              nil)  ;; just-this-one
-
-             (setf (wisi-process--parser-total-wait-time parser)
-                   (+ (wisi-process--parser-total-wait-time parser)
-                      (- (float-time) start-wait-time)))
-
-             (when (and (= (point-max) need-more)
-                        (> (wisi-process--parser-total-wait-time parser) 
wisi-process-time-out))
-               (error "wisi-process-parse timing out; increase 
`wisi-process-time-out'? (or bad syntax in process output)"))
-
-             (setq need-more nil))
-           );; while not done
-
-         ;; got command prompt
-         (unless (process-live-p process)
-           (wisi-process-parse-show-buffer parser)
-           (error "wisi-process-parse process died"))
-
-         (setf (wisi-process--parser-response-count parser) response-count)
-
-         (setf (wisi-process--parser-busy parser) nil)
-         (set-buffer source-buffer)
-         ;; If we get here, the parse succeeded (possibly with error
-         ;; recovery); move point to end of parsed region.
-         (goto-char (wisi-process--parser-end-pos parser))
-         )
-
-      (wisi-parse-error
-       (setf (wisi-process--parser-busy parser) nil)
-       (signal (car err) (cdr err)))
-
-      (error
-       (setf (wisi-process--parser-busy parser) nil)
-       (signal (car err) (cdr err))
-       )))
-
-(cl-defmethod wisi-parse-current ((parser wisi-process--parser) begin send-end 
parse-end)
-  (wisi-process-parse--prepare parser)
-  (let ((total-line-count (1+ (count-lines (point-max) (point-min)))))
-    (setf (wisi-process--parser-line-begin parser) (wisi--set-line-begin 
total-line-count))
-    (wisi-process-parse--send-parse parser begin send-end parse-end)
-
-    ;; We reset the elisp lexer, because post-parse actions may use it.
-    (when wisi--lexer
-      (wisi-elisp-lexer-reset total-line-count wisi--lexer))
-    )
-  (wisi-process-parse--handle-messages parser)
-  (cons begin (point))
-  )
-
-(cl-defmethod wisi-refactor ((parser wisi-process--parser) refactor-action 
parse-begin parse-end edit-begin)
-  (save-excursion
-    (wisi-process-parse--prepare parser)
-    (wisi-process-parse--send-refactor parser refactor-action parse-begin 
parse-end edit-begin)
-    (wisi-process-parse--handle-messages parser))
-  )
-
-(defvar wisi--parser nil) ;; wisi.el
-
-(defun wisi-process-send-tokens-noop ()
-  "Run lexer, send tokens to subprocess; otherwise no operation.
-For use with ’wisi-time’."
-  (wisi-process-parse--require-process wisi--parser)
-  (if (wisi-process--parser-busy wisi--parser)
-      (error "%s parser busy" wisi--parse-action)
-
-    ;; not busy
-    (let* ((source-buffer (current-buffer))
-          (action-buffer (wisi-process--parser-buffer wisi--parser))
-          (process (wisi-process--parser-process wisi--parser))
-          (sexp-start (point-min))
-          (need-more nil)
-          (done nil))
-
-      (setf (wisi-process--parser-busy wisi--parser) t)
-      (wisi-process-parse--send-noop wisi--parser)
-
-      (set-buffer action-buffer)
-      (while (and (process-live-p process)
-                 (not done))
-       (goto-char sexp-start)
-       (cond
-        ((eobp)
-         (setq need-more t))
-
-        ((looking-at wisi-process-parse-prompt)
-         (setq done t))
-
-        (t
-         (forward-line 1)
-         (setq sexp-start (point)))
-        )
-
-       (unless done
-         ;; end of response buffer
-         (unless (process-live-p process)
-           (wisi-process-parse-show-buffer wisi--parser)
-           (error "wisi-process-parse process died"))
-
-         (accept-process-output process 1.0 nil nil)
-         (setq need-more nil))
-       )
-      (set-buffer source-buffer)
-      (setf (wisi-process--parser-busy wisi--parser) nil)
-      )))
-
-;;;;; debugging
-(defun wisi-process-parse-ids-to-enum (token-table &rest int-ids)
-  "Translate INT-IDS from process integer token ids to elisp enumeral ids.
-Returns reversed sequence."
-  (let ((enum-ids nil))
-    (cl-dolist (i int-ids)
-      (push (aref token-table i) enum-ids))
-    enum-ids))
-
-(defun wisi-process-parse-show-args ()
-  "Show the partial parse command-line args for run_ada_[lalr | lr1]_parse for 
current region.
-Also add it to the kill ring."
-  (interactive)
-  (let* ((begin (region-beginning))
-        (end   (region-end))
-        (parse-action (wisi-read-parse-action))
-        (msg
-         (format "%s %s %d %d %d %d %d %d %d"
-                 (file-name-nondirectory (buffer-file-name))
-                 parse-action
-                 (position-bytes begin)
-                 (position-bytes end)
-                 (position-bytes end)
-                 begin ;; char_pos
-                 (line-number-at-pos begin)
-                 (line-number-at-pos end)
-                 (save-excursion (goto-char begin) (back-to-indentation) 
(current-column));; indent-begin
-                 )))
-    (kill-new msg)
-    (message msg)))
-
-(provide 'wisi-process-parse)
diff --git a/packages/wisi/wisi-run-indent-test.el 
b/packages/wisi/wisi-run-indent-test.el
deleted file mode 100644
index 8c0eef0..0000000
--- a/packages/wisi/wisi-run-indent-test.el
+++ /dev/null
@@ -1,399 +0,0 @@
-;;; wisi-run-indent-test.el --- utils for automating indentation and casing 
tests
-;;
-;; Copyright (C) 2018 - 2020  Free Software Foundation, Inc.
-;;
-;; This file is part of GNU Emacs.
-;;
-;; GNU Emacs 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 3 of the License, or
-;; (at your option) any later version.
-;;
-;; GNU Emacs 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 GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.
-
-(require 'wisi-tests)
-(require 'wisi-prj)
-
-;; user can set these to t in an EMACSCMD
-(defvar skip-cmds nil)
-(defvar skip-reindent-test nil)
-(defvar skip-recase-test nil)
-(defvar skip-write nil)
-
-(defun test-in-comment-p ()
-  (nth 4 (syntax-ppss)))
-
-(defun test-face (token face)
-  "Test if all of TOKEN in next code line has FACE.
-FACE may be a list."
-  (save-excursion
-    (when (test-in-comment-p)
-      (beginning-of-line); forward-comment doesn't move if inside a comment!
-      (forward-comment (point-max)))
-    (condition-case err
-       (search-forward token (line-end-position 5))
-      (error
-       (error "can't find '%s'" token)))
-
-    (save-match-data
-      (wisi-validate-cache (line-beginning-position) (line-end-position) nil 
'face)
-      (font-lock-ensure (line-beginning-position) (line-end-position)))
-    
-    ;; We don't use face-at-point, because it doesn't respect
-    ;; font-lock-face set by the parser! And we want to check for
-    ;; conflicts between font-lock-keywords and the parser.
-
-    ;; font-lock-keywords sets 'face property, parser sets 'font-lock-face.
-
-    ;; In emacs < 27, if we use (get-text-property (point) 'face), we
-    ;; also get 'font-lock-face, but not vice-versa. So we have to use
-    ;; text-properties-at to check for both.
-    (let* ((token (match-string 0))
-          (props (text-properties-at (match-beginning 0)))
-          key
-          token-face)
-
-      (cond
-       ((plist-get props 'font-lock-face)
-       (setq key 'font-lock-face)
-       (setq token-face (plist-get props 'font-lock-face)))
-
-       ((plist-get props 'face)
-       (setq key 'face)
-       (setq token-face (plist-get props 'face)))
-       )
-
-      (when (and (memq 'font-lock-face props)
-                (memq 'face props))
-       (describe-text-properties (match-beginning 0))
-       (error "mixed font-lock-keyword and parser faces for '%s'" token))
-
-      (unless (not (text-property-not-all 0 (length token) key token-face 
token))
-       (error "mixed faces, expecting %s for '%s'" face token))
-
-      (unless (or (and (listp face)
-                      (memq token-face face))
-                 (eq token-face face))
-       (error "found face %s, expecting %s for '%s'" token-face face token))
-    )))
-
-(defun test-face-1 (search token face)
-  "Move to end of comment, search for SEARCH, call `test-face'."
-  (save-excursion
-    (when (test-in-comment-p)
-      (beginning-of-line); forward-comment doesn't move if inside a comment!
-      (forward-comment (point-max)))
-    (search-forward search)
-    (test-face token face)
-    ))
-
-(defun test-cache-class (token class)
-  "Test if TOKEN in next code line has wisi-cache with class CLASS."
-  (save-excursion
-    (wisi-validate-cache (line-beginning-position 0) (line-end-position 3) nil 
'navigate)
-    (beginning-of-line); forward-comment doesn't move if inside a comment!
-    (forward-comment (point-max))
-    (condition-case err
-       (search-forward token (line-end-position 5))
-      (error
-       (error "can't find '%s'" token)))
-
-    (let ((cache (get-text-property (match-beginning 0) 'wisi-cache)))
-
-      (unless cache (error "no cache"))
-      (unless (eq (wisi-cache-class cache) class)
-       (error "expecting class %s, found '%s'" class (wisi-cache-class cache)))
-    )))
-
-(defun test-cache-containing (containing contained)
-  "Test if CONTAINING in next code line has wisi-cache with that contains 
CONTAINED."
-  (save-excursion
-    (wisi-validate-cache (line-beginning-position 0) (line-end-position 3) nil 
'navigate)
-    (beginning-of-line)
-    (forward-comment (point-max))
-    (let (containing-pos contained-cache)
-      (search-forward containing (line-end-position 5))
-      (setq containing-pos (match-beginning 0))
-
-      (search-forward contained (line-end-position 5))
-      (setq contained-cache (get-text-property (match-beginning 0) 
'wisi-cache))
-
-      (unless contained-cache (error "no cache on %s" contained))
-      (unless (= containing-pos (wisi-cache-containing contained-cache))
-       (error "expecting %d, got %d" containing-pos (wisi-cache-containing 
contained-cache)))
-    )))
-
-(defvar test-refactor-markers nil
-  "Stores positions altered by `test-refactor-1' for `test-refactor-2'.
-Each item is a list (ACTION PARSE-BEGIN PARSE-END EDIT-BEGIN)")
-
-(defun test-refactor-1 (action inverse-action search-string refactor-string)
-  (beginning-of-line)
-  (forward-comment (point-max)) ;; forward-comment does not work from inside 
comment
-  (search-forward search-string (line-end-position 7))
-  (wisi-validate-cache (line-end-position -7) (line-end-position 7) t 
'navigate)
-  (search-forward refactor-string (line-end-position 7))
-  (let* ((edit-begin (match-beginning 0))
-        (cache (wisi-goto-statement-start))
-        (parse-begin (point))
-        (parse-end (wisi-cache-end cache)))
-    (setq parse-end (+ parse-end (wisi-cache-last (wisi-get-cache 
(wisi-cache-end cache)))))
-    (push (list
-          inverse-action
-          (copy-marker parse-begin nil)
-          (copy-marker parse-end nil)
-          (copy-marker edit-begin nil))
-         test-refactor-markers)
-    (wisi-refactor wisi--parser action parse-begin parse-end edit-begin)
-    ))
-
-(defun test-refactor-inverse ()
-  "Reverse refactors done by recent set of `test-refactor-1'."
-  (save-excursion
-    (condition-case-unless-debug nil
-       (dolist (item test-refactor-markers)
-         (wisi-refactor wisi--parser
-                        (nth 0 item)
-                        (marker-position (nth 1 item))
-                        (marker-position (nth 2 item))
-                        (marker-position (nth 3 item))))
-      (error nil))
-    (setq test-refactor-markers nil)))
-
-(defun run-test-here ()
-  "Run an indentation and casing test on the current buffer."
-  (interactive)
-  (setq indent-tabs-mode nil)
-  (setq jit-lock-context-time 0.0);; for test-face
-
-  ;; Test files use wisi-prj-select-cached to parse and select a project file.
-  (setq project-find-functions (list #'wisi-prj-current-cached))
-  (setq xref-backend-functions (list #'wisi-prj-xref-backend))
-
-
-  (let ((error-count 0)
-       (test-buffer (current-buffer))
-       cmd-line
-       last-result last-cmd expected-result)
-    ;; Look for EMACS* comments in the file:
-    ;;
-    ;; EMACSCMD: <form>
-    ;;    Executes the lisp form inside a save-excursion, saves the result as 
a lisp object.
-    ;;
-    ;; EMACSRESULT: <form>
-    ;;    point is moved to end of line, <form> is evaluated inside
-    ;;    save-excursion and compared (using `equal') with the result
-    ;;    of the previous EMACSCMD, and the test fails if they don't
-    ;;    match.
-    ;;
-    ;; EMACSRESULT_START:<first list element>
-    ;; EMACSRESULT_ADD:  <list element>
-    ;; EMACSRESULT_FINISH:
-    ;;    build a list, compare it to the result of the previous EMACSCMD.
-    ;;
-    ;; EMACS_SKIP_UNLESS: <form>
-    ;;   skip entire test if form evals nil
-    ;;
-    ;; EMACSDEBUG: <form>
-    ;;    Eval form, display result. Also used for setting breakpoint.
-
-    (goto-char (point-min))
-    (while (and (not skip-cmds)
-               (re-search-forward (concat comment-start "EMACS\\([^:]+\\):") 
nil t))
-      (cond
-       ((string= (match-string 1) "CMD")
-       (looking-at ".*$")
-       (save-excursion
-         (setq cmd-line (line-number-at-pos)
-               last-cmd (match-string 0)
-               last-result
-               (condition-case-unless-debug err
-                   (eval (car (read-from-string last-cmd)))
-                 (error
-                    (setq error-count (1+ error-count))
-                    (message "%s:%d: command: %s"
-                             (buffer-file-name) cmd-line last-cmd)
-                    (message "%s:%d: %s: %s"
-                             (buffer-file-name)
-                             (line-number-at-pos)
-                             (car err)
-                             (cdr err))))
-               )
-         ;; save-excursion does not preserve mapping of buffer to
-         ;; window, but some tests depend on that. For example,
-         ;; execute-kbd-macro doesn’t work properly if current buffer
-         ;; is not visible..
-         (pop-to-buffer test-buffer)))
-
-       ((string= (match-string 1) "RESULT")
-       (looking-at ".*$")
-       (setq expected-result (save-excursion (end-of-line 1) (eval (car 
(read-from-string (match-string 0))))))
-       (unless (equal expected-result last-result)
-         (setq error-count (1+ error-count))
-         (message
-          (concat
-           (format "error: %s:%d:\n" (buffer-file-name) (line-number-at-pos))
-           (format "Result of '%s' does not match.\nGot    '%s',\nexpect '%s'"
-                   last-cmd
-                   last-result
-                   expected-result)
-           ))))
-
-       ((string= (match-string 1) "RESULT_START")
-       (looking-at ".*$")
-       (setq expected-result (list (save-excursion (end-of-line 1) (eval (car 
(read-from-string (match-string 0))))))))
-
-       ((string= (match-string 1) "RESULT_ADD")
-       (looking-at ".*$")
-       (let ((val (save-excursion (end-of-line 1)
-                                  (eval (car (read-from-string (match-string 
0)))))))
-         (when val
-           (setq expected-result (append expected-result (list val))))))
-
-       ((string= (match-string 1) "RESULT_FINISH")
-       (unless (equal (length expected-result) (length last-result))
-         (setq error-count (1+ error-count))
-         (message
-          (concat
-           (format "error: %s:%d:\n" (buffer-file-name) (line-number-at-pos))
-           (format "Length of result of '%s' does not match.\nGot    
'%s',\nexpect '%s'"
-                   last-cmd
-                   (length last-result)
-                   (length expected-result)))))
-
-       (let ((i 0))
-         (while (< i (length expected-result))
-           (unless (equal (nth i expected-result) (nth i last-result))
-             (setq error-count (1+ error-count))
-             (message
-              (concat
-               (format "error: %s:%d:\n" (buffer-file-name) 
(line-number-at-pos))
-               (format "Nth (%d) result of '%s' does not match.\nGot    
'%s',\nexpect '%s'"
-                       i
-                       last-cmd
-                       (nth i last-result)
-                       (nth i expected-result))
-               )))
-           (setq i (1+ i)))))
-
-       ((string= (match-string 1) "_SKIP_UNLESS")
-       (looking-at ".*$")
-       (unless (eval (car (read-from-string (match-string 0))))
-         (setq skip-cmds t)
-         (setq skip-reindent-test t)
-         (setq skip-recase-test t)
-         ;; We don’t set ‘skip-write’ t here, so the *.diff Make target 
succeeds.
-         ))
-
-       ((string= (match-string 1) "DEBUG")
-       (looking-at ".*$")
-       (message "DEBUG: %s:%d %s"
-                (current-buffer)
-                (line-number-at-pos)
-                (save-excursion
-                 (eval (car (read-from-string (match-string 0)))))))
-
-       (t
-       (setq error-count (1+ error-count))
-       (error (concat "Unexpected EMACS test command " (match-string 1))))))
-
-    (when (> error-count 0)
-      (error
-       "%s:%d: aborting due to previous errors (%d)"
-       (buffer-file-name) (line-number-at-pos (point)) error-count))
-    )
-
-  (unless skip-reindent-test
-    ;; Reindent the buffer
-    (message "indenting")
-
-    ;; first unindent; if the indentation rules do nothing, the test
-    ;; would pass, otherwise!  Only unindent by 1 column, so comments
-    ;; not currently in column 0 are still not in column 0, in case
-    ;; the mode supports a special case for comments in column 0.
-    (indent-rigidly (point-min) (point-max) -1)
-
-    ;; indent-region uses save-excursion, so we can't goto an error location
-    (indent-region (point-min) (point-max))
-
-    ;; Cleanup the buffer; indenting often leaves trailing whitespace;
-    ;; files must be saved without any.
-    (delete-trailing-whitespace)
-    )
-
-  (when (and wisi-auto-case (not skip-recase-test))
-    (message "casing")
-    (wisi-case-adjust-buffer))
-  )
-
-(defvar cl-print-readably); cl-print.el, used by edebug
-
-(defun large-frame ()
-  (interactive)
-  (modify-frame-parameters
-      nil
-      (list
-       (cons 'width 120) ;; characters; fringe extra
-       (cons 'height 71) ;; characters
-       (cons 'left 0) ;; pixels
-       (cons 'top 0))))
-(define-key global-map "\C-cp" 'large-screen)
-
-(defun run-test (file-name)
-  "Run an indentation and casing test on FILE-NAME."
-  (interactive "f")
-
-  (package-initialize) ;; for uniquify-files
-
-  ;; Let edebug display strings full-length, and show internals of records
-  (setq cl-print-readably t)
-
-  ;; we'd like to run emacs from a makefile as:
-  ;;
-  ;; emacs -Q --batch -l runtest.el -f run-test-here <filename>
-  ;;
-  ;; However, the function specified with -f is run _before_
-  ;; <filename> is visited. So we try this instead:
-  ;;
-  ;; emacs -Q --batch -l runtest.el --eval '(run-test "<filename>")'
-  ;;
-  ;; And then we discover that processes spawned with start-process
-  ;; don't run when emacs is in --batch mode. So we try this:
-  ;;
-  ;; emacs -Q -l runtest.el --eval '(progn (run-test 
"<filename>")(kill-emacs))'
-  ;;
-  ;; Then we have problems with font lock defaulting to jit-lock; that
-  ;; screws up font-lock tests because the test runs before jit-lock
-  ;; does. This forces default font-lock, which fontifies the whole
-  ;; buffer when (font-lock-fontify-buffer) is called, which tests
-  ;; that rely on font-lock do explicitly.
-  (setq font-lock-support-mode nil)
-
-  (setq xref-prompt-for-identifier nil)
-
-  (let ((dir default-directory))
-    (find-file file-name) ;; sets default-directory
-
-    (run-test-here)
-
-    (unless skip-write
-      ;; Write the result file; makefile will diff.
-      (when skip-reindent-test
-       ;; user sets skip-reindent-test when testing interactive editing
-       ;; commands, so the diff would fail. Revert to the original file,
-       ;; save a copy of that.
-       (revert-buffer t t))
-
-      (delete-trailing-whitespace)
-      (write-file (concat dir (file-name-nondirectory file-name) ".tmp")) )
-    )
-  )
-
-(provide 'wisi-run-indent-test)
-;; end of file
diff --git a/packages/wisi/wisi-skel.el b/packages/wisi/wisi-skel.el
deleted file mode 100644
index 9af5b9b..0000000
--- a/packages/wisi/wisi-skel.el
+++ /dev/null
@@ -1,187 +0,0 @@
-;;; wisi-skel.el --- Extensions skeleton  -*- lexical-binding:t -*-
-
-;; Copyright (C) 1987, 1993, 1994, 1996-2020  Free Software Foundation, Inc.
-
-;; Authors: Stephen Leake <stephen_leake@stephe-leake.org>
-
-;; This file is part of GNU Emacs.
-
-;; GNU Emacs 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 3 of the License, or
-;; (at your option) any later version.
-
-;; GNU Emacs 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 GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.
-
-;;; Design:
-;;
-;; The primary user command is `wisi-skel-expand', which inserts the
-;; skeleton associated with the previous word (possibly skipping a
-;; name).
-
-(require 'skeleton)
-
-(defvar-local wisi-skel-token-alist nil
-  "Alist of (STRING . ELEMENT), used by `wisi-skel-expand'.
-STRING should be a grammar symbol in the current language.
-
-ELEMENT may be:
-- a skeleton, which is inserted
-- an alist of (STRING . SKELETON). User is prompted with `completing-read',
-  selected skeleton is inserted.")
-
-(defun wisi-skel-add-token-after (alist token skel after-1 &optional after-2)
-  "Add a new entry in ALIST (should be an instance of `wisi-skel-token-alist')
-after AFTER-1. If AFTER-1 is a nested alist, add the new entry after AFTER-2."
-  (let ((tail alist)
-       done)
-    (if (string= after-1 (car (car alist)))
-       (setcdr alist (cons (cons token skel) (cdr alist)))
-
-      (while (and (not done) tail)
-       (if (string= after-1 (car-safe (car (cdr tail))))
-           (cond
-            ((symbolp (cdr (car (cdr tail))))
-             (setcdr tail (cons (cons token skel) (cdr (cdr tail))))
-             (setq done t))
-
-            ((consp (cdr (car (cdr tail))))
-             (wisi-skel-add-token-after (cdr (car (cdr tail))) token skel 
after-2)
-             (setq done t))
-            )
-         ;; else
-         (setq tail (cdr tail))
-         ))
-      )))
-
-(defun wisi-skel-build-prompt (alist count)
-  "Build a prompt from the keys of the ALIST.
-The prompt consists of the first COUNT keys from the alist, separated by `|', 
with
-trailing `...' if there are more keys."
-  (if (>= count (length alist))
-      (concat (mapconcat 'car alist " | ") " : ")
-    (let ((alist-1 (butlast alist (- (length alist) count))))
-      (concat (mapconcat 'car alist-1 " | ") " | ... : "))
-  ))
-
-(defvar wisi-skel-test-input nil
-  "Override prompt for input from wisi-skel-token-alist, for unit testing."
-  ;; see test/ada_skel.adb
-  )
-
-(defun wisi-skel-expand (&optional name)
-  "Expand the token or placeholder before point to a skeleton.
-Tokens are defined by `wisi-skel-token-alist'; they must have
-symbol syntax.  A placeholder is a token enclosed in generic
-comment delimiters.  If the symbol before point is not in
-`wisi-skel-token-alist', assume it is a name, and use the symbol
-before that as the token."
-  (interactive "*")
-
-  ;; Skip trailing space, newline, and placeholder delimiter.
-  ;; Standard comment end included for languages where that is newline.
-  (skip-syntax-backward " !>")
-
-  (let* ((wisi-inhibit-parse t) ;; don't parse until skeleton is fully inserted
-        (end (point))
-        ;; Include punctuation here, to handle a dotted name (ie Ada.Text_IO)
-        (token (progn (skip-syntax-backward "w_.")
-                      (downcase (buffer-substring-no-properties (point) end))))
-        (skel (assoc-string token wisi-skel-token-alist))
-        (handled nil))
-
-    (if skel
-       (progn
-         (when (listp (cdr skel))
-           (let* ((alist (cdr skel))
-                  (prompt (wisi-skel-build-prompt alist 4)))
-             (setq skel (assoc-string
-                         (or wisi-skel-test-input (completing-read prompt 
alist))
-                         alist))
-             ))
-
-         ;; delete placeholder delimiters around token, token, and
-         ;; name. point is currently before token.
-         (skip-syntax-backward "!")
-         (delete-region
-          (point)
-          (progn
-            (skip-syntax-forward "!w_")
-            (when name
-              (skip-syntax-forward " ")
-              (skip-syntax-forward "w_."))
-            (point)))
-         (let ((skeleton-end-newline nil))
-           (funcall (cdr skel) name))
-         (setq handled t))
-
-      ;; word in point .. end is not a token; assume it is a name
-      (when (not name)
-       ;; avoid infinite recursion
-
-       (when wisi-auto-case
-         ;; Adjust case now, because skeleton insert won't.
-         ;;
-         ;; We didn't do it above, because we don't want to adjust case
-         ;; on tokens and placeholders.
-         (save-excursion (wisi-case-adjust-region (point) end)))
-
-       (condition-case-unless-debug nil
-           (progn
-             (wisi-skel-expand (buffer-substring-no-properties (point) end))
-             (setq handled t))
-         (user-error ;; leave handled nil
-          ))
-       ))
-
-    (when (not handled)
-      (setq name (buffer-substring-no-properties (point) end))
-      ;; restore point
-      (goto-char end)
-      (user-error "'%s' is not a skeleton token" name))
-    ))
-
-;;;###autoload
-(defun wisi-skel-hippie-try (old)
-  "For `hippie-expand-try-functions-list'."
-  (if old
-      ;; hippie is asking us to try the "next" completion; we don't have one
-      nil
-    (let ((pos (point))
-         (undo-len (if (eq 't pending-undo-list)
-                       0
-                     (length pending-undo-list))))
-      (undo-boundary)
-      (condition-case nil
-         (progn
-           (wisi-skel-expand)
-           t)
-       (error
-        ;; undo hook action if any
-        (unless (or (eq 't pending-undo-list)
-                    (= undo-len (length pending-undo-list)))
-          (undo))
-
-        ;; undo motion
-        (goto-char pos)
-        nil)))))
-
-(defun wisi-skel-next-placeholder ()
-  "Move point to after next placeholder."
-  (interactive)
-  (skip-syntax-forward "^!")
-  (skip-syntax-forward "w_!"))
-
-(defun wisi-skel-prev-placeholder ()
-  "Move point to after previous placeholder."
-  (interactive)
-  (skip-syntax-backward "^!"))
-
-(provide 'wisi-skel)
-;;; wisi-skel.el ends here
diff --git a/packages/wisi/wisi-tests.el b/packages/wisi/wisi-tests.el
deleted file mode 100644
index b730cf1..0000000
--- a/packages/wisi/wisi-tests.el
+++ /dev/null
@@ -1,120 +0,0 @@
-;;; wisi-tests.el --- Common utils for wisi tests -*- lexical-binding:t -*-
-;;
-;; Copyright (C) 2012 - 2019  Free Software Foundation, Inc.
-;;
-;; Author: Stephen Leake <stephen_leake@stephe-leake.org>
-;; Maintainer: Stephen Leake <stephen_leake@stephe-leake.org>
-;;
-;; This file is part of GNU Emacs.
-;;
-;; GNU Emacs 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 3 of the License, or
-;; (at your option) any later version.
-;;
-;; GNU Emacs 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 GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.
-;;
-
-(require 'cl-lib)
-(require 'wisi)
-
-(defvar wisi-test-parser 'process
-  "Set to ’process to test external process parser.")
-
-(defvar test-syntax-table
-  (let ((table (make-syntax-table)))
-    ;; make-syntax-table sets all alphanumeric to w, etc; so we only
-    ;; have to add test-specific things.
-
-    ;; operator symbols
-    (modify-syntax-entry ?&  "." table)
-    (modify-syntax-entry ?*  "." table)
-    (modify-syntax-entry ?+  "." table)
-    (modify-syntax-entry ?-  "." table)
-    (modify-syntax-entry ?/  "." table)
-    (modify-syntax-entry ?<  "." table)
-    (modify-syntax-entry ?=  "." table)
-    (modify-syntax-entry ?>  "." table)
-    (modify-syntax-entry ?|  "." table)
-
-    ;; \f and \n end a comment - see test-syntax-propertize for comment start
-    (modify-syntax-entry ?\f  ">   " table)
-    (modify-syntax-entry ?\n  ">   " table)
-    table
-    ))
-
-(defun test-syntax-propertize (start end)
-  "Assign `syntax-table' properties in accessible part of buffer."
-  ;; (info "(elisp)Syntax Properties")
-  (let ((modified (buffer-modified-p))
-       (buffer-undo-list t)
-       (inhibit-read-only t)
-       (inhibit-point-motion-hooks t)
-       (inhibit-modification-hooks t))
-    (goto-char start)
-    (while (re-search-forward
-            "\\(--\\)"; 1: comment start
-           end t)
-      ;; The help for syntax-propertize-extend-region-functions
-      ;; implies that 'start end' will always include whole lines, in
-      ;; which case we don't need
-      ;; syntax-propertize-extend-region-functions
-      (cond
-       ((match-beginning 1)
-       (put-text-property
-        (match-beginning 1) (match-end 1) 'syntax-table '(11 . nil)))
-       ))
-    (unless modified
-      (restore-buffer-modified-p nil))))
-
-(defun wisi-tests-setup (grammar-name)
-  ;; grammar-elisp file must be on load-path
-  ;; use Ada style comments in source
-  (set-syntax-table test-syntax-table)
-  (set (make-local-variable 'syntax-propertize-function) 
'test-syntax-propertize)
-  (syntax-ppss-flush-cache (point-min));; force re-evaluate with hook.
-
-  (cl-ecase wisi-test-parser
-    (process
-     (require 'wisi-process-parse)
-     (require (intern (concat grammar-name "-process"))) ;; generated by 
wisi-generate
-     (require (intern grammar-name)) ;; declares parser cl-defstruct
-     (add-to-list 'exec-path default-directory)
-     (wisi-setup
-      :indent-calculate nil
-      :post-indent-fail nil
-      :parser
-      (wisi-process-parse-get
-       (funcall
-       (intern-soft (concat "make-" grammar-name "-wisi-parser"))
-       :label grammar-name
-       :exec-file (concat grammar-name "_wisi_parse.exe")
-       :face-table (symbol-value (intern-soft (concat grammar-name 
"-process-face-table")))
-       :token-table (symbol-value (intern-soft (concat grammar-name 
"-process-token-table")))
-       )))
-     (setq wisi-mckenzie-disable nil)
-     )
-    )
-
-  ;; Not clear why this is not being done automatically
-  (syntax-propertize (point-max))
-  )
-
-;;; Initialization
-
-;; Default includes mtn, among others, which is broken in Emacs 22.2
-(setq vc-handled-backends '(CVS))
-
-(setq eval-expression-debug-on-error nil)
-
-;; ’package-initialize’ is not here; it must be run as part of one of the
-;; -l or --eval command line options
-
-(provide 'wisi-tests)
-;; end of file
diff --git a/packages/wisi/wisi.adb b/packages/wisi/wisi.adb
deleted file mode 100644
index 91dacab..0000000
--- a/packages/wisi/wisi.adb
+++ /dev/null
@@ -1,2434 +0,0 @@
---  Abstract :
---
---  See spec.
---
---  Copyright (C) 2017 - 2020 Free Software Foundation, Inc.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-with Ada.Exceptions;
-with Ada.Strings.Bounded;
-with Ada.Strings.Unbounded;
-with Ada.Text_IO;
-with SAL;
-with WisiToken.Semantic_Checks;
-package body Wisi is
-   use WisiToken;
-
-   Chars_Per_Int : constant Integer := Integer'Width;
-
-   ----------
-   --  body subprogram specs (as needed), alphabetical
-
-   function Indent_Nil_P (Indent : in Indent_Type) return Boolean;
-
-   function Max_Anchor_ID
-     (Data       : in out Parse_Data_Type;
-      First_Line : in     Line_Number_Type;
-      Last_Line  : in     Line_Number_Type)
-     return Integer;
-
-   function Paren_In_Anchor_Line
-     (Data         : in out Parse_Data_Type'Class;
-      Tree         : in     Syntax_Trees.Tree'Class;
-      Anchor_Token : in     Augmented_Token;
-      Offset       : in     Integer)
-     return Integer;
-
-   ----------
-   --  body subprograms bodies, alphabetical
-
-   procedure Adjust_Paren_State
-     (Data              : in out Parse_Data_Type;
-      Tree              : in     Syntax_Trees.Tree'Class;
-      First_Token_Index : in     Token_Index;
-      First_Line        : in     Line_Number_Type;
-      Adjust            : in     Integer)
-   is begin
-      for I in First_Token_Index .. Data.Terminals.Last_Index loop
-         declare
-            Aug : Augmented_Token renames Get_Aug_Token_Var (Data, Tree, I);
-         begin
-            Aug.Paren_State := Aug.Paren_State + Adjust;
-         end;
-      end loop;
-
-      for Line in First_Line .. Data.Line_Paren_State.Last_Index loop
-         Data.Line_Paren_State (Line) := Data.Line_Paren_State (Line) + Adjust;
-      end loop;
-   end Adjust_Paren_State;
-
-   function Image (Aug : in WisiToken.Base_Token_Class_Access; Descriptor : in 
WisiToken.Descriptor) return String
-   is begin
-      return Image (Augmented_Token_Access (Aug).all, Descriptor);
-   end Image;
-
-   function Image (Action : in WisiToken.Syntax_Trees.Semantic_Action) return 
String
-   is
-      pragma Unreferenced (Action);
-   begin
-      return "action";
-   end Image;
-
-   function Image (Anchor_IDs : in Anchor_ID_Vectors.Vector) return String
-   is
-      use Ada.Strings.Unbounded;
-      Result : Unbounded_String := +"(";
-   begin
-      for I in Anchor_IDs.First_Index .. Anchor_IDs.Last_Index loop
-         Result := Result & Integer'Image (Anchor_IDs (I));
-         if I /= Anchor_IDs.Last_Index then
-            Result := Result & ", ";
-         else
-            Result := Result & ")";
-         end if;
-      end loop;
-      return -Result;
-   end Image;
-
-   function Image (Indent : in Indent_Type) return String
-   is begin
-      case Indent.Label is
-      when Not_Set =>
-         return "(" & Indent_Label'Image (Indent.Label) & ")";
-
-      when Int =>
-         return "(" & Indent_Label'Image (Indent.Label) & Integer'Image 
(Indent.Int_Indent) & ")";
-
-      when Anchor_Nil =>
-         return "(" & Indent_Label'Image (Indent.Label) & ", " & Image 
(Indent.Anchor_Nil_IDs) & ", nil)";
-
-      when Anchor_Int =>
-         return "(" & Indent_Label'Image (Indent.Label) & ", " & Image 
(Indent.Anchor_Int_IDs) & ", " & Integer'Image
-           (Indent.Anchor_Int_Indent) & ")";
-
-      when Anchored =>
-         return "(" & Indent_Label'Image (Indent.Label) & ", " & Integer'Image 
(Indent.Anchored_ID) & ", " &
-           Integer'Image (Indent.Anchored_Delta) & ")";
-
-      when Anchor_Anchored =>
-         return "(" & Indent_Label'Image (Indent.Label) & ", " & Image 
(Indent.Anchor_Anchored_IDs) & Integer'Image
-           (Indent.Anchor_Anchored_ID) & ", " & Integer'Image 
(Indent.Anchor_Anchored_Delta) & ")";
-      end case;
-   end Image;
-
-   procedure Indent_Apply_Anchored
-     (Delta_Indent : in     Simple_Delta_Type;
-      Indent       : in out Indent_Type)
-   with Pre => Delta_Indent.Label = Anchored
-   is begin
-      --  Add Delta_Indent to Indent
-
-      case Indent.Label is
-      when Not_Set =>
-         Indent := (Anchored, Delta_Indent.Anchored_ID, 
Delta_Indent.Anchored_Delta);
-
-      when Int =>
-         if Delta_Indent.Anchored_Accumulate then
-            Indent := (Anchored, Delta_Indent.Anchored_ID, Indent.Int_Indent + 
Delta_Indent.Anchored_Delta);
-         end if;
-
-      when Anchor_Nil =>
-         Indent :=
-           (Anchor_Anchored,
-            Indent.Anchor_Nil_IDs,
-            Delta_Indent.Anchored_ID,
-            Delta_Indent.Anchored_Delta);
-
-      when Anchor_Int =>
-         if Delta_Indent.Anchored_Accumulate then
-            Indent :=
-              (Anchor_Anchored,
-               Indent.Anchor_Int_IDs,
-               Delta_Indent.Anchored_ID,
-               Delta_Indent.Anchored_Delta + Indent.Anchor_Int_Indent);
-         end if;
-
-      when Anchored | Anchor_Anchored =>
-         --  already anchored
-         null;
-      end case;
-   end Indent_Apply_Anchored;
-
-   procedure Indent_Apply_Int (Indent : in out Indent_Type; Offset : in 
Integer)
-   is begin
-      --  Add an Int indent to Indent
-      case Indent.Label is
-      when Not_Set =>
-         Indent := (Int, Offset);
-
-      when Int =>
-         Indent.Int_Indent := Indent.Int_Indent + Offset;
-
-      when Anchor_Nil         =>
-         Indent :=
-           (Label             => Anchor_Int,
-            Anchor_Int_IDs    => Indent.Anchor_Nil_IDs,
-            Anchor_Int_Indent => Offset);
-
-      when Anchor_Int =>
-         Indent.Anchor_Int_Indent := Indent.Anchor_Int_Indent + Offset;
-
-      when Anchored | Anchor_Anchored =>
-         null;
-      end case;
-   end Indent_Apply_Int;
-
-   procedure Indent_Line
-     (Data         : in out Parse_Data_Type;
-      Line         : in     Line_Number_Type;
-      Delta_Indent : in     Delta_Type)
-   is
-      --  See note in Indent_Anchored_2 for why we can't use renames here.
-      Indent : Indent_Type := Data.Indents (Line);
-   begin
-      case Delta_Indent.Label is
-      when Simple =>
-         case Delta_Indent.Simple_Delta.Label is
-         when None =>
-            null;
-
-         when Int =>
-            Indent_Apply_Int (Indent, Delta_Indent.Simple_Delta.Int_Delta);
-
-         when Anchored =>
-            Indent_Apply_Anchored (Delta_Indent.Simple_Delta, Indent);
-         end case;
-
-      when Hanging =>
-         if Delta_Indent.Hanging_Accumulate or Indent_Nil_P (Data.Indents 
(Line)) then
-            if Line = Delta_Indent.Hanging_First_Line then
-               --  Apply delta_1
-               case Delta_Indent.Hanging_Delta_1.Label is
-               when None =>
-                  null;
-               when Int =>
-                  Indent_Apply_Int (Indent, 
Delta_Indent.Hanging_Delta_1.Int_Delta);
-               when Anchored =>
-                  Indent_Apply_Anchored (Delta_Indent.Hanging_Delta_1, Indent);
-               end case;
-            else
-               if Delta_Indent.Hanging_Paren_State = Data.Line_Paren_State 
(Line) then
-                  case Delta_Indent.Hanging_Delta_2.Label is
-                  when None =>
-                     null;
-                  when Int =>
-                     Indent_Apply_Int (Indent, 
Delta_Indent.Hanging_Delta_2.Int_Delta);
-                  when Anchored =>
-                     Indent_Apply_Anchored (Delta_Indent.Hanging_Delta_2, 
Indent);
-                  end case;
-               end if;
-            end if;
-         end if;
-      end case;
-
-      if Trace_Action > Extra then
-         Ada.Text_IO.Put_Line (";; indent_line: " & Line_Number_Type'Image 
(Line) & " => " & Image (Indent));
-      end if;
-
-      Data.Indents.Replace_Element (Line, Indent);
-   end Indent_Line;
-
-   function Indent_Nil_P (Indent : in Indent_Type) return Boolean
-   is begin
-      return Indent.Label in Not_Set | Anchor_Nil;
-   end Indent_Nil_P;
-
-   function Max_Anchor_ID
-     (Data       : in out Parse_Data_Type;
-      First_Line : in     Line_Number_Type;
-      Last_Line  : in     Line_Number_Type)
-     return Integer
-   is
-      Result : Integer := First_Anchor_ID - 1;
-   begin
-      for Line in First_Line .. Last_Line loop
-         declare
-            Indent : Indent_Type renames Data.Indents (Line);
-         begin
-            case Indent.Label is
-            when Not_Set | Int =>
-               null;
-            when Anchor_Nil =>
-               Result := Integer'Max (Result, Indent.Anchor_Nil_IDs 
(Indent.Anchor_Nil_IDs.First_Index));
-            when Anchor_Int =>
-               Result := Integer'Max (Result, Indent.Anchor_Int_IDs 
(Indent.Anchor_Int_IDs.First_Index));
-            when Anchored =>
-               Result := Integer'Max (Result, Indent.Anchored_ID);
-            when Anchor_Anchored =>
-               Result := Integer'Max (Result, Indent.Anchor_Anchored_ID);
-            end case;
-         end;
-      end loop;
-      return Result;
-   end Max_Anchor_ID;
-
-   function Paren_In_Anchor_Line
-     (Data         : in out Parse_Data_Type'Class;
-      Tree         : in     Syntax_Trees.Tree'Class;
-      Anchor_Token : in     Augmented_Token;
-      Offset       : in     Integer)
-     return Integer
-   is
-      use Valid_Node_Index_Arrays;
-      use all type Ada.Containers.Count_Type;
-
-      Left_Paren_ID  : Token_ID renames Data.Left_Paren_ID;
-      Right_Paren_ID : Token_ID renames Data.Right_Paren_ID;
-
-      I              : Base_Token_Index := Anchor_Token.First_Terminals_Index;
-      Paren_Count    : Integer          := 0;
-      Paren_Char_Pos : Buffer_Pos       := Invalid_Buffer_Pos;
-      Text_Begin_Pos : Buffer_Pos       := Invalid_Buffer_Pos;
-   begin
-      Find_First :
-      loop
-         declare
-            Tok : Aug_Token_Const_Ref renames Get_Aug_Token_Const (Data, Tree, 
I);
-         begin
-            if Tok.Deleted then
-               null;
-
-            elsif Tok.ID = Left_Paren_ID then
-               Paren_Count := Paren_Count + 1;
-               if Paren_Count = 1 then
-                  Paren_Char_Pos := Tok.Char_Region.First;
-               end if;
-
-            elsif Tok.ID = Right_Paren_ID then
-               Paren_Count := Paren_Count - 1;
-
-            end if;
-
-            if Tok.First then
-               Text_Begin_Pos := Tok.Char_Region.First;
-               exit Find_First;
-            else
-               if Length (Tok.Inserted_Before) > 0 then
-                  for Node of Tok.Inserted_Before loop
-                     declare
-                        Ins_Tok : Augmented_Token renames Augmented_Token 
(Tree.Augmented (Node).all);
-                     begin
-                        if Ins_Tok.ID = Left_Paren_ID then
-                           Paren_Count := Paren_Count + 1;
-                           if Paren_Count = 1 then
-                              Paren_Char_Pos := Tok.Char_Region.First;
-                           end if;
-
-                        elsif Ins_Tok.ID = Right_Paren_ID then
-                           Paren_Count := Paren_Count - 1;
-
-                        end if;
-
-                        if Ins_Tok.First then
-                           Text_Begin_Pos := Tok.Char_Region.First;
-                           exit Find_First;
-                        end if;
-                     end;
-                  end loop;
-               end if;
-            end if;
-         end;
-         I := I - 1;
-      end loop Find_First;
-
-      if Paren_Char_Pos /= Invalid_Buffer_Pos and Text_Begin_Pos /= 
Invalid_Buffer_Pos then
-         return 1 + Offset + Integer (Paren_Char_Pos - Text_Begin_Pos);
-      else
-         return Offset;
-      end if;
-   end Paren_In_Anchor_Line;
-
-   procedure Put (Cache : in Navigate_Cache_Type)
-   is
-      package Bounded is new Ada.Strings.Bounded.Generic_Bounded_Length (Max 
=> 2 + 11 * Chars_Per_Int);
-      use Bounded;
-
-      Line : Bounded_String := To_Bounded_String ("[");
-
-      procedure Append (Item : in Nil_Buffer_Pos)
-      is begin
-         if Item.Set then
-            Append (Line, Buffer_Pos'Image (Item.Item));
-         else
-            Append (Line, " -1");
-         end if;
-      end Append;
-   begin
-      Append (Line, Navigate_Cache_Code);
-      Append (Line, Buffer_Pos'Image (Cache.Pos));
-      Append (Line, Token_ID'Image (Cache.Statement_ID));
-      Append (Line, Token_ID'Image (Cache.ID));
-      Append (Line, Integer'Image (Cache.Length));
-      Append (Line, Integer'Image (Navigate_Class_Type'Pos (Cache.Class)));
-      Append (Cache.Containing_Pos);
-      Append (Cache.Prev_Pos);
-      Append (Cache.Next_Pos);
-      Append (Cache.End_Pos);
-      Append (Line, ']');
-      Ada.Text_IO.Put_Line (To_String (Line));
-   end Put;
-
-   procedure Put (Cache : in WisiToken.Buffer_Region)
-   is begin
-      Ada.Text_IO.Put_Line
-        ("[" & Name_Property_Code & Buffer_Pos'Image (Cache.First) & 
Buffer_Pos'Image (Cache.Last) & "]");
-   end Put;
-
-   procedure Put (Cache : in Face_Cache_Type)
-   is
-      package Bounded is new Ada.Strings.Bounded.Generic_Bounded_Length (Max 
=> 2 + 4 * Chars_Per_Int);
-      use Bounded;
-
-      Line : Bounded_String := To_Bounded_String ("[");
-   begin
-      if Cache.Face.Set then
-         Append (Line, Face_Property_Code);
-         Append (Line, Buffer_Pos'Image (Cache.Char_Region.First));
-         Append (Line, Buffer_Pos'Image (Cache.Char_Region.Last));
-         Append (Line, Integer'Image (Cache.Face.Item));
-         Append (Line, ']');
-         Ada.Text_IO.Put_Line (To_String (Line));
-      end if;
-   end Put;
-
-   procedure Put (Line_Number : in Line_Number_Type; Item : in Indent_Type)
-   is begin
-      --  All Anchors must be resolved at this point, but not all lines have
-      --  an indent computed. A negative indent is an error in either the
-      --  grammar indent rules or the algorithms in this package.
-      case Item.Label is
-      when Not_Set =>
-         --  Especially with partial parse, we have no idea what this indent 
should be.
-         null;
-
-      when Int =>
-         declare
-            --  We can easily get negative indents when there are syntax 
errors.
-            Ind : constant Integer := Integer'Max (0, Item.Int_Indent);
-         begin
-            Ada.Text_IO.Put_Line
-              ('[' & Indent_Code & Line_Number_Type'Image (Line_Number) & 
Integer'Image (Ind) & ']');
-         end;
-
-      when Anchor_Nil | Anchor_Int | Anchored | Anchor_Anchored =>
-         raise SAL.Programmer_Error with "Indent item has non-int label: " & 
Indent_Label'Image (Item.Label);
-      end case;
-   end Put;
-
-   procedure Put
-     (Item : in Parse.LR.Configuration;
-      Data : in Parse_Data_Type;
-      Tree : in Syntax_Trees.Tree)
-   is
-      use Ada.Strings.Unbounded;
-      use Parse.LR;
-      use Parse.LR.Config_Op_Arrays, Parse.LR.Config_Op_Array_Refs;
-
-      --  Output is a sequence of edit regions; each is:
-      --  [edit-pos [inserted token-ids] [deleted token-ids] deleted-region]
-
-      type State_Label is
-        (None,     -- not started yet
-         Inserted, -- edit-pos, some insert ids appended
-         Deleted); -- some delete ids appended
-
-      State : State_Label := None;
-      --  State of the current edit region.
-
-      Line           : Unbounded_String := To_Unbounded_String ("[");
-      Deleted_Region : Buffer_Region    := Null_Buffer_Region;
-      Last_Deleted : Config_Op (Delete) := (Delete, Invalid_Token_ID, 
Invalid_Token_Index);
-
-      procedure Start_Edit_Region (Op : in Insert_Delete_Op)
-      is begin
-         Append (Line, "[");
-         Append (Line, Get_Aug_Token_Const (Data, Tree, Parse.LR.Token_Index 
(Op)).Char_Region.First'Image);
-         Append (Line, "[");
-      end Start_Edit_Region;
-
-      function Deleted_Region_Image return String
-      is begin
-         return "(" & Deleted_Region.First'Image & " . " & Buffer_Pos'Image 
(Deleted_Region.Last + 1) & ")";
-      end Deleted_Region_Image;
-
-      procedure Terminate_Edit_Region
-      is begin
-         case State is
-         when None =>
-            null;
-         when Inserted =>
-            Append (Line, "][]" & Deleted_Region_Image & "]");
-         when Deleted =>
-            Append (Line, "]" & Deleted_Region_Image & "]");
-         end case;
-         Deleted_Region := Null_Buffer_Region;
-      end Terminate_Edit_Region;
-   begin
-      if Trace_Action > Outline then
-         Ada.Text_IO.Put_Line (";; " & Parse.LR.Image (Item.Ops, 
Data.Descriptor.all));
-      end if;
-
-      Append (Line, Recover_Code);
-      for I in First_Index (Item.Ops) .. Last_Index (Item.Ops) loop
-         declare
-            Op : Config_Op renames Constant_Ref (Item.Ops, I);
-         begin
-            case Op.Op is
-            when Fast_Forward =>
-               Terminate_Edit_Region;
-               State := None;
-
-            when Undo_Reduce | Push_Back =>
-               null;
-
-            when Insert =>
-               case State is
-               when None =>
-                  Start_Edit_Region (Op);
-
-               when Inserted =>
-                  null;
-
-               when Deleted =>
-                  Terminate_Edit_Region;
-                  Start_Edit_Region (Op);
-
-               end case;
-               Append (Line, Token_ID'Image (Op.Ins_ID));
-               State := Inserted;
-
-            when Delete =>
-               Deleted_Region := Deleted_Region and Get_Aug_Token_Const (Data, 
Tree, Op.Del_Token_Index).Char_Region;
-               declare
-                  Skip : Boolean := False;
-               begin
-                  case State is
-                  when None =>
-                     Start_Edit_Region (Op);
-                     Append (Line, "][");
-
-                  when Inserted =>
-                     Append (Line, "][");
-
-                  when Deleted =>
-                     if Data.Embedded_Quote_Escape_Doubled and then
-                       ((Last_Deleted.Del_ID = Data.Descriptor.String_1_ID and
-                           Op.Del_ID = Data.Descriptor.String_1_ID) or
-                          (Last_Deleted.Del_ID = Data.Descriptor.String_2_ID 
and
-                             Op.Del_ID = Data.Descriptor.String_2_ID))
-                     then
-                        declare
-                           Tok_1 : Augmented_Token renames Get_Aug_Token_Const
-                             (Data, Tree, Last_Deleted.Del_Token_Index);
-                           Tok_2 : Augmented_Token renames Get_Aug_Token_Const 
(Data, Tree, Op.Del_Token_Index);
-                        begin
-                           if Tok_1.Char_Region.Last + 1 = 
Tok_2.Char_Region.First then
-                              --  Buffer text was '"""', lexer repair changed 
it to '""""'. The
-                              --  repaired text looks like a single string 
with an embedded quote.
-                              --  But here, it is two STRING_LITERAL tokens. 
Don't send the second
-                              --  delete to elisp. See 
test/ada_mode-recover_string_quote_1.adb
-                              Skip := True;
-                           end if;
-                        end;
-                     end if;
-                  end case;
-                  State := Deleted;
-
-                  if not Skip then
-                     Append (Line, Token_ID'Image (Op.Del_ID));
-                  end if;
-               end;
-               Last_Deleted := Op;
-            end case;
-         end;
-      end loop;
-
-      case State is
-      when None =>
-         null;
-      when Inserted | Deleted =>
-         Terminate_Edit_Region;
-      end case;
-      Append (Line, "]");
-      Ada.Text_IO.Put_Line (To_String (Line));
-   end Put;
-
-   procedure Resolve_Anchors (Data : in out Parse_Data_Type)
-   is
-      Begin_Indent  : Integer renames Data.Begin_Indent;
-      Anchor_Indent : array (First_Anchor_ID .. Data.Max_Anchor_ID) of Integer;
-   begin
-      if Trace_Action > Outline then
-         Ada.Text_IO.New_Line;
-         Ada.Text_IO.Put_Line (";; Begin_Indent: " & Integer'Image 
(Data.Begin_Indent));
-         for I in Data.Indents.First_Index .. Data.Indents.Last_Index loop
-            Ada.Text_IO.Put_Line (";; " & Line_Number_Type'Image (I) & ", " & 
Image (Data.Indents (I)));
-         end loop;
-         Ada.Text_IO.Put_Line (";; resolve anchors");
-      end if;
-
-      for I in Data.Indents.First_Index .. Data.Indents.Last_Index loop
-         declare
-            Indent : constant Indent_Type := Data.Indents (I);
-         begin
-            case Indent.Label is
-            when Not_Set =>
-               --  Indent not computed, therefore not output.
-               null;
-
-            when Int =>
-               Data.Indents.Replace_Element (I, (Int, Indent.Int_Indent + 
Begin_Indent));
-
-            when Anchor_Nil =>
-               for I of Indent.Anchor_Nil_IDs loop
-                  Anchor_Indent (I) := Begin_Indent;
-               end loop;
-               Data.Indents.Replace_Element (I, (Int, Begin_Indent));
-
-            when Anchor_Int =>
-               for I of Indent.Anchor_Int_IDs loop
-                  Anchor_Indent (I) := Indent.Anchor_Int_Indent + Begin_Indent;
-               end loop;
-               Data.Indents.Replace_Element (I, (Int, Indent.Anchor_Int_Indent 
+ Begin_Indent));
-
-            when Anchored =>
-               Data.Indents.Replace_Element
-                 (I, (Int, Anchor_Indent (Indent.Anchored_ID) + 
Indent.Anchored_Delta));
-
-            when Anchor_Anchored =>
-               declare
-                  Temp : constant Integer :=
-                    Anchor_Indent (Indent.Anchor_Anchored_ID) + 
Indent.Anchor_Anchored_Delta;
-               begin
-                  for I of Indent.Anchor_Anchored_IDs loop
-                     Anchor_Indent (I) := Temp;
-                  end loop;
-                  Data.Indents.Replace_Element (I, (Int, Temp));
-               end;
-            end case;
-         end;
-      end loop;
-   end Resolve_Anchors;
-
-   procedure Set_End
-     (Data           : in out Parse_Data_Type;
-      Containing_Pos : in     Buffer_Pos;
-      End_Pos        : in     Buffer_Pos)
-   is
-      use Navigate_Cursor_Lists;
-      I            : Cursor := Data.End_Positions.First;
-      Delete_Cache : Boolean;
-      Temp         : Cursor;
-   begin
-      loop
-         exit when not Has_Element (I);
-         declare
-            Cache : Navigate_Cache_Type renames Data.Navigate_Caches (Element 
(I));
-         begin
-            if Cache.Pos in Containing_Pos .. End_Pos then
-               Cache.End_Pos := (True, End_Pos);
-               Delete_Cache := True;
-            else
-               Delete_Cache := False;
-            end if;
-         end;
-         if Delete_Cache then
-            Temp := Next (I);
-            Delete (Data.End_Positions, I);
-
-            I := Temp;
-         else
-            Next (I);
-         end if;
-
-      end loop;
-   end Set_End;
-
-   ----------
-   --  public subprograms (declaration order)
-
-   procedure Initialize
-     (Data              : in out Parse_Data_Type;
-      Lexer             : in     WisiToken.Lexer.Handle;
-      Descriptor        : access constant WisiToken.Descriptor;
-      Base_Terminals    : in     Base_Token_Array_Access;
-      Post_Parse_Action : in     Post_Parse_Action_Type;
-      Begin_Line        : in     Line_Number_Type;
-      End_Line          : in     Line_Number_Type;
-      Begin_Indent      : in     Integer;
-      Params            : in     String)
-   is
-      pragma Unreferenced (Params);
-   begin
-      Data.Line_Begin_Char_Pos.Set_First_Last
-        (First   => Begin_Line,
-         Last    => End_Line);
-
-      --  + 1 for data on line following last line; see Lexer_To_Augmented.
-      Data.Line_Paren_State.Set_First_Last
-        (First   => Begin_Line,
-         Last    => End_Line + 1);
-
-      Data.Lexer             := Lexer;
-      Data.Descriptor        := Descriptor;
-      Data.Base_Terminals    := Base_Terminals;
-      Data.Post_Parse_Action := Post_Parse_Action;
-
-      case Post_Parse_Action is
-      when Navigate | Face =>
-         null;
-      when Indent =>
-         Data.Indents.Set_First_Last
-           (First   => Begin_Line,
-            Last    => End_Line);
-
-         Data.Begin_Indent := Begin_Indent;
-      end case;
-
-      Data.Reset;
-   exception
-   when E : others =>
-      raise SAL.Programmer_Error with "wisi.initialize: " & 
Ada.Exceptions.Exception_Name (E) & ": " &
-        Ada.Exceptions.Exception_Message (E);
-   end Initialize;
-
-   overriding procedure Reset (Data : in out Parse_Data_Type)
-   is begin
-      Data.Last_Terminal_Node := WisiToken.Invalid_Node_Index;
-
-      Data.Leading_Non_Grammar.Clear;
-
-      --  Data.Line_Begin_Char_Pos  set in Initialize, overwritten in 
Lexer_To_Augmented
-
-      for S of Data.Line_Paren_State loop
-         S := 0;
-      end loop;
-      Data.Current_Paren_State := 0;
-
-      Data.Navigate_Caches.Finalize;
-      Data.Navigate_Caches.Initialize;
-
-      Data.Name_Caches.Finalize;
-      Data.Name_Caches.Initialize;
-
-      Data.End_Positions.Clear;
-
-      Data.Face_Caches.Finalize;
-      Data.Face_Caches.Initialize;
-
-      for I in Data.Indents.First_Index .. Data.Indents.Last_Index loop
-         Data.Indents.Replace_Element (I, (Label => Not_Set));
-      end loop;
-      Data.Max_Anchor_ID := First_Anchor_ID - 1;
-   end Reset;
-
-   function Source_File_Name (Data : in Parse_Data_Type) return String
-   is begin
-      return Data.Lexer.File_Name;
-   end Source_File_Name;
-
-   function Post_Parse_Action (Data : in Parse_Data_Type) return 
Post_Parse_Action_Type
-   is begin
-      return Data.Post_Parse_Action;
-   end Post_Parse_Action;
-
-   overriding
-   procedure Lexer_To_Augmented
-     (Data  : in out          Parse_Data_Type;
-      Tree  : in out          Syntax_Trees.Tree'Class;
-      Token : in              Base_Token;
-      Lexer : not null access WisiToken.Lexer.Instance'Class)
-   is
-      use all type Ada.Containers.Count_Type;
-   begin
-      if Lexer.First then
-         Data.Line_Begin_Char_Pos (Token.Line) := Token.Char_Region.First;
-
-         if Token.Line > Data.Line_Begin_Char_Pos.First_Index and then
-           Data.Line_Begin_Char_Pos (Token.Line - 1) = Invalid_Buffer_Pos
-         then
-            --  Previous token contains multiple lines; ie %code in 
wisitoken_grammar.wy
-            declare
-               First_Set_Line : Line_Number_Type;
-            begin
-               for Line in reverse Data.Line_Begin_Char_Pos.First_Index .. 
Token.Line - 1 loop
-                  if Data.Line_Begin_Char_Pos (Line) /= Invalid_Buffer_Pos then
-                     First_Set_Line := Line;
-                     exit;
-                  end if;
-               end loop;
-               for Line in First_Set_Line + 1 .. Token.Line - 1 loop
-                  Data.Line_Begin_Char_Pos (Line) := Data.Line_Begin_Char_Pos 
(First_Set_Line); -- good enough
-               end loop;
-            end;
-         end if;
-      end if;
-
-      if Token.ID < Data.Descriptor.First_Terminal then
-         --  Non-grammar token
-
-         if Token.ID = Data.Descriptor.New_Line_ID then
-            Data.Line_Paren_State (Token.Line + 1) := Data.Current_Paren_State;
-         end if;
-
-         if Data.Last_Terminal_Node = Invalid_Node_Index then
-            Data.Leading_Non_Grammar.Append ((Token with Lexer.First));
-         else
-            declare
-               Containing_Token : Aug_Token_Var_Ref renames Get_Aug_Token_Var 
(Tree, Data.Last_Terminal_Node);
-
-               Trailing_Blank : constant Boolean :=
-                 Token.ID = Data.Descriptor.New_Line_ID and
-                 (Containing_Token.Non_Grammar.Length > 0 and then
-                    Containing_Token.Non_Grammar
-                      (Containing_Token.Non_Grammar.Last_Index).ID = 
Data.Descriptor.New_Line_ID);
-            begin
-               if Lexer.First and
-                 (Token.ID in Data.First_Comment_ID .. Data.Last_Comment_ID or
-                    Trailing_Blank)
-               then
-                  if Containing_Token.First_Trailing_Comment_Line = 
Invalid_Line_Number then
-                     Containing_Token.First_Trailing_Comment_Line := 
Token.Line;
-                  end if;
-                  Containing_Token.Last_Trailing_Comment_Line  := Token.Line;
-               end if;
-
-               Containing_Token.Non_Grammar.Append ((Token with Lexer.First));
-            end;
-         end if;
-
-      else
-         --  grammar token
-         declare
-            Temp : constant Augmented_Token_Access := new Augmented_Token'
-              (Token with
-               Deleted                     => False,
-               First                       => Lexer.First,
-               Paren_State                 => Data.Current_Paren_State,
-               First_Terminals_Index       => Data.Terminals.Last_Index,
-               Last_Terminals_Index        => Data.Terminals.Last_Index,
-               First_Indent_Line           => (if Lexer.First then Token.Line 
else Invalid_Line_Number),
-               Last_Indent_Line            => (if Lexer.First then Token.Line 
else Invalid_Line_Number),
-               First_Trailing_Comment_Line => Invalid_Line_Number, -- Set by 
Reduce
-               Last_Trailing_Comment_Line  => Invalid_Line_Number,
-               Non_Grammar                 => 
Non_Grammar_Token_Arrays.Empty_Vector,
-               Inserted_Before             => 
Valid_Node_Index_Arrays.Empty_Vector);
-         begin
-            Data.Last_Terminal_Node := Token.Tree_Index;
-
-            if Token.ID = Data.Left_Paren_ID then
-               Data.Current_Paren_State := Data.Current_Paren_State + 1;
-
-            elsif Token.ID = Data.Right_Paren_ID then
-               Data.Current_Paren_State := Data.Current_Paren_State - 1;
-            end if;
-
-            Tree.Set_Augmented (Token.Tree_Index, Base_Token_Class_Access 
(Temp));
-         end;
-      end if;
-   end Lexer_To_Augmented;
-
-   overriding
-   procedure Insert_Token
-     (Data  : in out Parse_Data_Type;
-      Tree  : in out Syntax_Trees.Tree'Class;
-      Token : in     Valid_Node_Index)
-   is
-      use Valid_Node_Index_Arrays;
-
-      Before_Index : constant Token_Index := Tree.Before (Token);
-      Before_Aug : Aug_Token_Var_Ref renames Get_Aug_Token_Var (Data, Tree, 
Before_Index);
-
-      --  Set data that allows using Token when computing indent.
-
-      Indent_Line : constant Line_Number_Type :=
-        (if Before_Aug.First
-         then Before_Aug.Line
-         else Invalid_Line_Number);
-
-      --  Set for Insert_After False; see below for True.
-      New_Aug : constant Augmented_Token_Access := new Augmented_Token'
-        (ID                          => Tree.ID (Token),
-         Tree_Index                  => Token,
-         Byte_Region                 => (First | Last => 
Before_Aug.Byte_Region.First),
-         Line                        => Before_Aug.Line,
-         Column                      => Before_Aug.Column,
-         Char_Region                 => (First | Last => 
Before_Aug.Char_Region.First),
-         Deleted                     => False,
-         First                       => Before_Aug.First,
-         Paren_State                 => Before_Aug.Paren_State,
-         First_Terminals_Index       => Invalid_Token_Index,
-         Last_Terminals_Index        => Invalid_Token_Index,
-         First_Indent_Line           => Indent_Line,
-         Last_Indent_Line            => Indent_Line,
-         First_Trailing_Comment_Line => Invalid_Line_Number,
-         Last_Trailing_Comment_Line  => Invalid_Line_Number,
-         Non_Grammar                 => Non_Grammar_Token_Arrays.Empty_Vector,
-         Inserted_Before             => Valid_Node_Index_Arrays.Empty_Vector);
-
-      Prev_Terminal : constant Node_Index := Tree.Prev_Terminal (Token);
-      --  Invalid_Node_Index if Token is inserted before first grammar token
-
-      Insert_After : Boolean := False;
-   begin
-      Tree.Set_Augmented (Token, Base_Token_Class_Access (New_Aug));
-
-      Append (Before_Aug.Inserted_Before, Token);
-
-      if Prev_Terminal /= Invalid_Node_Index and Before_Aug.First then
-         declare
-            use all type Ada.Containers.Count_Type;
-            use all type Ada.Text_IO.Count;
-
-            --  See test/ada_mode-interactive_2.adb, "Typing ..."; three tests.
-            --
-            --  When typing new code, we want a new blank line to be indented 
as
-            --  if the code was there already. To accomplish that, we put the
-            --  inserted tokens at the end of the line before the Before token;
-            --  that will be after the non-grammar on the previous terminal.
-            --
-            --  Compare to test/ada_mode-recover_20.adb. There we are not 
typing
-            --  new code, but there is a blank line; the right paren is placed 
at
-            --  the end of the blank line, causing the comment to be indented.
-
-            Prev_Aug : Aug_Token_Var_Ref renames Get_Aug_Token_Var (Tree, 
Prev_Terminal);
-
-            --  Prev_Aug.Non_Grammar must have at least one New_Line, since
-            --  Before_Aug.First is True. The whitespace after the New_Line is 
not
-            --  given a token.
-            --
-            --  If the first two tokens in Prev_Non_Grammar are both New_Lines,
-            --  there is a blank line after the code line (and before any
-            --  comments); assume that is the edit point.
-            Insert_On_Blank_Line : constant Boolean := 
Prev_Aug.Non_Grammar.Length >= 2 and then
-              (Prev_Aug.Non_Grammar (Prev_Aug.Non_Grammar.First_Index).ID = 
Data.Descriptor.New_Line_ID and
-                 Prev_Aug.Non_Grammar (Prev_Aug.Non_Grammar.First_Index + 
1).ID = Data.Descriptor.New_Line_ID);
-
-            --  In Ada, 'end' is Insert_After except when Insert_On_Blank_Line 
is
-            --  True (see test/ada_mode-interactive_2.adb Record_1), so 
Insert_After
-            --  needs Insert_On_Blank_Line.
-         begin
-            Insert_After := Parse_Data_Type'Class (Data).Insert_After (Tree, 
Token, Insert_On_Blank_Line);
-
-            if Insert_After then
-               if Insert_On_Blank_Line then
-                  declare
-                     Prev_Non_Grammar : constant Non_Grammar_Token :=
-                       Prev_Aug.Non_Grammar (Prev_Aug.Non_Grammar.First_Index 
+ 1);
-                     --  The newline nominally after the inserted token.
-                  begin
-                     New_Aug.Byte_Region := (First | Last => 
Prev_Non_Grammar.Byte_Region.Last - 1);
-                     New_Aug.Char_Region := (First | Last => 
Prev_Non_Grammar.Char_Region.Last - 1);
-
-                     New_Aug.First  := True;
-                     New_Aug.Line   := Prev_Non_Grammar.Line;
-                     New_Aug.Column := Prev_Aug.Column + Ada.Text_IO.Count 
(Length (New_Aug.Char_Region)) - 1;
-
-                     New_Aug.First_Indent_Line := Prev_Non_Grammar.Line;
-                     New_Aug.Last_Indent_Line  := Prev_Non_Grammar.Line;
-
-                     for I in Prev_Aug.Non_Grammar.First_Index + 1 .. 
Prev_Aug.Non_Grammar.Last_Index loop
-                        New_Aug.Non_Grammar.Append (Prev_Aug.Non_Grammar (I));
-                     end loop;
-
-                     Prev_Aug.Non_Grammar.Set_First_Last
-                       (Prev_Aug.Non_Grammar.First_Index, 
Prev_Aug.Non_Grammar.First_Index);
-                  end;
-               else
-                  New_Aug.Byte_Region := (First | Last => 
Prev_Aug.Byte_Region.Last);
-                  New_Aug.Char_Region := (First | Last => 
Prev_Aug.Char_Region.Last);
-
-                  New_Aug.First  := False;
-                  New_Aug.Line   := Prev_Aug.Line;
-                  New_Aug.Column := Prev_Aug.Column + Ada.Text_IO.Count 
(Length (Prev_Aug.Char_Region)) - 1;
-
-                  New_Aug.First_Indent_Line := Invalid_Line_Number;
-                  New_Aug.Last_Indent_Line  := Invalid_Line_Number;
-
-                  New_Aug.Non_Grammar  := Prev_Aug.Non_Grammar;
-                  Prev_Aug.Non_Grammar := 
Non_Grammar_Token_Arrays.Empty_Vector;
-
-               end if;
-
-               New_Aug.First_Trailing_Comment_Line := 
Prev_Aug.First_Trailing_Comment_Line;
-               New_Aug.Last_Trailing_Comment_Line  := 
Prev_Aug.Last_Trailing_Comment_Line;
-
-               Prev_Aug.First_Trailing_Comment_Line := Invalid_Line_Number;
-               Prev_Aug.Last_Trailing_Comment_Line  := Invalid_Line_Number;
-            end if;
-         end;
-      end if;
-
-      if New_Aug.First and not Insert_After then
-         Before_Aug.First             := False;
-         Before_Aug.First_Indent_Line := Invalid_Line_Number;
-         Before_Aug.Last_Indent_Line  := Invalid_Line_Number;
-      end if;
-
-      if New_Aug.ID = Data.Left_Paren_ID then
-         Adjust_Paren_State (Data, Tree, Before_Index, New_Aug.Line + 1, +1);
-
-      elsif New_Aug.ID = Data.Right_Paren_ID then
-         Adjust_Paren_State (Data, Tree, Before_Index, New_Aug.Line + 1, -1);
-      end if;
-   end Insert_Token;
-
-   overriding
-   procedure Delete_Token
-     (Data                : in out Parse_Data_Type;
-      Tree                : in out Syntax_Trees.Tree'Class;
-      Deleted_Token_Index : in     WisiToken.Token_Index)
-   is
-      use all type Ada.Containers.Count_Type;
-      Deleted_Token    : Augmented_Token renames Get_Aug_Token_Var (Data, 
Tree, Deleted_Token_Index);
-      Prev_Token_Index : Base_Token_Index := Deleted_Token_Index - 1;
-      Next_Token_Index : Base_Token_Index := Deleted_Token_Index + 1;
-   begin
-      if Deleted_Token.Deleted then
-         --  This can happen if error recovery screws up.
-         if WisiToken.Trace_Action > WisiToken.Detail then
-            Ada.Text_IO.Put_Line (";; delete token again; ignored " & Image 
(Deleted_Token, Data.Descriptor.all));
-         end if;
-         return;
-      end if;
-      if WisiToken.Trace_Action > WisiToken.Detail then
-         Ada.Text_IO.Put_Line (";; delete token " & Image (Deleted_Token, 
Data.Descriptor.all));
-      end if;
-
-      Deleted_Token.Deleted := True;
-
-      if Deleted_Token.Non_Grammar.Length > 0 then
-         --  Move Non_Grammar to previous non-deleted token
-
-         loop
-            exit when Prev_Token_Index = Base_Token_Index'First;
-            exit when Get_Aug_Token_Const (Data, Tree, 
Prev_Token_Index).Deleted = False;
-            Prev_Token_Index := Prev_Token_Index - 1;
-         end loop;
-
-         if Prev_Token_Index = Base_Token_Index'First then
-            Deleted_Token.Non_Grammar 
(Deleted_Token.Non_Grammar.First_Index).First := Deleted_Token.First;
-            Data.Leading_Non_Grammar.Append (Deleted_Token.Non_Grammar);
-         else
-            declare
-               Prev_Token : Augmented_Token renames Get_Aug_Token_Var (Data, 
Tree, Prev_Token_Index);
-            begin
-               Prev_Token.Non_Grammar.Append (Deleted_Token.Non_Grammar);
-
-               if Deleted_Token.First_Trailing_Comment_Line /= 
Invalid_Line_Number then
-                  if Prev_Token.First_Trailing_Comment_Line = 
Invalid_Line_Number then
-                     Prev_Token.First_Trailing_Comment_Line := 
Deleted_Token.First_Trailing_Comment_Line;
-                  end if;
-                  Prev_Token.Last_Trailing_Comment_Line  := 
Deleted_Token.Last_Trailing_Comment_Line;
-               end if;
-            end;
-         end if;
-      end if;
-
-      --  Data.Terminals.Last_Index is Wisi_EOI; it is never deleted
-      loop
-         exit when Get_Aug_Token_Const (Data, Tree, Next_Token_Index).Deleted 
= False;
-         Next_Token_Index := Next_Token_Index + 1;
-         exit when Next_Token_Index = Data.Terminals.Last_Index;
-      end loop;
-
-      if Deleted_Token.First and
-        (Next_Token_Index = Data.Terminals.Last_Index or else
-           Get_Aug_Token_Const (Data, Tree, Next_Token_Index).Line > 
Deleted_Token.Line)
-      then
-         --  Deleted_Token.Line is now blank; add to previous token non
-         --  grammar.
-         if Prev_Token_Index > Base_Token_Index'First then
-            declare
-               Prev_Token : Augmented_Token renames Get_Aug_Token_Var (Data, 
Tree, Prev_Token_Index);
-            begin
-               if Prev_Token.First_Trailing_Comment_Line = Invalid_Line_Number 
then
-                  Prev_Token.First_Trailing_Comment_Line := Deleted_Token.Line;
-                  Prev_Token.Last_Trailing_Comment_Line  := Deleted_Token.Line;
-               else
-                  if Prev_Token.First_Trailing_Comment_Line > 
Deleted_Token.Line then
-                     Prev_Token.First_Trailing_Comment_Line := 
Deleted_Token.Line;
-                  end if;
-                  if Prev_Token.Last_Trailing_Comment_Line < 
Deleted_Token.Line then
-                     Prev_Token.Last_Trailing_Comment_Line := 
Deleted_Token.Line;
-                  end if;
-               end if;
-            end;
-         end if;
-      end if;
-
-      if Deleted_Token.First and Next_Token_Index < Data.Terminals.Last_Index 
then
-         declare
-            Next_Token : Augmented_Token renames Get_Aug_Token_Var (Data, 
Tree, Next_Token_Index);
-         begin
-            if not Next_Token.First then
-               Next_Token.First             := True;
-               Next_Token.First_Indent_Line := Deleted_Token.First_Indent_Line;
-               Next_Token.Last_Indent_Line  := Deleted_Token.Last_Indent_Line;
-            end if;
-         end;
-      end if;
-
-      if Deleted_Token.ID = Data.Left_Paren_ID then
-         Adjust_Paren_State (Data, Tree, Deleted_Token_Index + 1, 
Deleted_Token.Line + 1, -1);
-
-      elsif Deleted_Token.ID = Data.Right_Paren_ID then
-         Adjust_Paren_State (Data, Tree, Deleted_Token_Index + 1, 
Deleted_Token.Line + 1, +1);
-
-      end if;
-   end Delete_Token;
-
-   overriding
-   procedure Reduce
-     (Data    : in out Parse_Data_Type;
-      Tree    : in out Syntax_Trees.Tree'Class;
-      Nonterm : in     Valid_Node_Index;
-      Tokens  : in     Valid_Node_Index_Array)
-   is
-      Aug_Nonterm : constant Augmented_Token_Access := new Augmented_Token'
-        (ID          => Tree.ID (Nonterm),
-         Byte_Region => Tree.Byte_Region (Nonterm),
-         others      => <>);
-
-      Trailing_Comment_Done : Boolean := False;
-   begin
-      Tree.Set_Augmented (Nonterm, Base_Token_Class_Access (Aug_Nonterm));
-
-      for I in reverse Tokens'Range loop
-         --  'reverse' to find token containing trailing comments; last
-         --  non-empty token.
-         declare
-            Aug_Token : Aug_Token_Const_Ref renames Get_Aug_Token_Const_1 
(Tree, Tokens (I));
-         begin
-
-            if Data.Post_Parse_Action = Indent then
-               if Aug_Token.First_Terminals_Index /= Invalid_Token_Index then
-                  Aug_Nonterm.First_Terminals_Index := 
Aug_Token.First_Terminals_Index;
-               end if;
-
-               if Aug_Nonterm.Last_Terminals_Index = Invalid_Token_Index then
-                  Aug_Nonterm.Last_Terminals_Index := 
Aug_Token.Last_Terminals_Index;
-               end if;
-
-               Aug_Nonterm.First := Aug_Nonterm.First or Aug_Token.First;
-
-               if Aug_Token.First_Indent_Line /= Invalid_Line_Number then
-                  Aug_Nonterm.First_Indent_Line := Aug_Token.First_Indent_Line;
-               elsif Trailing_Comment_Done and 
Aug_Token.First_Trailing_Comment_Line /= Invalid_Line_Number then
-                  Aug_Nonterm.First_Indent_Line := 
Aug_Token.First_Trailing_Comment_Line;
-               end if;
-
-               if Aug_Nonterm.Last_Indent_Line = Invalid_Line_Number then
-                  if Trailing_Comment_Done and 
Aug_Token.Last_Trailing_Comment_Line /= Invalid_Line_Number then
-                     Aug_Nonterm.Last_Indent_Line := 
Aug_Token.Last_Trailing_Comment_Line;
-                  elsif Aug_Token.Last_Indent_Line /= Invalid_Line_Number then
-                     Aug_Nonterm.Last_Indent_Line := 
Aug_Token.Last_Indent_Line;
-                  end if;
-               end if;
-
-               if not Trailing_Comment_Done then
-                  Aug_Nonterm.First_Trailing_Comment_Line := 
Aug_Token.First_Trailing_Comment_Line;
-                  Aug_Nonterm.Last_Trailing_Comment_Line  := 
Aug_Token.Last_Trailing_Comment_Line;
-                  Trailing_Comment_Done := True;
-               end if;
-
-            end if; --  Compute_Indent
-
-            if Aug_Token.Line /= Invalid_Line_Number then
-               Aug_Nonterm.Line   := Aug_Token.Line;
-               Aug_Nonterm.Column := Aug_Token.Column;
-            end if;
-
-            if Aug_Nonterm.Char_Region.First > Aug_Token.Char_Region.First then
-               Aug_Nonterm.Char_Region.First := Aug_Token.Char_Region.First;
-            end if;
-
-            if Aug_Nonterm.Char_Region.Last < Aug_Token.Char_Region.Last then
-               Aug_Nonterm.Char_Region.Last := Aug_Token.Char_Region.Last;
-            end if;
-
-            Aug_Nonterm.Paren_State := Aug_Token.Paren_State;
-         end;
-      end loop;
-   end Reduce;
-
-   procedure Statement_Action
-     (Data    : in out Parse_Data_Type;
-      Tree    : in     Syntax_Trees.Tree;
-      Nonterm : in     Valid_Node_Index;
-      Tokens  : in     Valid_Node_Index_Array;
-      Params  : in     Statement_Param_Array)
-   is
-      Nonterm_Tok        : Aug_Token_Const_Ref renames Get_Aug_Token_Const_1 
(Tree, Nonterm);
-      First_Item         : Boolean                := True;
-      Start_Set          : Boolean                := False;
-      Override_Start_Set : Boolean                := False;
-      Containing_Pos     : Nil_Buffer_Pos         := Nil;
-   begin
-      for Pair of Params loop
-         if not (Pair.Index in Tokens'Range) then
-            raise Fatal_Error with Error_Message
-              (File_Name => Data.Lexer.File_Name,
-               Line      => Nonterm_Tok.Line,
-               Column    => Nonterm_Tok.Column,
-               Message   => "wisi-statement-action: " & Trimmed_Image 
(Tree.Production_ID (Nonterm)) &
-                 " token index" & SAL.Peek_Type'Image (Pair.Index) &
-                 " not in tokens range (" & SAL.Peek_Type'Image (Tokens'First) 
& " .." &
-                 SAL.Peek_Type'Image (Tokens'Last) & "); bad grammar action.");
-
-         elsif Tree.Byte_Region (Tokens (Pair.Index)) /= Null_Buffer_Region 
then
-            declare
-               use all type WisiToken.Syntax_Trees.Node_Label;
-               Token  : Aug_Token_Const_Ref renames Get_Aug_Token_Const_1
-                 (Tree,
-                  (if Pair.Class = Statement_End and then
-                     Tree.Label (Tokens (Pair.Index)) = 
WisiToken.Syntax_Trees.Nonterm
-                   then Tree.Last_Terminal (Tokens (Pair.Index))
-                   else Tokens (Pair.Index)));
-
-               Cache_Pos : constant Buffer_Pos         := 
Token.Char_Region.First;
-               Cursor    : Navigate_Cache_Trees.Cursor := 
Navigate_Cache_Trees.Find
-                 (Data.Navigate_Caches.Iterate, Cache_Pos,
-                  Direction => Navigate_Cache_Trees.Unknown);
-            begin
-               if Navigate_Cache_Trees.Has_Element (Cursor) then
-                  declare
-                     Cache : Navigate_Cache_Type renames Data.Navigate_Caches 
(Cursor);
-                  begin
-                     if Pair.Class = Statement_Start then
-                        if Start_Set then
-                           Cache.Class := Motion;
-                        else
-                           Cache.Class := Statement_Start;
-                           Start_Set   := True;
-                        end if;
-                     elsif Override_Start_Set then
-                        Cache.Class := Statement_Start;
-                        Start_Set   := True;
-                     else
-                        Cache.Class := Pair.Class;
-                     end if;
-                     Cache.Statement_ID   := Tree.ID (Nonterm);
-                     Cache.Containing_Pos := Containing_Pos;
-                  end;
-               else
-                  Cursor := Data.Navigate_Caches.Insert
-                    ((Pos            => Cache_Pos,
-                      Statement_ID   => Tree.ID (Nonterm),
-                      ID             => Token.ID,
-                      Length         => Length (Token.Char_Region),
-                      Class          => (if Override_Start_Set then 
Statement_Start else Pair.Class),
-                      Containing_Pos => Containing_Pos,
-                      others         => Nil));
-               end if;
-
-               Data.End_Positions.Append (Cursor);
-
-               if First_Item then
-                  First_Item := False;
-                  if Override_Start_Set or Pair.Class = Statement_Start then
-                     Override_Start_Set := False;
-                     Containing_Pos     := (True, Token.Char_Region.First);
-
-                     --  Set containing on all contained caches
-                     declare
-                        use Navigate_Cache_Trees;
-                        Iterator : constant Navigate_Cache_Trees.Iterator := 
Data.Navigate_Caches.Iterate;
-                        Cursor   : Navigate_Cache_Trees.Cursor            := 
Find_In_Range
-                          (Iterator, Ascending, Nonterm_Tok.Char_Region.First 
+ 1, -- don't set containing on start
-                           Nonterm_Tok.Char_Region.Last);
-                     begin
-                        loop
-                           exit when not Has_Element (Cursor);
-                           declare
-                              Cache : Navigate_Cache_Type renames 
Data.Navigate_Caches (Cursor);
-                           begin
-                              if not Cache.Containing_Pos.Set then
-                                 Cache.Containing_Pos := Containing_Pos;
-                              end if;
-                              exit when Nonterm_Tok.Char_Region.Last < 
Cache.Pos + 1;
-                           end;
-                           Cursor := Iterator.Next (Cursor);
-                        end loop;
-                     end;
-                  end if;
-               end if;
-
-               if Pair.Class = Statement_End and Containing_Pos.Set then
-                  Set_End (Data, Containing_Pos.Item, Cache_Pos);
-               end if;
-            end;
-
-         else
-            --  Token.Byte_Region is null
-            if First_Item and Pair.Class = Statement_Start then
-               Override_Start_Set := True;
-            end if;
-         end if;
-      end loop;
-   end Statement_Action;
-
-   procedure Name_Action
-     (Data    : in out Parse_Data_Type;
-      Tree    : in     WisiToken.Syntax_Trees.Tree;
-      Nonterm : in     Valid_Node_Index;
-      Tokens  : in     WisiToken.Valid_Node_Index_Array;
-      Name    : in     WisiToken.Positive_Index_Type)
-   is begin
-      if not (Name in Tokens'Range) then
-         declare
-            Token : Aug_Token_Const_Ref renames Get_Aug_Token_Const_1 (Tree, 
Tokens (Tokens'First));
-         begin
-            raise Fatal_Error with Error_Message
-              (File_Name => Data.Lexer.File_Name,
-               Line      => Token.Line,
-               Column    => Token.Column,
-               Message   => "wisi-name-action: " & Trimmed_Image 
(Tree.Production_ID (Nonterm)) & " name (" &
-                 Trimmed_Image (Name) & ") not in Tokens range (" & 
SAL.Peek_Type'Image (Tokens'First) & " .." &
-                 SAL.Peek_Type'Image (Tokens'Last) & "); bad grammar action.");
-         end;
-      end if;
-
-      if Tree.Is_Virtual (Tokens (Name)) then
-         --  Virtual tokens have the same Char_Region as the token they are
-         --  inserted before (for indent purposes), which leads to Name_Action
-         --  appearing to be applied twice. test/ada_mode-fatal_error_1.adb.
-         --  They also don't appear in the actual buffer, so setting a face or
-         --  completing on them is pointless.
-         return;
-      end if;
-
-      declare
-         use Name_Cache_Trees;
-         Name_Token : Aug_Token_Const_Ref renames Get_Aug_Token_Const_1 (Tree, 
Tokens (Name));
-         Cursor     : constant Name_Cache_Trees.Cursor := Find
-           (Data.Name_Caches.Iterate, Name_Token.Char_Region.First,
-            Direction => Name_Cache_Trees.Unknown);
-      begin
-         if Name_Token.Char_Region = Null_Buffer_Region then
-            return;
-         elsif Has_Element (Cursor) then
-            raise Fatal_Error with Error_Message
-              (File_Name            => Data.Lexer.File_Name,
-               Line                 => Name_Token.Line,
-               Column               => Name_Token.Column,
-               Message              => Tree.Image
-                 (Tokens (Name), Data.Descriptor.all,
-                  Node_Numbers      => WisiToken.Trace_Action > Extra,
-                  Include_RHS_Index => WisiToken.Trace_Action > Extra)
-                 & ": wisi-name-action: name set twice.");
-         else
-            if Trace_Action > Detail then
-               Ada.Text_IO.Put_Line
-                 ("Name_Action " & Tree.Image
-                    (Nonterm, Data.Descriptor.all,
-                     Node_Numbers      => WisiToken.Trace_Action > Extra,
-                     Include_RHS_Index => WisiToken.Trace_Action > Extra) & " 
" & Tree.Image
-                       (Tokens (Name), Data.Descriptor.all,
-                        Node_Numbers      => WisiToken.Trace_Action > Extra,
-                        Include_RHS_Index => WisiToken.Trace_Action > Extra));
-            end if;
-
-            Data.Name_Caches.Insert (Name_Token.Char_Region);
-         end if;
-      end;
-   end Name_Action;
-
-   procedure Motion_Action
-     (Data    : in out Parse_Data_Type;
-      Tree    : in     Syntax_Trees.Tree;
-      Nonterm : in     Valid_Node_Index;
-      Tokens  : in     Valid_Node_Index_Array;
-      Params  : in     Motion_Param_Array)
-   is
-      use Navigate_Cache_Trees;
-
-      Start          : Nil_Buffer_Pos    := (Set => False);
-      Iter           : constant Iterator := Data.Navigate_Caches.Iterate;
-      Prev_Cache_Cur : Cursor;
-      Cache_Cur      : Cursor;
-   begin
-      if WisiToken.Trace_Action > Outline then
-         Ada.Text_IO.Put_Line
-           ("Motion_Action " & Image (Tree.ID (Nonterm), Data.Descriptor.all) 
& " " &
-              Image (Tree.Byte_Region (Nonterm)));
-      end if;
-      for Param of Params loop
-         if Tree.Byte_Region (Tokens (Param.Index)) /= Null_Buffer_Region then
-            declare
-               use all type WisiToken.Syntax_Trees.Node_Label;
-               Token  : Aug_Token_Const_Ref renames Get_Aug_Token_Const_1 
(Tree, Tokens (Param.Index));
-               Region : constant Buffer_Region := Token.Char_Region;
-               Skip   : Boolean                := False;
-            begin
-               if not Start.Set then
-                  Start := (True, Region.First);
-               end if;
-
-               case Tree.Label (Tokens (Param.Index)) is
-               when Shared_Terminal =>
-                  Cache_Cur := Find (Iter, Region.First);
-               when Virtual_Terminal | Virtual_Identifier =>
-                  return;
-
-               when Syntax_Trees.Nonterm =>
-                  if Param.ID = Invalid_Token_ID then
-                     Cache_Cur := Find (Iter, Region.First);
-
-                  else
-                     Skip      := True;
-                     Cache_Cur := Find_In_Range (Iter, Ascending, 
Region.First, Region.Last);
-                     loop
-                        exit when not Has_Element (Cache_Cur);
-                        if Data.Navigate_Caches (Cache_Cur).Pos > Region.Last 
then
-                           Cache_Cur := No_Element;
-                           exit;
-
-                        elsif Data.Navigate_Caches (Cache_Cur).ID = Param.ID 
and
-                          not Data.Navigate_Caches (Cache_Cur).Prev_Pos.Set
-                        then
-                           Skip := False;
-                           exit;
-                        end if;
-
-                        Cache_Cur := Next (Iter, Cache_Cur);
-                     end loop;
-                  end if;
-               end case;
-
-               if not Skip then
-                  if not Has_Element (Cache_Cur) then
-                     raise Fatal_Error with Error_Message
-                       (File_Name => Data.Lexer.File_Name,
-                        Line      => Token.Line,
-                        Column    => Token.Column,
-                        Message   => "wisi-motion-action: token " &
-                          WisiToken.Image (Token.ID, Data.Descriptor.all) &
-                          " has no cache; add to statement-action for " &
-                          Trimmed_Image (Tree.Production_ID (Nonterm)) & ".");
-                  end if;
-
-                  if Has_Element (Prev_Cache_Cur) then
-                     declare
-                        Cache      : Navigate_Cache_Type renames 
Data.Navigate_Caches (Cache_Cur);
-                        Prev_Cache : Navigate_Cache_Type renames 
Data.Navigate_Caches (Prev_Cache_Cur);
-                     begin
-                        if not Cache.Prev_Pos.Set then
-                           Cache.Prev_Pos := (True, Prev_Cache.Pos);
-                           if WisiToken.Trace_Action > Detail then
-                              Ada.Text_IO.Put_Line ("   " & Cache.Pos'Image & 
" prev to " & Cache.Prev_Pos.Item'Image);
-                           end if;
-                        end if;
-
-                        if not Prev_Cache.Next_Pos.Set then
-                           Prev_Cache.Next_Pos := (True, Cache.Pos);
-                           if WisiToken.Trace_Action > Detail then
-                              Ada.Text_IO.Put_Line
-                                ("   " & Prev_Cache.Pos'Image & " next to " & 
Prev_Cache.Next_Pos.Item'Image);
-                           end if;
-                        end if;
-                     end;
-                  end if;
-
-                  loop
-                     --  Set Prev_Cache_Cur to last motion cache in nonterm 
chain
-                     exit when not Data.Navigate_Caches 
(Cache_Cur).Next_Pos.Set;
-
-                     Cache_Cur := Find (Iter, Data.Navigate_Caches 
(Cache_Cur).Next_Pos.Item);
-                     pragma Assert (Has_Element (Cache_Cur)); --  otherwise 
there's a bug in this subprogram.
-
-                  end loop;
-                  Prev_Cache_Cur := Cache_Cur;
-               end if;
-            end;
-         end if;
-      end loop;
-   end Motion_Action;
-
-   procedure Face_Apply_Action
-     (Data    : in out Parse_Data_Type;
-      Tree    : in     Syntax_Trees.Tree;
-      Nonterm : in     Valid_Node_Index;
-      Tokens  : in     Valid_Node_Index_Array;
-      Params  : in     Face_Apply_Param_Array)
-   is
-      pragma Unreferenced (Nonterm);
-
-      use Face_Cache_Trees;
-
-      Iter       : constant Iterator := Data.Face_Caches.Iterate;
-      Cache_Cur  : Cursor;
-      Suffix_Cur : Cursor;
-   begin
-      for Param of Params loop
-         if Tree.Byte_Region (Tokens (Param.Index)) /= Null_Buffer_Region then
-            declare
-               Token : Aug_Token_Const_Ref renames Get_Aug_Token_Const_1 
(Tree, Tokens (Param.Index));
-            begin
-               Cache_Cur := Find (Iter, Token.Char_Region.First, Direction => 
Ascending);
-               if Has_Element (Cache_Cur) then
-                  declare
-                     Cache : Face_Cache_Type renames Data.Face_Caches 
(Cache_Cur);
-                  begin
-                     case Cache.Class is
-                     when Prefix =>
-                        Cache.Face := (True, Param.Prefix_Face);
-
-                        --  Check for suffix
-                        Suffix_Cur := Next (Iter, Cache_Cur);
-                        if Has_Element (Suffix_Cur) then
-                           declare
-                              Suf_Cache : Face_Cache_Type renames 
Data.Face_Caches (Suffix_Cur);
-                           begin
-                              if Suffix = Suf_Cache.Class and
-                                Inside (Suf_Cache.Char_Region.First, 
Token.Char_Region)
-                              then
-                                 Suf_Cache.Face := (True, Param.Suffix_Face);
-                              end if;
-                           end;
-                        end if;
-
-                     when Suffix =>
-                        Cache.Face := (True, Param.Suffix_Face);
-                     end case;
-                  end;
-               else
-                  Data.Face_Caches.Insert ((Token.Char_Region, Suffix, (True, 
Param.Suffix_Face)));
-               end if;
-            end;
-         end if;
-      end loop;
-   end Face_Apply_Action;
-
-   procedure Face_Apply_List_Action
-     (Data    : in out Parse_Data_Type;
-      Tree    : in     Syntax_Trees.Tree;
-      Nonterm : in     Valid_Node_Index;
-      Tokens  : in     Valid_Node_Index_Array;
-      Params  : in     Face_Apply_Param_Array)
-   is
-      pragma Unreferenced (Nonterm);
-      use Face_Cache_Trees;
-
-      Iter      : constant Iterator := Data.Face_Caches.Iterate;
-      Cache_Cur : Cursor;
-   begin
-      for Param of Params loop
-         if Tree.Byte_Region (Tokens (Param.Index)) /= Null_Buffer_Region then
-            declare
-               Token : Aug_Token_Const_Ref renames Get_Aug_Token_Const_1 
(Tree, Tokens (Param.Index));
-            begin
-               Cache_Cur := Find_In_Range (Iter, Ascending, 
Token.Char_Region.First, Token.Char_Region.Last);
-               loop
-                  exit when not Has_Element (Cache_Cur) or else
-                    Data.Face_Caches (Cache_Cur).Char_Region.First > 
Token.Char_Region.Last;
-                  declare
-                     Cache : Face_Cache_Type renames Data.Face_Caches 
(Cache_Cur);
-                  begin
-                     case Cache.Class is
-                     when Prefix =>
-                        Cache.Face := (True, Param.Prefix_Face);
-
-                     when Suffix =>
-                        Cache.Face := (True, Param.Suffix_Face);
-                     end case;
-                  end;
-                  Cache_Cur := Next (Iter, Cache_Cur);
-               end loop;
-            end;
-         end if;
-      end loop;
-   end Face_Apply_List_Action;
-
-   procedure Face_Mark_Action
-     (Data    : in out Parse_Data_Type;
-      Tree    : in     Syntax_Trees.Tree;
-      Nonterm : in     Valid_Node_Index;
-      Tokens  : in     Valid_Node_Index_Array;
-      Params  : in     Face_Mark_Param_Array)
-   is
-      pragma Unreferenced (Nonterm);
-
-      use Face_Cache_Trees;
-
-      Iter      : constant Iterator := Data.Face_Caches.Iterate;
-      Cache_Cur : Cursor;
-   begin
-      for Param of Params loop
-         if Tree.Byte_Region (Tokens (Param.Index)) /= Null_Buffer_Region then
-            declare
-               Token : Aug_Token_Const_Ref renames Get_Aug_Token_Const_1 
(Tree, Tokens (Param.Index));
-            begin
-               Cache_Cur := Find (Iter, Token.Char_Region.First, Direction => 
Ascending);
-               if Has_Element (Cache_Cur) then
-                  declare
-                     Cache : Face_Cache_Type renames Data.Face_Caches 
(Cache_Cur);
-                     Other_Cur : Cursor := Find_In_Range
-                       (Iter, Ascending, Cache.Char_Region.Last + 1, 
Token.Char_Region.Last);
-                     Temp : Cursor;
-                  begin
-                     loop
-                        exit when not Has_Element (Other_Cur) or else
-                          Data.Face_Caches (Other_Cur).Char_Region.First > 
Token.Char_Region.Last;
-                        Temp := Other_Cur;
-                        Other_Cur := Next (Iter, Other_Cur);
-                        Delete (Data.Face_Caches, Temp);
-                     end loop;
-
-                     Cache.Class            := Param.Class;
-                     Cache.Char_Region.Last := Token.Char_Region.Last;
-                  end;
-               else
-                  Data.Face_Caches.Insert ((Token.Char_Region, Param.Class, 
(Set => False)));
-               end if;
-            end;
-         end if;
-      end loop;
-   end Face_Mark_Action;
-
-   procedure Face_Remove_Action
-     (Data    : in out Parse_Data_Type;
-      Tree    : in     Syntax_Trees.Tree;
-      Nonterm : in     Valid_Node_Index;
-      Tokens  : in     Valid_Node_Index_Array;
-      Params  : in     Face_Remove_Param_Array)
-   is
-      pragma Unreferenced (Nonterm);
-      use Face_Cache_Trees;
-
-      Iter      : constant Iterator := Data.Face_Caches.Iterate;
-      Cache_Cur : Cursor;
-      Temp      : Cursor;
-   begin
-      for I of Params loop
-         if Tree.Byte_Region (Tokens (I)) /= Null_Buffer_Region then
-            declare
-               Token : Aug_Token_Const_Ref renames Get_Aug_Token_Const_1 
(Tree, Tokens (I));
-            begin
-               Cache_Cur := Find_In_Range (Iter, Ascending, 
Token.Char_Region.First, Token.Char_Region.Last);
-               loop
-                  exit when not Has_Element (Cache_Cur) or else
-                    Data.Face_Caches (Cache_Cur).Char_Region.First > 
Token.Char_Region.Last;
-                  Temp := Cache_Cur;
-                  Cache_Cur := Next (Iter, Cache_Cur);
-                  Delete (Data.Face_Caches, Temp);
-               end loop;
-            end;
-         end if;
-      end loop;
-   end Face_Remove_Action;
-
-   function "+" (Item : in Integer) return Indent_Arg_Arrays.Vector
-   is begin
-      return Result : Indent_Arg_Arrays.Vector do
-         Result.Append (Item);
-      end return;
-   end "+";
-
-   function "&" (List : in Indent_Arg_Arrays.Vector; Item : in Integer) return 
Indent_Arg_Arrays.Vector
-   is begin
-      return Result : Indent_Arg_Arrays.Vector := List do
-         Result.Append (Item);
-      end return;
-   end "&";
-
-   function "&" (Left, Right : in Integer) return Indent_Arg_Arrays.Vector
-   is begin
-      return Result : Indent_Arg_Arrays.Vector do
-         Result.Append (Left);
-         Result.Append (Right);
-      end return;
-   end "&";
-
-   function Image (Item : in Simple_Indent_Param) return String
-   is begin
-      return "(" & Simple_Indent_Param_Label'Image (Item.Label) &
-        (case Item.Label is
-         when None => "",
-         when Int => Integer'Image (Item.Int_Delta),
-         when Anchored_Label => Positive_Index_Type'Image 
(Item.Anchored_Index) & "," &
-              Integer'Image (Item.Anchored_Delta),
-         when Language => "<language_function>") & ")";
-   end Image;
-
-   function Image (Item : in Indent_Param) return String
-   is begin
-      return "(" & Indent_Param_Label'Image (Item.Label) & ", " &
-        (case Item.Label is
-         when Simple => Image (Item.Param),
-         when Hanging_Label =>
-            Image (Item.Hanging_Delta_1) & ", "  & Image 
(Item.Hanging_Delta_2) & ")");
-   end Image;
-
-   function Image (Item : in Indent_Pair) return String
-   is begin
-      return "(" & Image (Item.Code_Delta) &
-        (if Item.Comment_Present
-         then ", " & Image (Item.Comment_Delta)
-         else "") & ")";
-   end Image;
-
-   procedure Indent_Action_0
-     (Data    : in out Parse_Data_Type'Class;
-      Tree    : in     Syntax_Trees.Tree;
-      Nonterm : in     Valid_Node_Index;
-      Tokens  : in     Valid_Node_Index_Array;
-      Params  : in     Indent_Param_Array)
-   is begin
-      if Trace_Action > Outline then
-         Ada.Text_IO.Put_Line (";; indent_action_0: " & Tree.Image (Nonterm, 
Data.Descriptor.all));
-      end if;
-
-      for I in Tokens'Range loop
-         if (Tree.Is_Virtual_Terminal (Tokens (I)) or
-               Tree.Byte_Region (Tokens (I)) /= Null_Buffer_Region) and
-           I in Params'Range -- in some translated EBNF, not every token has 
an indent param
-         then
-            declare
-               use all type SAL.Base_Peek_Type;
-               Tree_Token        : constant Valid_Node_Index := Tokens (I);
-               Token             : Aug_Token_Const_Ref renames 
Get_Aug_Token_Const_1 (Tree, Tree_Token);
-               Pair              : Indent_Pair renames Params (I);
-               Code_Delta        : Delta_Type;
-               Comment_Param     : Indent_Param;
-               Comment_Param_Set : Boolean                                := 
False;
-               Comment_Delta     : Delta_Type;
-            begin
-               if Trace_Action > Detail then
-                  Ada.Text_IO.Put_Line
-                    (";; indent_action_0 a: " & Tree.Image (Tree_Token, 
Data.Descriptor.all) & ": " & Image (Pair));
-               end if;
-
-               if Token.First_Indent_Line /= Invalid_Line_Number then
-                  Code_Delta := Indent_Compute_Delta
-                    (Data, Tree, Tokens, Pair.Code_Delta, Tree_Token, 
Indenting_Comment => False);
-
-                  Indent_Token_1 (Data, Tree, Token, Code_Delta, 
Indenting_Comment => False);
-               end if;
-
-               if Token.First_Trailing_Comment_Line /= Invalid_Line_Number then
-                  if Pair.Comment_Present then
-                     Comment_Param     := Pair.Comment_Delta;
-                     Comment_Param_Set := True;
-
-                  elsif I < Tokens'Last then
-                     Comment_Param     := Params (I + 1).Code_Delta;
-                     Comment_Param_Set := True;
-
-                  end if;
-
-                  if Comment_Param_Set then
-                     Comment_Delta := Indent_Compute_Delta
-                       (Data, Tree, Tokens, Comment_Param, Tree_Token, 
Indenting_Comment => True);
-
-                     Indent_Token_1 (Data, Tree, Token, Comment_Delta, 
Indenting_Comment => True);
-                  end if;
-               end if;
-            end;
-         end if;
-      end loop;
-   end Indent_Action_0;
-
-   procedure Indent_Action_1
-     (Data    : in out Parse_Data_Type'Class;
-      Tree    : in     Syntax_Trees.Tree;
-      Nonterm : in     Valid_Node_Index;
-      Tokens  : in     Valid_Node_Index_Array;
-      N       : in     Positive_Index_Type;
-      Params  : in     Indent_Param_Array)
-   is
-      use all type Syntax_Trees.Node_Label;
-   begin
-      for I in Tokens'First .. N loop
-         declare
-            Aug : Aug_Token_Const_Ref renames Wisi.Get_Aug_Token_Const_1 
(Tree, Tokens (I));
-         begin
-            if Tree.Label (Tokens (I)) /= Virtual_Terminal and then Aug.First 
then
-               Indent_Action_0 (Data, Tree, Nonterm, Tokens, Params);
-               return;
-            end if;
-         end;
-      end loop;
-   end Indent_Action_1;
-
-   function Indent_Hanging_1
-     (Data              : in out Parse_Data_Type;
-      Tree              : in     Syntax_Trees.Tree;
-      Tokens            : in     Valid_Node_Index_Array;
-      Tree_Indenting    : in     Valid_Node_Index;
-      Indenting_Comment : in     Boolean;
-      Delta_1           : in     Simple_Indent_Param;
-      Delta_2           : in     Simple_Indent_Param;
-      Option            : in     Boolean;
-      Accumulate        : in     Boolean)
-     return Delta_Type
-   is
-      Indenting_Token : Aug_Token_Const_Ref renames Get_Aug_Token_Const_1 
(Tree, Tree_Indenting);
-   begin
-      if Indenting_Comment then
-         return Indent_Compute_Delta
-           (Data, Tree, Tokens, (Simple, Delta_1), Tree_Indenting, 
Indenting_Comment);
-      else
-         return
-           (Hanging,
-            Hanging_First_Line  => Indenting_Token.Line,
-            Hanging_Paren_State => Indenting_Token.Paren_State,
-            Hanging_Delta_1     => Indent_Compute_Delta
-              (Data, Tree, Tokens, (Simple, Delta_1), Tree_Indenting, 
Indenting_Comment).Simple_Delta,
-            Hanging_Delta_2     =>
-              (if (not Option) or
-                 Indenting_Token.Line = Indenting_Token.First_Indent_Line -- 
first token in tok is first on line
-               then Indent_Compute_Delta
-                 (Data, Tree, Tokens, (Simple, Delta_2), Tree_Indenting, 
Indenting_Comment).Simple_Delta
-               else Indent_Compute_Delta
-                 (Data, Tree, Tokens, (Simple, Delta_1), Tree_Indenting, 
Indenting_Comment).Simple_Delta),
-            Hanging_Accumulate => Accumulate);
-      end if;
-   end Indent_Hanging_1;
-
-   procedure Put_Language_Action
-     (Data    : in Parse_Data_Type;
-      Content : in String)
-   is
-      pragma Unreferenced (Data);
-   begin
-      Ada.Text_IO.Put_Line ("[" & Language_Action_Code & Content & "]");
-   end Put_Language_Action;
-
-   procedure Put (Data : in out Parse_Data_Type; Parser : in 
Parse.Base_Parser'Class)
-   is
-      use all type Ada.Containers.Count_Type;
-
-      Last_Term : constant Node_Index := Parser.Tree.Last_Terminal 
(Parser.Tree.Root);
-
-      function Get_Last_Char_Pos return Buffer_Pos
-      is begin
-
-         if Last_Term = Invalid_Node_Index then
-            --  All comments, or empty
-            if Data.Leading_Non_Grammar.Length > 0 then
-               return Data.Leading_Non_Grammar 
(Data.Leading_Non_Grammar.Last_Index).Char_Region.Last;
-            else
-               return Buffer_Pos'First;
-            end if;
-         else
-            declare
-               Aug : Aug_Token_Const_Ref renames Get_Aug_Token_Const_1 
(Parser.Tree, Last_Term);
-            begin
-               if Aug.Non_Grammar.Length = 0 then
-                  return Aug.Char_Region.Last;
-               else
-                  return Aug.Non_Grammar 
(Aug.Non_Grammar.Last_Index).Char_Region.Last;
-               end if;
-            end;
-         end if;
-      end Get_Last_Char_Pos;
-
-      Last_Char_Pos : constant Buffer_Pos := Get_Last_Char_Pos;
-
-      function Get_Last_Line return Line_Number_Type
-      is begin
-         for I in Data.Line_Begin_Char_Pos.First_Index .. 
Data.Line_Begin_Char_Pos.Last_Index loop
-            if Data.Line_Begin_Char_Pos (I) = Invalid_Buffer_Pos then
-               raise SAL.Programmer_Error with "line_begin_pos" & 
Line_Number_Type'Image (I) & " invalid";
-            end if;
-            if Data.Line_Begin_Char_Pos (I) > Last_Char_Pos then
-               if I > Line_Number_Type'First then
-                  return I - 1;
-               else
-                  return I;
-               end if;
-            end if;
-         end loop;
-         return Data.Line_Begin_Char_Pos.Last_Index;
-      end Get_Last_Line;
-
-   begin
-      if Trace_Action > Outline then
-         Ada.Text_IO.Put_Line
-           (";; last_char_pos:" & Buffer_Pos'Image (Last_Char_Pos + 1) &
-              " last_line:" & Line_Number_Type'Image (Get_Last_Line));
-      end if;
-
-      --  +1 to match Emacs region
-      Ada.Text_IO.Put_Line ('[' & End_Code & Buffer_Pos'Image (Last_Char_Pos + 
1) & ']');
-
-      case Data.Post_Parse_Action is
-      when Navigate =>
-         for Cache of Data.Navigate_Caches loop
-            Put (Cache);
-         end loop;
-         for Cache of Data.Name_Caches loop
-            Put (Cache);
-         end loop;
-
-      when Face =>
-         for Cache of Data.Face_Caches loop
-            Put (Cache);
-         end loop;
-
-      when Indent =>
-
-         Resolve_Anchors (Data);
-
-         if Trace_Action > Outline then
-            Ada.Text_IO.Put_Line (";; indent leading non_grammar");
-         end if;
-         for Token of Data.Leading_Non_Grammar loop
-            if Token.First then
-               Put (Token.Line, (Int, Data.Begin_Indent));
-            end if;
-         end loop;
-
-         --  It may be that not all lines in Data.Indents were parsed.
-         if Trace_Action > Outline then
-            Ada.Text_IO.Put_Line (";; indent grammar");
-         end if;
-         for I in Data.Indents.First_Index .. Get_Last_Line loop
-            Put (I, Data.Indents (I));
-         end loop;
-      end case;
-   end Put;
-
-   procedure Put (Lexer_Errors : in Lexer.Error_Lists.List)
-   is begin
-      for Item of Lexer_Errors loop
-         Ada.Text_IO.Put_Line
-           ('[' & Lexer_Error_Code & Buffer_Pos'Image (Item.Char_Pos) &
-              " ""lexer error" &
-              (if Item.Recover_Char (1) = ASCII.NUL
-               then """"
-               elsif Item.Recover_Char (1) = '"'
-               then """ ?\"""
-               else """ ?" & Item.Recover_Char (1)) &
-              "]");
-         if Item.Recover_Char (2) /= ASCII.NUL then
-            raise SAL.Programmer_Error with "lexer error with non-ascii or 
multiple repair char";
-         end if;
-      end loop;
-   end Put;
-
-   procedure Put
-     (Data         : in Parse_Data_Type;
-      Lexer_Errors : in Lexer.Error_Lists.List;
-      Parse_Errors : in Parse.LR.Parse_Error_Lists.List;
-      Tree         : in Syntax_Trees.Tree)
-   is
-      use all type SAL.Base_Peek_Type;
-      use Ada.Text_IO;
-      use Semantic_Checks;
-
-      function Safe_Pos (Node : in Valid_Node_Index) return Buffer_Pos
-      is
-         --  Return a reasonable position for the error at Node.
-         --
-         --  In a successful parse with error recovery, Node is a terminal with
-         --  an augmented token in Data.Terminals, so that is the first
-         --  choice.
-         --
-         --  If this is an error due to a bad recovery, Node may be a virtual
-         --  token, with no position information, so we try to get information
-         --  from its parent.
-         use Syntax_Trees;
-
-         N : Node_Index := Node;
-      begin
-         loop
-            if Tree.Label (N) /= Virtual_Terminal then
-               declare
-                  Ref : Aug_Token_Const_Ref renames Get_Aug_Token_Const_1 
(Tree, N);
-               begin
-                  if Ref.Char_Region /= Null_Buffer_Region then
-                     return Ref.Element.Char_Region.First;
-                  end if;
-
-               end;
-            end if;
-            N := Tree.Parent (N);
-            exit when N = Invalid_Node_Index;
-         end loop;
-         return Buffer_Pos'First;
-      end Safe_Pos;
-
-      function Safe_Pos (Token : in Recover_Token) return Buffer_Pos
-      is begin
-         if Token.Name /= Null_Buffer_Region then
-            return Token.Name.First;
-
-         elsif Token.Byte_Region = Null_Buffer_Region then
-            return Buffer_Pos'First;
-
-         else
-            return Token.Byte_Region.First;
-         end if;
-      end Safe_Pos;
-
-   begin
-      Put (Lexer_Errors);
-
-      for Item of Parse_Errors loop
-         case Item.Label is
-         when Parse.LR.Action =>
-            Put_Line
-              ('[' & Parser_Error_Code & Buffer_Pos'Image (Safe_Pos 
(Item.Error_Token)) &
-                 " ""syntax error: expecting " & Image (Item.Expecting, 
Data.Descriptor.all) &
-                 ", found '" & Image (Tree.ID (Item.Error_Token), 
Data.Descriptor.all) & "'""]");
-
-         when Parse.LR.Check =>
-            Put_Line
-              ('[' & Check_Error_Code & Integer'Image
-                 (Semantic_Checks.Check_Status_Label'Pos 
(Item.Check_Status.Label)) &
-                 (case Item.Check_Status.Label is
-                  when Ok => "",
-                  when Error =>
-                     Buffer_Pos'Image (Safe_Pos 
(Item.Check_Status.Begin_Name)) &
-                       Buffer_Pos'Image (Safe_Pos 
(Item.Check_Status.End_Name)) &
-                       " ""block name error""]"));
-
-         when Parse.LR.Message =>
-            Put_Line
-              ('[' & Parser_Error_Code & Buffer_Pos'Image (Buffer_Pos'First) &
-                 " """ & (-Item.Msg) & """]");
-         end case;
-
-         if Item.Recover.Stack.Depth > 0 then
-            Put (Item.Recover, Data, Tree);
-         end if;
-      end loop;
-   end Put;
-
-   procedure Put_Error (Data : in Parse_Data_Type; Line_Number : in 
Line_Number_Type; Message : in String)
-   is
-      use Ada.Text_IO;
-   begin
-      Put_Line ("(error """ & Error_Message (Data.Lexer.File_Name, 
Line_Number, 0, Message) & """)");
-   end Put_Error;
-
-   ----------
-   --  Spec visible private subprograms, alphabetical
-
-   function Image (Item : in Simple_Delta_Type) return String
-   is begin
-      return "(" & Simple_Delta_Labels'Image (Item.Label) &
-        (case Item.Label is
-         when None => "",
-         when Int => Integer'Image (Item.Int_Delta),
-         when Anchored => Integer'Image (Item.Anchored_ID) & Integer'Image 
(Item.Anchored_Delta) & " " &
-              Boolean'Image (Item.Anchored_Accumulate))
-        & ")";
-   end Image;
-
-   function Image (Item : in Delta_Type) return String
-   is begin
-      return "(" & Delta_Labels'Image (Item.Label) &
-        (case Item.Label is
-         when Simple => " " & Image (Item.Simple_Delta),
-         when Hanging => Line_Number_Type'Image (Item.Hanging_First_Line) & 
Integer'Image (Item.Hanging_Paren_State) &
-              " " & Image (Item.Hanging_Delta_1) & " " & Image 
(Item.Hanging_Delta_2) & " " &
-              Boolean'Image (Item.Hanging_Accumulate)) & ")";
-   end Image;
-
-   function Current_Indent_Offset
-     (Data         : in Parse_Data_Type;
-      Anchor_Token : in Augmented_Token'Class;
-      Offset       : in Integer)
-     return Integer
-   is begin
-      return Offset + Integer (Anchor_Token.Char_Region.First - 
Data.Line_Begin_Char_Pos (Anchor_Token.Line));
-   end Current_Indent_Offset;
-
-   function First_Line
-     (Token             : in Augmented_Token;
-      Indenting_Comment : in Boolean)
-     return Line_Number_Type
-   is begin
-      return
-        (if Indenting_Comment then
-           (if Token.First_Trailing_Comment_Line = Invalid_Line_Number
-            then Token.Line
-            else Token.First_Trailing_Comment_Line)
-         else
-           (if Token.First_Indent_Line = Invalid_Line_Number
-            then Token.Line
-            else Token.First_Indent_Line));
-   end First_Line;
-
-   function Get_Aug_Token_Const_1
-     (Tree       : in Syntax_Trees.Tree'Class;
-      Tree_Index : in Valid_Node_Index)
-     return Aug_Token_Const_Ref
-   is begin
-      return To_Aug_Token_Const_Ref (Tree.Augmented (Tree_Index));
-   end Get_Aug_Token_Const_1;
-
-   function Get_Aug_Token_Const
-     (Data  : in Parse_Data_Type;
-      Tree  : in WisiToken.Syntax_Trees.Tree'Class;
-      Token : in WisiToken.Token_Index)
-     return Aug_Token_Const_Ref
-   is begin
-      return Get_Aug_Token_Const_1 (Tree, Data.Terminals.all 
(Token).Tree_Index);
-   end Get_Aug_Token_Const;
-
-   function Get_Aug_Token_Var
-     (Tree       : in Syntax_Trees.Tree'Class;
-      Tree_Index : in Valid_Node_Index)
-     return Aug_Token_Var_Ref
-   is begin
-      return To_Aug_Token_Var_Ref (Tree.Augmented (Tree_Index));
-   end Get_Aug_Token_Var;
-
-   function Get_Aug_Token_Var
-     (Data  : in Parse_Data_Type;
-      Tree  : in WisiToken.Syntax_Trees.Tree'Class;
-      Token : in WisiToken.Token_Index)
-     return Aug_Token_Var_Ref
-   is begin
-      return Get_Aug_Token_Var (Tree, Data.Terminals.all (Token).Tree_Index);
-   end Get_Aug_Token_Var;
-
-   function Get_Text
-     (Data       : in Parse_Data_Type;
-      Tree       : in WisiToken.Syntax_Trees.Tree;
-      Tree_Index : in WisiToken.Valid_Node_Index)
-     return String
-   is
-      use all type Syntax_Trees.Node_Label;
-   begin
-      case Tree.Label (Tree_Index) is
-      when Shared_Terminal | Nonterm =>
-         return Data.Lexer.Buffer_Text (Tree.Byte_Region (Tree_Index));
-
-      when Virtual_Terminal | Virtual_Identifier =>
-         raise SAL.Programmer_Error;
-
-      end case;
-   end Get_Text;
-
-   function Elisp_Escape_Quotes (Item : in String) return String
-   is
-      Result : String (Item'First .. Item'First + Item'Length * 2);
-      Last   : Integer := Item'First - 1;
-   begin
-      for I in Item'Range loop
-         if Item (I) = '"' then
-            Last := Last + 1;
-            Result (Last) := '\';
-         end if;
-         Last := Last + 1;
-         Result (Last) := Item (I);
-      end loop;
-      return Result (Result'First .. Last);
-   end Elisp_Escape_Quotes;
-
-   overriding
-   function Image
-     (Item       : in Augmented_Token;
-      Descriptor : in WisiToken.Descriptor)
-     return String
-   is
-      ID_Image : constant String := Image (Item.ID, Descriptor);
-   begin
-      if Item.Line /= Invalid_Line_Number then
-         return "(" & ID_Image &
-           Line_Number_Type'Image (Item.Line) & ":" & Trimmed_Image (Integer 
(Item.Column)) & ")";
-
-      elsif Item.Char_Region = Null_Buffer_Region then
-         if Item.Byte_Region = Null_Buffer_Region then
-            return "(" & ID_Image & ")";
-         else
-            return "(" & ID_Image & ", " & Image (Item.Byte_Region) & ")";
-         end if;
-      else
-         return "(" & ID_Image & ", " & Image (Item.Char_Region) & ")";
-      end if;
-   end Image;
-
-   function Indent_Anchored_2
-     (Data        : in out Parse_Data_Type;
-      Anchor_Line : in     Line_Number_Type;
-      Last_Line   : in     Line_Number_Type;
-      Offset      : in     Integer;
-      Accumulate  : in     Boolean)
-     return Delta_Type
-   is
-      --  Return an anchored delta
-      use Anchor_ID_Vectors;
-      --  We can't use a Reference here, because the Element in reference
-      --  types is constrained (as are all allocated objects of access
-      --  types; AARM 4.8 (6/3)), and we may need to change the Label.
-      Indent    : Indent_Type      := Data.Indents (Anchor_Line);
-      Anchor_ID : constant Integer := 1 + Max_Anchor_ID (Data, Anchor_Line, 
Last_Line);
-   begin
-      Data.Max_Anchor_ID := Integer'Max (Data.Max_Anchor_ID, Anchor_ID);
-
-      case Indent.Label is
-      when Not_Set =>
-         Indent := (Anchor_Nil, To_Vector (Anchor_ID, 1));
-
-         if Trace_Action > Extra then
-            Ada.Text_IO.Put_Line
-              (";; indent_anchored: " & Line_Number_Type'Image (Anchor_Line) & 
" => " & Image (Indent));
-         end if;
-
-      when Int =>
-         Indent := (Anchor_Int, To_Vector (Anchor_ID, 1), Indent.Int_Indent);
-
-         if Trace_Action > Extra then
-            Ada.Text_IO.Put_Line
-              (";; indent_anchored: " & Line_Number_Type'Image (Anchor_Line) & 
" => " & Image (Indent));
-         end if;
-
-      when Anchor_Nil =>
-         Indent.Anchor_Nil_IDs := Anchor_ID & Indent.Anchor_Nil_IDs;
-
-      when Anchor_Int =>
-         Indent.Anchor_Int_IDs := Anchor_ID & Indent.Anchor_Int_IDs;
-
-      when Anchored =>
-         Indent := (Anchor_Anchored, To_Vector (Anchor_ID, 1), 
Indent.Anchored_ID, Indent.Anchored_Delta);
-
-      when Anchor_Anchored =>
-         Indent.Anchor_Anchored_IDs := Anchor_ID & Indent.Anchor_Anchored_IDs;
-      end case;
-
-      Data.Indents.Replace_Element (Anchor_Line, Indent);
-
-      return (Simple, (Anchored, Anchor_ID, Offset, Accumulate));
-   end Indent_Anchored_2;
-
-   function Indent_Compute_Delta
-     (Data              : in out Parse_Data_Type'Class;
-      Tree              : in     Syntax_Trees.Tree;
-      Tokens            : in     Valid_Node_Index_Array;
-      Param             : in     Indent_Param;
-      Tree_Indenting    : in     Valid_Node_Index;
-      Indenting_Comment : in     Boolean)
-     return Delta_Type
-   is
-      Indenting_Token : Aug_Token_Const_Ref renames Get_Aug_Token_Const_1 
(Tree, Tree_Indenting);
-   begin
-      --  Evaluate wisi-anchored*, wisi-hanging*.
-      case Param.Label is
-      when Simple =>
-         case Param.Param.Label is
-         when None =>
-            return (Simple, (Label => None));
-
-         when Int =>
-            return (Simple, (Int, Param.Param.Int_Delta));
-
-         when Anchored_Label =>
-            declare
-               Anchor_Token : Aug_Token_Const_Ref renames Get_Aug_Token_Const_1
-                 (Tree, Tokens (Param.Param.Anchored_Index));
-            begin
-               case Anchored_Label'(Param.Param.Label) is
-               when Anchored_0 =>
-                  --  [2] wisi-anchored
-                  return Indent_Anchored_2
-                    (Data,
-                     Anchor_Line => Anchor_Token.Line,
-                     Last_Line   => Indenting_Token.Last_Line 
(Indenting_Comment),
-                     Offset      => Current_Indent_Offset (Data, Anchor_Token, 
Param.Param.Anchored_Delta),
-                     Accumulate  => True);
-
-               when Anchored_1 =>
-                  --  [2] wisi-anchored%
-                  return Indent_Anchored_2
-                    (Data,
-                     Anchor_Line => Anchor_Token.Line,
-                     Last_Line   => Indenting_Token.Last_Line 
(Indenting_Comment),
-                     Offset      => Paren_In_Anchor_Line (Data, Tree, 
Anchor_Token, Param.Param.Anchored_Delta),
-                     Accumulate  => True);
-
-               when Anchored_2 =>
-                  --  [2] wisi-anchored%-
-                  return Indent_Anchored_2
-                    (Data,
-                     Anchor_Line => Anchor_Token.Line,
-                     Last_Line   => Indenting_Token.Last_Line 
(Indenting_Comment),
-                     Offset      => Paren_In_Anchor_Line (Data, Tree, 
Anchor_Token, Param.Param.Anchored_Delta),
-                     Accumulate  => False);
-
-               when Anchored_3 =>
-                  --  [2] wisi-anchored*
-                  if Indenting_Token.First then
-                     return Indent_Anchored_2
-                       (Data,
-                        Anchor_Line => Anchor_Token.Line,
-                        Last_Line   => Indenting_Token.Last_Line 
(Indenting_Comment),
-                        Offset      => Current_Indent_Offset (Data, 
Anchor_Token, Param.Param.Anchored_Delta),
-                        Accumulate  => True);
-
-                  else
-                     return Null_Delta;
-                  end if;
-
-               when Anchored_4 =>
-                  --  [2] wisi-anchored*-
-                  return Indent_Anchored_2
-                    (Data,
-                     Anchor_Line => Anchor_Token.Line,
-                     Last_Line   => Indenting_Token.Last_Line 
(Indenting_Comment),
-                     Offset      => Current_Indent_Offset (Data, Anchor_Token, 
Param.Param.Anchored_Delta),
-                     Accumulate  => False);
-
-               end case;
-            end;
-
-         when Language =>
-            return Param.Param.Function_Ptr
-              (Data, Tree, Tokens, Tree_Indenting, Indenting_Comment, 
Param.Param.Args);
-         end case;
-
-      when Hanging_Label =>
-         case Hanging_Label'(Param.Label) is
-         when Hanging_0 => -- wisi-hanging
-            return Indent_Hanging_1
-              (Data, Tree, Tokens, Tree_Indenting, Indenting_Comment, 
Param.Hanging_Delta_1,
-               Param.Hanging_Delta_2,
-               Option => False, Accumulate => True);
-         when Hanging_1 => -- wisi-hanging-
-            return Indent_Hanging_1
-              (Data, Tree, Tokens, Tree_Indenting, Indenting_Comment, 
Param.Hanging_Delta_1,
-               Param.Hanging_Delta_2,
-               Option => False, Accumulate => False);
-         when Hanging_2 => -- wisi-hanging%
-            return Indent_Hanging_1
-              (Data, Tree, Tokens, Tree_Indenting, Indenting_Comment, 
Param.Hanging_Delta_1,
-               Param.Hanging_Delta_2,
-               Option => True, Accumulate => True);
-         when Hanging_3 => -- wisi-hanging%-
-            return Indent_Hanging_1
-              (Data, Tree, Tokens, Tree_Indenting, Indenting_Comment, 
Param.Hanging_Delta_1,
-               Param.Hanging_Delta_2,
-               Option => True, Accumulate => False);
-         end case;
-      end case;
-   end Indent_Compute_Delta;
-
-   procedure Indent_Token_1
-     (Data              : in out Parse_Data_Type;
-      Tree              : in     Syntax_Trees.Tree;
-      Indenting_Token   : in     Augmented_Token'Class;
-      Delta_Indent      : in     Delta_Type;
-      Indenting_Comment : in     Boolean)
-   is
-      --  Aplly Delta_Indent to Indenting_Token
-      First_Line : constant Line_Number_Type := Indenting_Token.First_Line 
(Indenting_Comment);
-      Last_Line  : constant Line_Number_Type := Indenting_Token.Last_Line 
(Indenting_Comment);
-   begin
-      if Trace_Action > Detail then
-         Ada.Text_IO.Put_Line
-           (";; indent_token_1: " & Indenting_Token.Image 
(Data.Descriptor.all) & " " & Image (Delta_Indent) &
-              Line_Number_Type'Image (First_Line) & " .." & 
Line_Number_Type'Image (Last_Line) &
-              (if Indenting_Comment then " comment" else ""));
-      end if;
-
-      for Line in First_Line .. Last_Line loop
-         if Data.Indent_Comment_Col_0 then
-            declare
-               use all type Ada.Text_IO.Count;
-
-               function Containing_Token return Base_Token_Index
-               is
-                  --  Return token index of terminal containing non_grammer on 
Line;
-                  --  Invalid_Token_Index if none.
-                  I : Line_Number_Type := Line;
-                  J : Base_Token_Index;
-               begin
-                  if Line < Data.Line_Begin_Token.First_Index then
-                     --  Line is before first grammar token; 
Leading_Non_Grammar checked
-                     --  below.
-                     return Invalid_Token_Index;
-                  end if;
-
-                  loop
-                     exit when Data.Line_Begin_Token.all (I) /= 
Base_Token_Arrays.No_Index;
-                     --  No_Index means Line is in a multi-line token, which 
could be a block comment.
-                     I := I - 1;
-                  end loop;
-
-                  J := Data.Line_Begin_Token.all (I);
-                  declare
-                     Aug : Augmented_Token renames Get_Aug_Token_Const (Data, 
Tree, J);
-                  begin
-                     if Line in Aug.First_Trailing_Comment_Line .. 
Aug.Last_Trailing_Comment_Line then
-                        return J;
-                     else
-                        return Invalid_Token_Index;
-                     end if;
-                  end;
-               end Containing_Token;
-
-               Indent     : Boolean                   := True;
-               Containing : constant Base_Token_Index := Containing_Token;
-            begin
-               if Line < Data.Line_Begin_Token.First_Index then
-                  --  Line is before the first grammar token. We may be doing 
a partial
-                  --  parse where the initial indent is non-zero, so we still 
have to
-                  --  check for column 0.
-                  for Tok of Data.Leading_Non_Grammar loop
-                     if Tok.Line = Line and then
-                       Tok.ID in Data.First_Comment_ID .. Data.Last_Comment_ID 
and then
-                       Tok.Column = 0
-                     then
-                        Indent := False;
-                        exit;
-                     end if;
-                  end loop;
-
-               elsif Containing /= Invalid_Token_Index then
-                  for Tok of Get_Aug_Token_Const (Data, Tree, 
Containing).Non_Grammar loop
-                     if Tok.Line = Line and then
-                       Tok.ID in Data.First_Comment_ID .. Data.Last_Comment_ID 
and then
-                       Tok.Column = 0
-                     then
-                        Indent := False;
-                        exit;
-                     end if;
-                  end loop;
-               end if;
-
-               if Indent then
-                  Indent_Line (Data, Line, Delta_Indent);
-               else
-                  Indent_Line (Data, Line, (Simple, (Int, 0)));
-               end if;
-            end;
-         else
-            Indent_Line (Data, Line, Delta_Indent);
-         end if;
-      end loop;
-   end Indent_Token_1;
-
-   function Last_Line
-     (Token             : in Augmented_Token;
-      Indenting_Comment : in Boolean)
-     return Line_Number_Type
-   is begin
-      return
-        (if Indenting_Comment then
-           (if Token.Last_Trailing_Comment_Line = Invalid_Line_Number
-            then Token.Line
-            else Token.Last_Trailing_Comment_Line)
-         else
-           (if Token.Last_Indent_Line = Invalid_Line_Number
-            then Token.Line
-            else Token.Last_Indent_Line));
-   end Last_Line;
-
-end Wisi;
diff --git a/packages/wisi/wisi.ads b/packages/wisi/wisi.ads
deleted file mode 100644
index e707ab8..0000000
--- a/packages/wisi/wisi.ads
+++ /dev/null
@@ -1,769 +0,0 @@
---  Abstract :
---
---  Ada implementation of wisi parser actions.
---
---  References
---
---  [1] wisi-parse-common.el - defines common stuff.
---
---  [2] wisi.texi - defines parse action functions.
---
---  [3] wisi-process-parse.el - defines elisp/process API
---
---  Copyright (C) 2017 - 2020 Free Software Foundation, Inc.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-with Ada.Containers.Doubly_Linked_Lists;
-with Ada.Containers.Vectors;
-with SAL.Gen_Unbounded_Definite_Red_Black_Trees;
-with SAL.Gen_Unbounded_Definite_Vectors;
-with WisiToken.Parse.LR;
-with WisiToken.Lexer;
-with WisiToken.Syntax_Trees;
-package Wisi is
-   use all type WisiToken.Base_Buffer_Pos;
-
-   function Image (Aug : in WisiToken.Base_Token_Class_Access; Descriptor : in 
WisiToken.Descriptor) return String;
-   function Image (Action : in WisiToken.Syntax_Trees.Semantic_Action) return 
String;
-   --  For Syntax_Trees.Print_Tree, Parser.Execute_Action
-
-   type Post_Parse_Action_Type is (Navigate, Face, Indent);
-
-   type Parse_Data_Type
-     (Terminals        : not null access constant 
WisiToken.Base_Token_Arrays.Vector;
-      Line_Begin_Token : not null access constant 
WisiToken.Line_Begin_Token_Vectors.Vector)
-     is new WisiToken.Syntax_Trees.User_Data_Type with private;
-
-   procedure Initialize
-     (Data              : in out Parse_Data_Type;
-      Lexer             : in     WisiToken.Lexer.Handle;
-      Descriptor        : access constant WisiToken.Descriptor;
-      Base_Terminals    : in     WisiToken.Base_Token_Array_Access;
-      Post_Parse_Action : in     Post_Parse_Action_Type;
-      Begin_Line        : in     WisiToken.Line_Number_Type;
-      End_Line          : in     WisiToken.Line_Number_Type;
-      Begin_Indent      : in     Integer;
-      Params            : in     String);
-   --  Begin_Line, Begin_Indent, Line_Count only used for Indent. Params
-   --  contains language-specific indent parameter values.
-
-   overriding procedure Reset (Data : in out Parse_Data_Type);
-   --  Reset for a new parse, with data from previous Initialize.
-
-   function Source_File_Name (Data : in Parse_Data_Type) return String;
-   function Post_Parse_Action (Data : in Parse_Data_Type) return 
Post_Parse_Action_Type;
-
-   overriding
-   procedure Lexer_To_Augmented
-     (Data  : in out          Parse_Data_Type;
-      Tree  : in out          WisiToken.Syntax_Trees.Tree'Class;
-      Token : in              WisiToken.Base_Token;
-      Lexer : not null access WisiToken.Lexer.Instance'Class);
-
-   overriding
-   procedure Insert_Token
-     (Data  : in out Parse_Data_Type;
-      Tree  : in out WisiToken.Syntax_Trees.Tree'Class;
-      Token : in     WisiToken.Valid_Node_Index);
-
-   overriding
-   procedure Delete_Token
-     (Data                : in out Parse_Data_Type;
-      Tree                : in out WisiToken.Syntax_Trees.Tree'Class;
-      Deleted_Token_Index : in     WisiToken.Token_Index);
-
-   overriding
-   procedure Reduce
-     (Data    : in out Parse_Data_Type;
-      Tree    : in out WisiToken.Syntax_Trees.Tree'Class;
-      Nonterm : in     WisiToken.Valid_Node_Index;
-      Tokens  : in     WisiToken.Valid_Node_Index_Array);
-
-   type Navigate_Class_Type is (Motion, Statement_End, Statement_Override, 
Statement_Start, Misc);
-   --  Matches [1] wisi-class-list.
-
-   type Index_Navigate_Class is record
-      Index : WisiToken.Positive_Index_Type; -- into Tokens
-      Class : Navigate_Class_Type;
-   end record;
-
-   type Statement_Param_Array is array (Natural range <>) of 
Index_Navigate_Class;
-
-   procedure Statement_Action
-     (Data    : in out Parse_Data_Type;
-      Tree    : in     WisiToken.Syntax_Trees.Tree;
-      Nonterm : in     WisiToken.Valid_Node_Index;
-      Tokens  : in     WisiToken.Valid_Node_Index_Array;
-      Params  : in     Statement_Param_Array);
-   --  Implements [2] wisi-statement-action.
-
-   procedure Name_Action
-     (Data    : in out Parse_Data_Type;
-      Tree    : in     WisiToken.Syntax_Trees.Tree;
-      Nonterm : in     WisiToken.Valid_Node_Index;
-      Tokens  : in     WisiToken.Valid_Node_Index_Array;
-      Name    : in     WisiToken.Positive_Index_Type);
-   --  Implements [2] wisi-name-action.
-
-   type Index_ID is record
-      Index : WisiToken.Positive_Index_Type; -- into Tokens
-      ID    : WisiToken.Token_ID;
-      --  If ID is not Invalid_Token_ID, it is the first token in the
-      --  nonterm that Index points to that should have a navigate cache for
-      --  Motion_Action to link to; an error is reported by Motion_Action if
-      --  it does not.
-      --
-      --  If ID is Invalid_Token_ID, and the token at Index is a
-      --  nonterminal, the first token in that nonterminal must have a
-      --  navigate cache; an error is reported by Motion_Action if not.
-   end record;
-
-   package Index_ID_Vectors is new Ada.Containers.Vectors 
(Ada.Containers.Count_Type, Index_ID);
-
-   subtype Motion_Param_Array is Index_ID_Vectors.Vector;
-
-   Invalid_Token_ID : WisiToken.Token_ID := WisiToken.Invalid_Token_ID;
-   --  So Create_Parser can just use "Invalid_Token_ID".
-
-   procedure Motion_Action
-     (Data    : in out Parse_Data_Type;
-      Tree    : in     WisiToken.Syntax_Trees.Tree;
-      Nonterm : in     WisiToken.Valid_Node_Index;
-      Tokens  : in     WisiToken.Valid_Node_Index_Array;
-      Params  : in     Motion_Param_Array);
-   --  Implements [2] wisi-motion-action.
-
-   type Index_Faces is record
-      Index       : WisiToken.Positive_Index_Type; -- into Tokens
-      Prefix_Face : Integer; -- into grammar.Face_List
-      Suffix_Face : Integer; -- into grammar.Face_List
-   end record;
-
-   type Face_Apply_Param_Array is array (Natural range <>) of Index_Faces;
-
-   procedure Face_Apply_Action
-     (Data    : in out Parse_Data_Type;
-      Tree    : in     WisiToken.Syntax_Trees.Tree;
-      Nonterm : in     WisiToken.Valid_Node_Index;
-      Tokens  : in     WisiToken.Valid_Node_Index_Array;
-      Params  : in     Face_Apply_Param_Array);
-   --  Implements [2] wisi-face-apply-action.
-
-   procedure Face_Apply_List_Action
-     (Data    : in out Parse_Data_Type;
-      Tree    : in     WisiToken.Syntax_Trees.Tree;
-      Nonterm : in     WisiToken.Valid_Node_Index;
-      Tokens  : in     WisiToken.Valid_Node_Index_Array;
-      Params  : in     Face_Apply_Param_Array);
-   --  Implements [2] wisi-face-apply-list-action.
-
-   type Face_Class_Type is (Prefix, Suffix);
-
-   type Index_Face_Class is record
-      Index : WisiToken.Positive_Index_Type; -- into Tokens
-      Class : Face_Class_Type;
-   end record;
-
-   type Face_Mark_Param_Array is array (Natural range <>) of Index_Face_Class;
-
-   procedure Face_Mark_Action
-     (Data    : in out Parse_Data_Type;
-      Tree    : in     WisiToken.Syntax_Trees.Tree;
-      Nonterm : in     WisiToken.Valid_Node_Index;
-      Tokens  : in     WisiToken.Valid_Node_Index_Array;
-      Params  : in     Face_Mark_Param_Array);
-   --  Implements [2] wisi-face-mark-action.
-
-   type Face_Remove_Param_Array is array (Natural range <>) of 
WisiToken.Positive_Index_Type;
-
-   procedure Face_Remove_Action
-     (Data    : in out Parse_Data_Type;
-      Tree    : in     WisiToken.Syntax_Trees.Tree;
-      Nonterm : in     WisiToken.Valid_Node_Index;
-      Tokens  : in     WisiToken.Valid_Node_Index_Array;
-      Params  : in     Face_Remove_Param_Array);
-   --  Implements [2] wisi-face-remove-action.
-
-   ----------
-   --  Indent
-   --
-   --  Indent functions are represented by the Indent_Param type.
-
-   type Simple_Indent_Param_Label is -- not hanging
-     (None,
-      Int,
-      Anchored_0, -- [2] wisi-anchored
-      Anchored_1, -- [2] wisi-anchored%
-      Anchored_2, -- [2] wisi-anchored%-
-      Anchored_3, -- [2] wisi-anchored*
-      Anchored_4, -- [2] wisi-anchored*-
-      Language    -- [2] language-specific function
-     );
-   subtype Anchored_Label is Simple_Indent_Param_Label range Anchored_0 .. 
Anchored_4;
-
-   --  Arguments to language-specific functions are integers; one of
-   --  delta, Token_Number, or Token_ID - the syntax does not distinguish
-   --  among these three types.
-
-   package Indent_Arg_Arrays is new Ada.Containers.Vectors 
(WisiToken.Positive_Index_Type, Integer);
-
-   function "+" (Item : in Integer) return Indent_Arg_Arrays.Vector;
-   function "&" (List : in Indent_Arg_Arrays.Vector; Item : in Integer) return 
Indent_Arg_Arrays.Vector;
-   function "&" (Left, Right : in Integer) return Indent_Arg_Arrays.Vector;
-
-   type Delta_Type (<>) is private;
-
-   type Language_Indent_Function is access function
-     (Data              : in out Parse_Data_Type'Class;
-      Tree              : in     WisiToken.Syntax_Trees.Tree;
-      Tree_Tokens       : in     WisiToken.Valid_Node_Index_Array;
-      Tree_Indenting    : in     WisiToken.Valid_Node_Index;
-      Indenting_Comment : in     Boolean;
-      Args              : in     Indent_Arg_Arrays.Vector)
-     return Delta_Type;
-
-   Null_Args : Indent_Arg_Arrays.Vector renames Indent_Arg_Arrays.Empty_Vector;
-
-   type Simple_Indent_Param (Label : Simple_Indent_Param_Label := None) is
-   record
-      case Label is
-      when None =>
-         null;
-
-      when Int =>
-         Int_Delta : Integer;
-
-      when Anchored_Label =>
-         Anchored_Index : WisiToken.Positive_Index_Type;
-         Anchored_Delta : Integer;
-
-      when Language =>
-         Function_Ptr : Language_Indent_Function;
-         Args         : Indent_Arg_Arrays.Vector;
-      end case;
-   end record;
-
-   function Image (Item : in Simple_Indent_Param) return String;
-
-   type Indent_Param_Label is
-     (Simple,
-      Hanging_0, -- [2] wisi-hanging
-      Hanging_1, -- [2] wisi-hanging-
-      Hanging_2, -- [2] wisi-hanging%
-      Hanging_3  -- [2] wisi-hanging%-
-     );
-   subtype Hanging_Label is Indent_Param_Label range Hanging_0 .. Hanging_3;
-
-   type Indent_Param (Label : Indent_Param_Label := Simple) is
-   record
-      case Label is
-      when Simple =>
-         Param : Simple_Indent_Param;
-
-      when Hanging_Label =>
-         Hanging_Delta_1 : Simple_Indent_Param;
-         Hanging_Delta_2 : Simple_Indent_Param;
-
-      end case;
-   end record;
-
-   function Image (Item : in Indent_Param) return String;
-
-   type Indent_Pair (Comment_Present : Boolean := False) is
-   record
-      Code_Delta : Indent_Param;
-      case Comment_Present is
-      when True =>
-         Comment_Delta : Indent_Param;
-      when False =>
-         null;
-      end case;
-   end record;
-
-   function Image (Item : in Indent_Pair) return String;
-
-   type Indent_Param_Array is array (WisiToken.Positive_Index_Type range <>) 
of Indent_Pair;
-
-   procedure Indent_Action_0
-     (Data    : in out Parse_Data_Type'Class;
-      Tree    : in     WisiToken.Syntax_Trees.Tree;
-      Nonterm : in     WisiToken.Valid_Node_Index;
-      Tokens  : in     WisiToken.Valid_Node_Index_Array;
-      Params  : in     Indent_Param_Array);
-   --  Implements [2] wisi-indent-action.
-
-   procedure Indent_Action_1
-     (Data    : in out Parse_Data_Type'Class;
-      Tree    : in     WisiToken.Syntax_Trees.Tree;
-      Nonterm : in     WisiToken.Valid_Node_Index;
-      Tokens  : in     WisiToken.Valid_Node_Index_Array;
-      N       : in     WisiToken.Positive_Index_Type;
-      Params  : in     Indent_Param_Array);
-   --  Implements [2] wisi-indent-action*.
-
-   function Indent_Hanging_1
-     (Data              : in out Parse_Data_Type;
-      Tree              : in     WisiToken.Syntax_Trees.Tree;
-      Tokens            : in     WisiToken.Valid_Node_Index_Array;
-      Tree_Indenting    : in     WisiToken.Valid_Node_Index;
-      Indenting_Comment : in     Boolean;
-      Delta_1           : in     Simple_Indent_Param;
-      Delta_2           : in     Simple_Indent_Param;
-      Option            : in     Boolean;
-      Accumulate        : in     Boolean)
-     return Delta_Type;
-   --  Implements [2] wisi-hanging, wisi-hanging%, wisi-hanging%-.
-   --
-   --  Language specific child packages may override this to implement
-   --  language-specific cases.
-
-   ----------
-   --  Other
-
-   procedure Refactor
-     (Data       : in out Parse_Data_Type;
-      Tree       : in out WisiToken.Syntax_Trees.Tree;
-      Action     : in     Positive;
-      Edit_Begin : in     WisiToken.Buffer_Pos) is null;
-
-   type Arg_Index_Array is array (Positive range <>) of 
WisiToken.Positive_Index_Type;
-
-   procedure Put_Language_Action
-     (Data    : in Parse_Data_Type;
-      Content : in String);
-   --  Send a Language_Action message to Emacs.
-
-   procedure Put (Data : in out Parse_Data_Type; Parser : in 
WisiToken.Parse.Base_Parser'Class);
-   --  Perform additional post-parse actions, then put result to
-   --  Ada.Text_IO.Current_Output, as encoded responses as defined in [3]
-   --  wisi-process-parse--execute.
-
-   procedure Put (Lexer_Errors : in WisiToken.Lexer.Error_Lists.List);
-   procedure Put
-     (Data         : in Parse_Data_Type;
-      Lexer_Errors : in WisiToken.Lexer.Error_Lists.List;
-      Parse_Errors : in WisiToken.Parse.LR.Parse_Error_Lists.List;
-      Tree         : in WisiToken.Syntax_Trees.Tree);
-   --  Put Lexer_Errors and Parse_Errors to Ada.Text_IO.Current_Output,
-   --  as encoded error responses as defined in [3]
-   --  wisi-process-parse--execute.
-
-   procedure Put_Error (Data : in Parse_Data_Type; Line_Number : in 
WisiToken.Line_Number_Type; Message : in String);
-   --  Put an error elisp form to Ada.Text_IO.Standard_Output.
-
-private
-
-   type Non_Grammar_Token is new WisiToken.Base_Token with record
-      First : Boolean := False;
-   end record;
-
-   package Non_Grammar_Token_Arrays is new SAL.Gen_Unbounded_Definite_Vectors
-     (WisiToken.Token_Index, Non_Grammar_Token, Default_Element => (others => 
<>));
-
-   type Augmented_Token is new WisiToken.Base_Token with record
-      --  Most fields are set by Lexer_To_Augmented at parse time; others
-      --  are set by Reduce for nonterminals.
-
-      Deleted : Boolean := False;
-      --  Set True by Parse_Data_Type.Delete_Token; Non_Grammar tokens are
-      --  moved to the previous non-deleted token.
-
-      --  The following fields are only needed for indent.
-
-      First : Boolean := False;
-      --  For a terminal, True if the token is first on a line.
-      --
-      --  For a nonterminal, True if some contained token's First is True.
-
-      Paren_State : Integer := 0;
-      --  Parenthesis nesting count, before token.
-
-      First_Terminals_Index : WisiToken.Base_Token_Index := 
WisiToken.Invalid_Token_Index;
-      --  For virtual tokens, Invalid_Token_Index
-      --
-      --  For terminal tokens, index of this token in Parser.Terminals.
-      --
-      --  For nonterminal tokens, index of first contained token in
-      --  Parser.Terminals.
-
-      Last_Terminals_Index : WisiToken.Base_Token_Index := 
WisiToken.Base_Token_Arrays.No_Index;
-      --  For non-virtual nonterminal tokens, index of last contained
-      --  token in Parser.Terminals.
-      --
-      --  For all others, same as First_Terminals_Index.
-
-      First_Indent_Line : WisiToken.Line_Number_Type := 
WisiToken.Invalid_Line_Number;
-      Last_Indent_Line  : WisiToken.Line_Number_Type := 
WisiToken.Invalid_Line_Number;
-      --  Lines that need indenting; first token on these lines is contained
-      --  in this token. If First is False, these are Invalid_Line_Number.
-      --
-      --  First_, Last_Indent_Line include blank and comment lines between
-      --  grammar tokens, but exclude trailing blanks and comments after the
-      --  last token, so they can be indented differently.
-
-      First_Trailing_Comment_Line : WisiToken.Line_Number_Type := 
WisiToken.Invalid_Line_Number;
-      Last_Trailing_Comment_Line  : WisiToken.Line_Number_Type := 
WisiToken.Invalid_Line_Number;
-      --  Trailing comment or blank lines (after the last contained grammar
-      --  token) that need indenting. Excludes comments following code on a
-      --  line. If there are no such lines, these are Invalid_Line_Number.
-
-      Non_Grammar : Non_Grammar_Token_Arrays.Vector;
-      --  For terminals, non-grammar tokens immediately following. For
-      --  nonterminals, empty.
-
-      Inserted_Before : WisiToken.Valid_Node_Index_Arrays.Vector;
-      --  Tokens inserted before this token by error recovery.
-
-   end record;
-   type Augmented_Token_Access is access all Augmented_Token;
-   type Augmented_Token_Access_Constant is access constant Augmented_Token;
-
-   type Aug_Token_Const_Ref (Element : not null access constant 
Augmented_Token) is null record with
-     Implicit_Dereference => Element;
-
-   function To_Aug_Token_Const_Ref (Item : in 
WisiToken.Base_Token_Class_Access) return Aug_Token_Const_Ref
-     is (Element => Augmented_Token_Access_Constant (Item));
-
-   type Aug_Token_Var_Ref (Element : not null access Augmented_Token) is null 
record with
-     Implicit_Dereference => Element;
-
-   function To_Aug_Token_Var_Ref (Item : in WisiToken.Base_Token_Class_Access) 
return Aug_Token_Var_Ref
-     is (Element => Augmented_Token_Access (Item));
-
-   overriding
-   function Image
-     (Item       : in Augmented_Token;
-      Descriptor : in WisiToken.Descriptor)
-     return String;
-   --  Return a string for debug/test messages
-
-   function First_Line
-     (Token             : in Augmented_Token;
-      Indenting_Comment : in Boolean)
-     return WisiToken.Line_Number_Type;
-   function Last_Line
-     (Token             : in Augmented_Token;
-      Indenting_Comment : in Boolean)
-     return WisiToken.Line_Number_Type;
-   --  Return first and last line in Token's region.
-
-   package Line_Paren_Vectors is new SAL.Gen_Unbounded_Definite_Vectors
-     (WisiToken.Line_Number_Type, Integer, Default_Element => Integer'Last);
-   package Line_Begin_Pos_Vectors is new SAL.Gen_Unbounded_Definite_Vectors
-     (WisiToken.Line_Number_Type, WisiToken.Buffer_Pos, Default_Element => 
WisiToken.Invalid_Buffer_Pos);
-
-   type Nil_Buffer_Pos (Set : Boolean := False) is record
-      case Set is
-      when True =>
-         Item : WisiToken.Buffer_Pos;
-      when False =>
-         null;
-      end case;
-   end record;
-
-   Nil : constant Nil_Buffer_Pos := (Set => False);
-
-   type Navigate_Cache_Type is record
-      Pos            : WisiToken.Buffer_Pos; -- implicit in [1] wisi-cache
-      Statement_ID   : WisiToken.Token_ID;   -- [1] wisi-cache-nonterm
-      ID             : WisiToken.Token_ID;   -- [1] wisi-cache-token
-      Length         : Natural;              -- [1] wisi-cache-last
-      Class          : Navigate_Class_Type;  -- [1] wisi-cache-class
-      Containing_Pos : Nil_Buffer_Pos;       -- [1] wisi-cache-containing
-      Prev_Pos       : Nil_Buffer_Pos;       -- [1] wisi-cache-prev
-      Next_Pos       : Nil_Buffer_Pos;       -- [1] wisi-cache-next
-      End_Pos        : Nil_Buffer_Pos;       -- [1] wisi-cache-end
-   end record;
-
-   function Key (Cache : in Navigate_Cache_Type) return WisiToken.Buffer_Pos 
is (Cache.Pos);
-
-   function Key_Compare (Left, Right : in WisiToken.Buffer_Pos) return 
SAL.Compare_Result is
-     (if Left > Right then SAL.Greater
-      elsif Left = Right then SAL.Equal
-      else SAL.Less);
-
-   package Navigate_Cache_Trees is new 
SAL.Gen_Unbounded_Definite_Red_Black_Trees
-     (Navigate_Cache_Type, WisiToken.Buffer_Pos);
-
-   function Key (Cache : in WisiToken.Buffer_Region) return 
WisiToken.Buffer_Pos is (Cache.First);
-
-   package Name_Cache_Trees is new SAL.Gen_Unbounded_Definite_Red_Black_Trees
-     (WisiToken.Buffer_Region, WisiToken.Buffer_Pos);
-
-   type Nil_Integer (Set : Boolean := False) is record
-      case Set is
-      when True =>
-         Item : Integer;
-      when False =>
-         null;
-      end case;
-   end record;
-
-   type Face_Cache_Type is record
-      Char_Region : WisiToken.Buffer_Region;
-      Class       : Face_Class_Type;
-      Face        : Nil_Integer; -- not set, or index into 
*-process-faces-names
-   end record;
-
-   function Key (Cache : in Face_Cache_Type) return WisiToken.Buffer_Pos is 
(Cache.Char_Region.First);
-
-   package Face_Cache_Trees is new SAL.Gen_Unbounded_Definite_Red_Black_Trees 
(Face_Cache_Type, WisiToken.Buffer_Pos);
-
-   type Indent_Label is (Not_Set, Int, Anchor_Nil, Anchor_Int, Anchored, 
Anchor_Anchored);
-
-   package Anchor_ID_Vectors is new Ada.Containers.Vectors (Natural, Positive);
-
-   type Indent_Type (Label : Indent_Label := Not_Set) is record
-      --  Indent values may be negative while indents are being computed.
-      case Label is
-      when Not_Set =>
-         null;
-
-      when Int =>
-         Int_Indent : Integer;
-
-      when Anchor_Nil =>
-         Anchor_Nil_IDs : Anchor_ID_Vectors.Vector; --  Largest ID first.
-
-      when Anchor_Int =>
-         Anchor_Int_IDs    : Anchor_ID_Vectors.Vector; --  Largest ID first.
-         Anchor_Int_Indent : Integer; --  Indent for this token.
-
-      when Anchored =>
-         Anchored_ID    : Positive;
-         Anchored_Delta : Integer; -- added to Anchor_Indent of Anchor_ID
-
-      when Anchor_Anchored =>
-         Anchor_Anchored_IDs   : Anchor_ID_Vectors.Vector;
-         Anchor_Anchored_ID    : Natural;
-         Anchor_Anchored_Delta : Integer;
-      end case;
-   end record;
-   First_Anchor_ID : constant Positive := Positive'First;
-
-   package Indent_Vectors is new SAL.Gen_Unbounded_Definite_Vectors
-     (WisiToken.Line_Number_Type, Indent_Type, Default_Element => (others => 
<>));
-   package Navigate_Cursor_Lists is new Ada.Containers.Doubly_Linked_Lists
-     (Navigate_Cache_Trees.Cursor, Navigate_Cache_Trees."=");
-
-   type Parse_Data_Type
-     (Terminals        : not null access constant 
WisiToken.Base_Token_Arrays.Vector;
-      Line_Begin_Token : not null access constant 
WisiToken.Line_Begin_Token_Vectors.Vector)
-     is new WisiToken.Syntax_Trees.User_Data_Type with
-   record
-      --  Aux token info
-      First_Comment_ID : WisiToken.Token_ID := WisiToken.Invalid_Token_ID;
-      Last_Comment_ID  : WisiToken.Token_ID := WisiToken.Invalid_Token_ID;
-      Left_Paren_ID    : WisiToken.Token_ID := WisiToken.Invalid_Token_ID;
-      Right_Paren_ID   : WisiToken.Token_ID := WisiToken.Invalid_Token_ID;
-
-      Embedded_Quote_Escape_Doubled : Boolean := False;
-
-      --  Data from parsing
-
-      --  All Augmented_Tokens are stored in the syntax tree.
-      Last_Terminal_Node : WisiToken.Node_Index := 
WisiToken.Invalid_Node_Index;
-
-      Leading_Non_Grammar : Non_Grammar_Token_Arrays.Vector;
-      --  non-grammar tokens before first grammar token.
-
-      Line_Begin_Char_Pos : Line_Begin_Pos_Vectors.Vector;
-      --  Character position at the start of the first token on each line.
-      --  Cached from Line_Begin_Token to simplify indent computations.
-
-      Line_Paren_State : Line_Paren_Vectors.Vector;
-      --  Parenthesis nesting state at the start of each line; used by
-      --  Indent. Set by Lexer_To_Augmented on New_Line_ID, updated by
-      --  Insert_Token, Delete_Token.
-
-      Current_Paren_State : Integer;
-      --  Current parenthesis nesting state; used by Indent. Set by
-      --  Lexer_To_Augmented on Left_Paren_ID, Right_Paren_ID.
-
-      --  Data for post-parse actions
-
-      Lexer             : WisiToken.Lexer.Handle;
-      Descriptor        : access constant WisiToken.Descriptor;
-      Base_Terminals    : WisiToken.Base_Token_Array_Access;
-      Post_Parse_Action : Post_Parse_Action_Type;
-      Navigate_Caches   : Navigate_Cache_Trees.Tree;  -- Set by Navigate.
-      Name_Caches       : Name_Cache_Trees.Tree;      -- Set by Navigate.
-      End_Positions     : Navigate_Cursor_Lists.List; -- Dynamic data for 
Navigate.
-      Face_Caches       : Face_Cache_Trees.Tree;      -- Set by Face.
-      Indents           : Indent_Vectors.Vector;      -- Set by Indent.
-      Begin_Indent      : Integer;                    -- Indentation of line 
at start of parse.
-
-      --  Copied from language-specific parameters
-      Indent_Comment_Col_0 : Boolean := False;
-
-      --  Dynamic data for Indent
-      Max_Anchor_ID : Integer;
-   end record;
-
-   type Simple_Delta_Labels is (None, Int, Anchored);
-
-   --  subtype Non_Anchored_Delta_Labels is Simple_Delta_Labels range None .. 
Int;
-
-   --  type Non_Anchored_Delta (Label : Non_Anchored_Delta_Labels := None) is
-   --  record
-   --     case Label is
-   --     when None =>
-   --        null;
-   --     when Int =>
-   --        Int_Delta : Integer;
-   --     end case;
-   --  end record;
-
-   --  function Image (Item : in Non_Anchored_Delta) return String;
-   --  For debugging
-
-   type Simple_Delta_Type (Label : Simple_Delta_Labels := None) is
-   record
-      case Label is
-      when None =>
-         null;
-
-      when Int =>
-         Int_Delta : Integer;
-
-      when Anchored =>
-         Anchored_ID         : Natural;
-         Anchored_Delta      : Integer;
-         Anchored_Accumulate : Boolean;
-
-      end case;
-   end record;
-
-   function Image (Item : in Simple_Delta_Type) return String;
-   --  For debugging
-
-   type Delta_Labels is (Simple, Hanging);
-
-   type Delta_Type (Label : Delta_Labels := Simple) is
-   record
-      case Label is
-      when Simple =>
-         Simple_Delta : Simple_Delta_Type;
-
-      when Hanging =>
-         Hanging_First_Line  : WisiToken.Line_Number_Type;
-         Hanging_Paren_State : Integer;
-         Hanging_Delta_1     : Simple_Delta_Type; -- indentation of first line
-         Hanging_Delta_2     : Simple_Delta_Type; -- indentation of 
continuation lines
-         Hanging_Accumulate  : Boolean;
-      end case;
-   end record;
-
-   Null_Delta : constant Delta_Type := (Simple, (Label => None));
-
-   function Image (Item : in Delta_Type) return String;
-   --  For debugging
-
-   ----------
-   --  Utilities for language-specific child packages
-
-   function Current_Indent_Offset
-     (Data         : in Parse_Data_Type;
-      Anchor_Token : in Augmented_Token'Class;
-      Offset       : in Integer)
-     return Integer;
-   --  Return offset from beginning of first token on line containing
-   --  Anchor_Token, to beginning of Anchor_Token, plus Offset.
-
-   function Get_Aug_Token_Const_1
-     (Tree       : in WisiToken.Syntax_Trees.Tree'Class;
-      Tree_Index : in WisiToken.Valid_Node_Index)
-     return Aug_Token_Const_Ref;
-   --  WORKAROUND: GNAT Community 2019 can't do the overload resolution
-   --  between the two Get_Aug_Token_Const without an explicit renames,
-   --  so we add _1 to this one.
-
-   function Get_Aug_Token_Const
-     (Data  : in Parse_Data_Type;
-      Tree  : in WisiToken.Syntax_Trees.Tree'Class;
-      Token : in WisiToken.Token_Index)
-     return Aug_Token_Const_Ref;
-
-   function Get_Aug_Token_Var
-     (Tree       : in WisiToken.Syntax_Trees.Tree'Class;
-      Tree_Index : in WisiToken.Valid_Node_Index)
-     return Aug_Token_Var_Ref;
-
-   function Get_Aug_Token_Var
-     (Data  : in Parse_Data_Type;
-      Tree  : in WisiToken.Syntax_Trees.Tree'Class;
-      Token : in WisiToken.Token_Index)
-     return Aug_Token_Var_Ref;
-
-   --  function Get_First_Terminal
-   --    (Data  : in Parse_Data_Type;
-   --     Tree  : in WisiToken.Syntax_Trees.Tree'Class;
-   --     Token : in WisiToken.Token_Index)
-   --    return Aug_Token_Const_Ref;
-   --  Return Augmented for first Token.Inserted_Before, or if that is
-   --  empty, for Token.
-
-   function Get_Text
-     (Data       : in Parse_Data_Type;
-      Tree       : in WisiToken.Syntax_Trees.Tree;
-      Tree_Index : in WisiToken.Valid_Node_Index)
-     return String;
-   --  Return text contained by Tree_Index token in source file
-   --  (lexer.buffer).
-
-   function Elisp_Escape_Quotes (Item : in String) return String;
-   --  Prefix any '"' in Item with '\' for elisp.
-
-   function Indent_Anchored_2
-     (Data        : in out Parse_Data_Type;
-      Anchor_Line : in     WisiToken.Line_Number_Type;
-      Last_Line   : in     WisiToken.Line_Number_Type;
-      Offset      : in     Integer;
-      Accumulate  : in     Boolean)
-     return Delta_Type;
-
-   function Indent_Compute_Delta
-     (Data              : in out Parse_Data_Type'Class;
-      Tree              : in     WisiToken.Syntax_Trees.Tree;
-      Tokens            : in     WisiToken.Valid_Node_Index_Array;
-      Param             : in     Indent_Param;
-      Tree_Indenting    : in     WisiToken.Valid_Node_Index;
-      Indenting_Comment : in     Boolean)
-     return Delta_Type;
-
-   procedure Indent_Token_1
-     (Data              : in out Parse_Data_Type;
-      Tree              : in     WisiToken.Syntax_Trees.Tree;
-      Indenting_Token   : in     Augmented_Token'Class;
-      Delta_Indent      : in     Delta_Type;
-      Indenting_Comment : in     Boolean);
-   --  Sets Data.Indents, so caller may not be in a renames for a
-   --  Data.Indents element.
-
-   --  Visible for language-specific children. Must match list in
-   --  [3] wisi-process-parse--execute.
-   Navigate_Cache_Code  : constant String := "1";
-   Face_Property_Code   : constant String := "2";
-   Indent_Code          : constant String := "3";
-   Lexer_Error_Code     : constant String := "4";
-   Parser_Error_Code    : constant String := "5";
-   Check_Error_Code     : constant String := "6";
-   Recover_Code         : constant String := "7 ";
-   End_Code             : constant String := "8";
-   Name_Property_Code   : constant String := "9";
-   Edit_Action_Code     : constant String := "10";
-   Language_Action_Code : constant String := "11 ";
-
-end Wisi;
diff --git a/packages/wisi/wisi.el b/packages/wisi/wisi.el
deleted file mode 100644
index a7b88ff..0000000
--- a/packages/wisi/wisi.el
+++ /dev/null
@@ -1,1725 +0,0 @@
-;;; wisi.el --- Utilities for implementing an indentation/navigation engine 
using a generalized LALR parser -*- lexical-binding:t -*-
-;;
-;; Copyright (C) 2012 - 2020  Free Software Foundation, Inc.
-;;
-;; Author: Stephen Leake <stephen_leake@stephe-leake.org>
-;; Maintainer: Stephen Leake <stephen_leake@stephe-leake.org>
-;; Keywords: parser
-;;  indentation
-;;  navigation
-;; Version: 3.1.3
-;; package-requires: ((emacs "25.0") (seq "2.20"))
-;; URL: http://stephe-leake.org/ada/wisitoken.html
-;;
-;; This file is part of GNU Emacs.
-;;
-;; GNU Emacs 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 3 of the License, or
-;; (at your option) any later version.
-;;
-;; GNU Emacs 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 GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.
-;;
-
-;;; Commentary:
-
-;;;; History: see NEWS-wisi.text
-;;
-;;;; Design:
-;;
-;; 'wisi' was originally short for "wisent indentation engine", but
-;; now is just a name. wisi was developed to support Emacs ada-mode
-;; 5.0 indentation, font-lock, and navigation, which are parser based.
-;;
-;; The approach to indenting a given token is to parse the buffer,
-;; computing a delta indent at each parse action.
-;;
-;; The parser actions also cache face and navigation information
-;; as text properties on tokens in statements.
-;;
-;; The three reasons to run the parser (indent, face, navigate) occur
-;; at different times (user indent, font-lock, user navigate), so only
-;; the relevant parser actions are run.
-;;
-;; Parsing can be noticeably slow in large files, so sometimes we do a
-;; partial parse, and keep a list of parsed regions.
-;;
-;; Since we have a cache (the text properties), we need to consider
-;; when to invalidate it.  Ideally, we invalidate only when a change
-;; to the buffer would change the result of a parse that crosses that
-;; change, or starts after that change.  Changes in whitespace
-;; (indentation and newlines) do not affect an Ada parse.  Other
-;; languages are sensitive to newlines (Bash for example) or
-;; indentation (Python).  Adding comments does not change a parse,
-;; unless code is commented out.
-;;
-;; For navigate, we expect fully accurate results, and can tolerate
-;; one initial delay, so we always parse the entire file.
-;;
-;; For font-lock, we only parse the portion of the file requested by
-;; font-lock, so we keep a list of regions, and edit that list when
-;; the buffer is changed..
-;;
-;; For indenting, we expect fast results, and can tolerate some
-;; inaccuracy until the editing is done, so we allow partial parse. We
-;; cache the indent for each line in a text property on the newline
-;; char preceding the line. `wisi-indent-region' sets the cache on all
-;; the lines computed (part of the buffer in large files), but
-;; performs the indent only on the lines in the indent
-;; region. Subsequent calls to `wisi-indent-region' apply the cached
-;; indents. Non-whitespace edits to the buffer invalidate the indent
-;; caches in the edited region and after. Since we can do partial
-;; parse, we keep a list of parsed regions.
-;;
-;; See `wisi--post-change' for the details of what we check for
-;; invalidating.
-;;
-;;;; Choice of grammar compiler and parser
-;;
-;; There are two other parsing engines available in Emacs:
-;;
-;; - SMIE
-;;
-;;   We don't use this because it is designed to parse small snippets
-;;   of code. For Ada indentation, we always need to parse the entire
-;;   buffer.
-;;
-;; - semantic
-;;
-;;   The Ada grammar as given in the Ada language reference manual is
-;;   not LALR(1). So we use a generalized parser. In addition, the
-;;   semantic lexer is more complex, and gives different information
-;;   than we need. Finally, the semantic parser does not support error
-;;   correction, and thus fails in most editing situations.
-;;
-;; We use the WisiToken tool wisi-bnf-generate to compile BNF or EBNF
-;; to Ada source, See ada-mode.info and wisi.info for more information
-;; on the developer tools used for ada-mode and wisi.
-;;
-;;; Code:
-
-(require 'cl-lib)
-(require 'compile)
-(require 'seq)
-(require 'semantic/lex)
-(require 'wisi-parse-common)
-(require 'wisi-fringe)
-(require 'xref)
-
-(defcustom wisi-size-threshold most-positive-fixnum
-  "Max size (in characters) for using wisi parser results for anything."
-  :type 'integer
-  :group 'wisi
-  :safe 'integerp)
-(make-variable-buffer-local 'wisi-size-threshold)
-
-(defcustom wisi-indent-context-lines 0
-  "Minimum number of lines before point to include in a parse for indent.
-Increasing this will give better results when in the middle of a
-deeply nested statement, but worse in some situations."
-  :type 'integer
-  :group 'wisi
-  :safe 'integerp)
-
-(defcustom wisi-disable-face nil
-  "When non-nil, `wisi-setup' does not enable use of parser for font-lock.
-Useful when debugging parser or parser actions."
-  :type 'boolean
-  :group 'wisi
-  :safe 'booleanp)
-
-(defconst wisi-error-buffer-name "*wisi syntax errors*"
-  "Name of buffer for displaying syntax errors.")
-
-(defvar wisi-error-buffer nil
-  "Buffer for displaying syntax errors.")
-
-(defvar wisi-inhibit-parse nil
-  "When non-nil, don't run the parser.
-Language code can set this non-nil when syntax is known to be
-invalid temporarily, or when making lots of changes.")
-
-(defun wisi-safe-marker-pos (pos)
-  "Return an integer buffer position from POS, an integer or marker"
-  (cond
-   ((markerp pos)
-    (marker-position pos))
-
-   (t pos)))
-
-;;;; misc
-
-(defun wisi-in-paren-p (&optional parse-result)
-  "Return t if point is inside a pair of parentheses.
-If PARSE-RESULT is non-nil, use it instead of calling `syntax-ppss'."
-  (> (nth 0 (or parse-result (syntax-ppss))) 0))
-
-(defun wisi-pos-in-paren-p (pos)
-  "Return t if POS is inside a pair of parentheses."
-  (save-excursion
-    (> (nth 0 (syntax-ppss pos)) 0)))
-
-(defun wisi-same-paren-depth-p (pos1 pos2)
-  "Return t if POS1 is at same parentheses depth as POS2."
-  (= (nth 0 (syntax-ppss pos1)) (nth 0 (syntax-ppss pos2))))
-
-(defun wisi-goto-open-paren (&optional offset parse-result)
-  "Move point to innermost opening paren surrounding current point, plus 
OFFSET.
-Throw error if not in paren.  If PARSE-RESULT is non-nil, use it
-instead of calling `syntax-ppss'."
-  (goto-char (+ (or offset 0) (nth 1 (or parse-result (syntax-ppss))))))
-
-(defun wisi-in-comment-p (&optional parse-result)
-  "Return t if inside a comment.
-If PARSE-RESULT is non-nil, use it instead of calling `syntax-ppss'."
-  (nth 4 (or parse-result (syntax-ppss))))
-
-(defun wisi-in-string-p (&optional parse-result)
-  "Return t if point is inside a string.
-If PARSE-RESULT is non-nil, use it instead of calling `syntax-ppss'."
-  (nth 3 (or parse-result (syntax-ppss))))
-
-(defun wisi-in-string-or-comment-p (&optional parse-result)
-  "Return t if inside a comment or string.
-If PARSE-RESULT is non-nil, use it instead of calling `syntax-ppss'."
-  (setq parse-result (or parse-result (syntax-ppss)))
-  (or (wisi-in-string-p parse-result) (wisi-in-comment-p parse-result)))
-
-(defun wisi-indent-newline-indent ()
-  "insert a newline, indent the old and new lines."
-  (interactive "*")
-  ;; point may be in the middle of a word, so insert newline first,
-  ;; then go back and indent.
-  (insert "\n")
-  (forward-char -1)
-  (funcall indent-line-function)
-  (forward-char 1)
-  (funcall indent-line-function))
-
-;;;; token info cache
-
-(defvar-local wisi-parse-failed nil
-  "Non-nil when last parse failed - cleared when parse succeeds.")
-
-(defvar-local wisi--parse-try
-  (list
-   (cons 'face t)
-   (cons 'navigate t)
-   (cons 'indent t))
-  "Non-nil when parse is needed because text has changed - cleared when parse 
succeeds.")
-
-(defun wisi-parse-try (&optional parse-action)
-  (cdr (assoc (or parse-action wisi--parse-action) wisi--parse-try)))
-
-(defun wisi-set-parse-try (value &optional parse-action)
-  (setcdr (assoc (or parse-action wisi--parse-action) wisi--parse-try) value))
-
-(defvar-local wisi--last-parse-region
-  (list
-   (cons 'face nil)
-   (cons 'navigate nil)
-   (cons 'indent nil))
-  "Last region on which parse was requested.")
-
-(defun wisi-last-parse-region (&optional parse-action)
-  (cdr (assoc (or parse-action wisi--parse-action) wisi--last-parse-region)))
-
-(defun wisi-set-last-parse-region (begin end parse-action)
-  (setcdr (assoc parse-action wisi--last-parse-region) (cons begin end)))
-
-(defvar-local wisi--cached-regions
-  (list
-   (cons 'face nil)
-   (cons 'navigate nil)
-   (cons 'indent nil))
-  "Alist of lists of regions in buffer where parser text properties are valid.
-Regions in a list are in random order.")
-
-(defun wisi--contained-region (begin end region)
-  "Non-nil if BEGIN and END (buffer positions) are both contained in REGION (a 
cons of positions)."
-  ;; We assume begin < end
-  (and (<= (car region) begin)
-       (<= end (cdr region))))
-
-(defun wisi--contained-pos (pos region)
-  "Non-nil if POS (a buffer position) is contained in REGION (a cons of 
positions)."
-  (and (<= (car region) pos)
-       (<= pos (cdr region))))
-
-(defun wisi-cache-covers-region (begin end &optional parse-action)
-  "Non-nil if BEGIN END is contained in a parsed region."
-  (let ((region-list (cdr (assoc (or parse-action wisi--parse-action) 
wisi--cached-regions)))
-       region)
-    (while (and region-list
-               (marker-buffer (caar region-list)) ;; this can fail after 
editing during ediff-regions.
-               (marker-buffer (cdar region-list))
-               (not (wisi--contained-region begin end (car region-list))))
-      (pop region-list))
-
-    (when region-list
-      ;; return a nice value for verbosity in wisi-validate-cache
-      (setq region (car region-list))
-      (cons (marker-position (car region)) (marker-position (cdr region))))))
-
-(defun wisi-cache-covers-pos (parse-action pos)
-  "Non-nil if POS is contained in a PARSE-ACTION parsed region."
-  (let ((region-list (cdr (assoc parse-action wisi--cached-regions))))
-    (while (and region-list
-               (not (wisi--contained-pos pos (car region-list))))
-      (pop region-list))
-
-    (when region-list
-      t)))
-
-(defun wisi-cache-contains-pos (parse-action pos)
-  "Non-nil if POS is at or before the end of any PARSE-ACTION parsed region."
-  (let ((region-list (cdr (assoc parse-action wisi--cached-regions)))
-       result)
-    (while (and (not result) region-list)
-      (when (<= pos (cdr (car region-list)))
-       (setq result t))
-      (pop region-list))
-
-    result))
-
-(defun wisi-cache-set-region (region)
-  "Set the cached region list for `wisi--parse-action' to REGION."
-  (setcdr (assoc wisi--parse-action wisi--cached-regions)
-         (list (cons (copy-marker (car region))
-                     (copy-marker (cdr region))))))
-
-(defun wisi-cache-add-region (region)
-  "Add REGION to the cached region list for `wisi--parse-action'."
-  (push (cons (copy-marker (car region))
-             (copy-marker (cdr region)))
-       (cdr (assoc wisi--parse-action wisi--cached-regions))))
-
-(defun wisi-cache-delete-regions-after (parse-action pos)
-  "Delete any PARSE-ACTION parsed region at or after POS.
-Truncate any region that overlaps POS."
-  (let ((region-list (cdr (assoc parse-action wisi--cached-regions)))
-       result)
-    (while (and (not result) region-list)
-      (cond
-       ((and (> pos (car (car region-list)))
-            (<= pos (cdr (car region-list))))
-       ;; region contains POS; keep truncated
-       (push (cons (car (car region-list)) (copy-marker pos)) result))
-
-       ((> pos (car (car region-list)))
-       ;; region is entirely before POS; keep
-       (push (car region-list) result))
-
-       ;; else region is entirely after POS; delete
-       )
-
-      (pop region-list))
-    (setcdr (assoc parse-action wisi--cached-regions) result)
-    ))
-
-(defun wisi--delete-face-cache (after)
-  (with-silent-modifications
-    (remove-text-properties after (point-max) '(font-lock-face nil)))
-  (if (= after (point-min))
-      (setcdr (assoc 'face wisi--cached-regions) nil)
-    (wisi-cache-delete-regions-after 'face after)))
-
-(defun wisi--delete-navigate-cache (after)
-  (with-silent-modifications
-    ;; This text property is 'wisi-cache', not 'wisi-navigate', for
-    ;; historical reasons.
-    (remove-text-properties after (point-max) '(wisi-cache nil wisi-name nil)))
-  (if (= after (point-min))
-      (setcdr (assoc 'navigate wisi--cached-regions) nil)
-    (wisi-cache-delete-regions-after 'navigate after)))
-
-(defun wisi--delete-indent-cache (after)
-  (with-silent-modifications
-    (remove-text-properties after (point-max) '(wisi-indent nil)))
-  (if (= after (point-min))
-      (setcdr (assoc 'indent wisi--cached-regions) nil)
-    (wisi-cache-delete-regions-after 'indent after)))
-
-(defun wisi-invalidate-cache (action after)
-  "Invalidate ACTION caches for the current buffer from AFTER to end of 
buffer."
-  (cond
-   ((= after (point-min))
-    (cond
-     ((eq 'face action)
-      (wisi--delete-face-cache after))
-
-     ((eq 'navigate action)
-      (wisi--delete-navigate-cache after))
-
-     ((eq 'indent action)
-      (wisi--delete-indent-cache after))
-     ))
-
-   ((wisi-cache-contains-pos action after)
-    (when (> wisi-debug 0) (message "wisi-invalidate-cache %s:%s:%d" action 
(current-buffer) after))
-    (cond
-     ((eq 'face action)
-      (wisi--delete-face-cache after))
-
-     ((eq 'navigate action)
-      (when (wisi-cache-covers-pos 'navigate after)
-       ;; We goto statement start to ensure that motion within nested
-       ;; structures is properly done (ie prev/next on ’elsif’ is not
-       ;; set by wisi-motion-action if already set by a lower level
-       ;; statement). We don’t do it for ’face or ’indent, because that
-       ;; might require a parse, and they don’t care about nested
-       ;; structures.
-       (save-excursion
-         (goto-char after)
-
-         ;; This is copied from ‘wisi-goto-statement-start’; we can’t
-         ;; call that because it would call ‘wisi-validate-cache’,
-         ;; which would call ‘wisi-invalidate-cache’; infinite loop.
-         ;; If this needed a navigate parse to succeed, we would not
-         ;; get here.
-         (let ((cache (or (wisi-get-cache (point))
-                          (wisi-backward-cache))))
-           (cond
-            ((null cache)
-             ;; at bob
-             nil)
-
-            ((eq 'statement-end (wisi-cache-class cache))
-             ;; If the change did affect part of a structure statement,
-             ;; this is a lower level statement. Otherwise, we are
-             ;; invalidating more than necessary; not a problem.
-             (wisi-goto-start cache)
-             (setq cache (wisi-backward-cache))
-             (when cache ;; else bob
-               (wisi-goto-start cache)))
-
-            (t
-             (wisi-goto-start cache))
-            ))
-
-         (setq after (point))))
-      (wisi--delete-navigate-cache after))
-
-     ((eq 'indent action)
-      ;; The indent cache is stored on newline before line being
-      ;; indented. We delete that, because changing text on a line can
-      ;; change the indent of that line.
-      (setq after
-           (save-excursion
-             (goto-char after)
-             (line-beginning-position)))
-      (wisi--delete-indent-cache (max 1 (1- after))))
-     )
-    )))
-
-(defun wisi-reset-parser ()
-  "Force a parse."
-  (interactive)
-  (syntax-ppss-flush-cache (point-min)) ;; necessary after edit during 
ediff-regions
-  (setq wisi--cached-regions ;; necessary instead of wisi-invalidate after 
ediff-regions
-       (list
-        (cons 'face nil)
-        (cons 'navigate nil)
-        (cons 'indent nil)))
-  (wisi-set-parse-try t 'indent)
-  (wisi-set-parse-try t 'face)
-  (wisi-set-parse-try t 'navigate)
-  (wisi-set-last-parse-region (point-min) (point-min) 'indent)
-  (wisi-set-last-parse-region (point-min) (point-min) 'face)
-  (wisi-set-last-parse-region (point-min) (point-min) 'navigate)
-  (wisi-fringe-clean))
-
-;; wisi--change-* keep track of buffer modifications.
-;; If wisi--change-end comes before wisi--change-beg, it means there were
-;; no modifications.
-(defvar-local wisi--change-beg most-positive-fixnum
-  "First position where a change may have taken place.")
-
-(defvar-local wisi--change-end nil
-  "Marker pointing to the last position where a change may have taken place.")
-
-(defvar-local wisi--deleted-syntax nil
-  "Worst syntax class of characters deleted in changes.
-One of:
-nil - no deletions since reset
-0   - only whitespace or comment deleted
-2   - some other syntax deleted
-
-Set by `wisi-before-change', used and reset by `wisi--post-change'.")
-
-(defvar-local wisi-indenting-p nil
-  "Non-nil when `wisi-indent-region' is actively indenting.
-Used to ignore whitespace changes in before/after change hooks.")
-
-(defvar-local wisi--last-parse-action nil
-  "Value of `wisi--parse-action' when `wisi-validate-cache' was last run.")
-
-(defun wisi-before-change (begin end)
-  "For `before-change-functions'."
-  ;; begin . (1- end) is range of text being deleted
-  (unless wisi-indenting-p
-    ;; We set wisi--change-beg, -end even if only inserting, so we
-    ;; don't have to do it again in wisi-after-change.
-    (setq wisi--change-beg (min wisi--change-beg begin))
-
-    ;; `buffer-base-buffer' deals with edits in indirect buffers
-    ;; created by ediff-regions-*
-
-    (cond
-     ((null wisi--change-end)
-      (setq wisi--change-end (make-marker))
-      (set-marker wisi--change-end end (or (buffer-base-buffer) 
(current-buffer))))
-
-     ((> end wisi--change-end)
-      (set-marker wisi--change-end end (or (buffer-base-buffer) 
(current-buffer))))
-     )
-
-    (unless (= begin end)
-      (cond
-       ((or (null wisi--deleted-syntax)
-           (= 0 wisi--deleted-syntax))
-       (save-excursion
-         (if (or (nth 4 (syntax-ppss begin)) ; in comment, moves point to begin
-                 (= end (skip-syntax-forward " " end)));; whitespace
-             (setq wisi--deleted-syntax 0)
-           (setq wisi--deleted-syntax 2))))
-
-       (t
-       ;; wisi--deleted-syntax is 2; no change.
-       )
-       ))))
-
-(defun wisi-after-change (begin end _length)
-  "For `after-change-functions'"
-  ;; begin . end is range of text being inserted (empty if equal);
-  ;; length is the size of the deleted text.
-
-  ;; Remove caches on inserted text, which could have caches from
-  ;; anywhere, and are in any case invalid.
-
-  ;; If the insertion changes a word that has wisi fontification,
-  ;; remove fontification from the entire word, so it is all
-  ;; refontified consistently.
-
-  (let (word-begin word-end)
-    (save-excursion
-      (goto-char end)
-      (skip-syntax-forward "w_")
-      (setq word-end (point))
-      (goto-char begin)
-      (skip-syntax-backward "w_")
-      (setq word-begin (point)))
-    (if (get-text-property word-begin 'font-lock-face)
-       (with-silent-modifications
-         (remove-text-properties
-          word-begin word-end
-          '(font-lock-face nil wisi-cache nil wisi-indent nil fontified nil)))
-
-      ;; No point in removing
-      ;; 'fontified here; that's already handled by jit-lock.
-      (with-silent-modifications
-       (remove-text-properties
-        begin end
-        '(font-lock-face nil wisi-cache nil wisi-indent nil))))
-    ))
-
-(defun wisi--post-change (begin end)
-  "Update wisi text properties for changes in region BEG END."
-  ;; (syntax-ppss-flush-cache begin) is in before-change-functions
-
-  (save-excursion
-    (let ((need-invalidate t)
-         (done nil)
-         ;; non-nil if require a parse because the syntax may have
-         ;; changed.
-
-         (begin-state (syntax-ppss begin))
-         (end-state (syntax-ppss end)))
-         ;; (info "(elisp)Parser State")
-         ;; syntax-ppss has moved point to "end"; might be eob.
-
-      ;; consider deletion
-      (cond
-       ((null wisi--deleted-syntax)
-       ;; no deletions
-       )
-
-       ((= 0 wisi--deleted-syntax)
-       ;; Only deleted whitespace; may have joined two words
-       (when
-           (and (= begin end) ;; no insertions
-                (or
-                 (= (point-min) begin)
-                 (= 0 (syntax-class (syntax-after (1- begin))))
-                 (= (point-max) end)
-                 (= 0 (syntax-class (syntax-after end)))))
-         ;; More whitespace on at least one side of deletion; did not
-         ;; join two words.
-         (setq need-invalidate nil)
-         (setq done t)
-         ))
-
-       (t
-       ;; wisi--deleted-syntax is 2; need invalidate and parse for all
-       ;; parse actions
-       (setq done t)
-       ))
-
-      (setq wisi--deleted-syntax nil)
-
-      (unless done
-       ;; consider insertion
-       (cond
-        ((= begin end)
-         ;; no insertions
-         nil)
-
-        ((and
-          (nth 3 begin-state);; in string
-          (nth 3 end-state)
-          (= (nth 8 begin-state) (nth 8 end-state)));; no intervening 
non-string
-         (setq need-invalidate nil))
-
-        ((and
-          (nth 4 begin-state) ;; in comment
-          (nth 4 end-state)
-          (= (nth 8 begin-state) (nth 8 end-state))) ;; no intervening 
non-comment
-
-         (if (and
-              (= 11 (car (syntax-after begin)))
-              (progn (goto-char begin)
-                     (skip-syntax-backward "<")
-                     (not (= (point) begin))))
-
-             ;; Either inserted last char of a multi-char comment
-             ;; start, or inserted extra comment-start chars.
-             (setq need-invalidate begin)
-           (setq need-invalidate nil)))
-
-        ((and
-          (or
-           (= (point-min) begin)
-           (= 0 (syntax-class (syntax-after (1- begin)))); whitespace
-           (= (point-max) end)
-           (= 0 (syntax-class (syntax-after end))))
-          (progn
-            (goto-char begin)
-            (= (- end begin) (skip-syntax-forward " " end))
-            ))
-         ;; Inserted only whitespace, there is more whitespace on at
-         ;; least one side, and we are not in a comment or string
-         ;; (checked above).  This may affect indentation, but not
-         ;; the indentation cache.
-         (setq need-invalidate nil))
-        ))
-
-      (when need-invalidate
-       (wisi-set-parse-try t 'face)
-       (wisi-set-parse-try t 'navigate)
-       (wisi-set-parse-try t 'indent)
-
-       (wisi-invalidate-cache 'face begin)
-       (wisi-invalidate-cache 'navigate begin)
-       (wisi-invalidate-cache 'indent begin))
-      )))
-
-(defun wisi-goto-error ()
-  "Move point to position in last error message (if any)."
-  (cond
-   ((wisi-parser-parse-errors wisi--parser)
-    (let ((data (car (wisi-parser-parse-errors wisi--parser))))
-      (cond
-       ((wisi--parse-error-pos data)
-       (push-mark)
-       (goto-char (wisi--parse-error-pos data)))
-
-       ((string-match ":\\([0-9]+\\):\\([0-9]+\\):" (wisi--parse-error-message 
data))
-       (let* ((msg (wisi--parse-error-message data))
-              (line (string-to-number (match-string 1 msg)))
-              (col (string-to-number (match-string 2 msg))))
-         (push-mark)
-         (goto-char (point-min))
-         (condition-case nil
-             (progn
-               ;; line can be wrong if parser screws up, or user edits buffer
-               (forward-line (1- line))
-               (forward-char col))
-           (error
-            ;; just stay at eob.
-            nil))))
-       )))
-   ((wisi-parser-lexer-errors wisi--parser)
-    (push-mark)
-    (goto-char (wisi--lexer-error-pos (car (wisi-parser-lexer-errors 
wisi--parser)))))
-   ))
-
-(defun wisi-show-parse-error ()
-  "Show current wisi-parse errors."
-  (interactive)
-  (cond
-   ((or (wisi-parser-lexer-errors wisi--parser)
-       (wisi-parser-parse-errors wisi--parser))
-    (if (and (= 1 (+ (length (wisi-parser-lexer-errors wisi--parser))
-                    (length (wisi-parser-parse-errors wisi--parser))))
-            (or (and (wisi-parser-parse-errors wisi--parser)
-                     (not (wisi--parse-error-repair (car 
(wisi-parser-parse-errors wisi--parser)))))
-                (and (wisi-parser-lexer-errors wisi--parser)
-                     (not (wisi--lexer-error-inserted (car 
(wisi-parser-lexer-errors wisi--parser)))))))
-       ;; There is exactly one error; if there is error correction
-       ;; information, use a ’compilation’ buffer, so
-       ;; *-fix-compiler-error will call
-       ;; wisi-repair-error. Otherwise, just position cursor at
-       ;; error.
-       (progn
-         (wisi-goto-error)
-         (message (or (and (wisi-parser-parse-errors wisi--parser)
-                           (wisi--parse-error-message (car 
(wisi-parser-parse-errors wisi--parser))))
-                      (and (wisi-parser-lexer-errors wisi--parser)
-                           (wisi--lexer-error-message (car 
(wisi-parser-lexer-errors wisi--parser)))))
-                  ))
-
-      ;; else show all errors in a ’compilation’ buffer
-      (setq wisi-error-buffer (get-buffer-create wisi-error-buffer-name))
-
-      (let ((lexer-errs (sort (cl-copy-seq (wisi-parser-lexer-errors 
wisi--parser))
-                             (lambda (a b) (< (wisi--parse-error-pos a) 
(wisi--parse-error-pos b)))))
-           (parse-errs (sort (cl-copy-seq (wisi-parser-parse-errors 
wisi--parser))
-                             (lambda (a b) (< (wisi--parse-error-pos a) 
(wisi--parse-error-pos b)))))
-           (dir default-directory))
-       (with-current-buffer wisi-error-buffer
-         (setq window-size-fixed nil)
-         (compilation-mode)
-         (setq-local compilation-search-path (list dir))
-         (setq default-directory dir)
-         (setq next-error-last-buffer (current-buffer))
-         (setq buffer-read-only nil)
-         (erase-buffer)
-         ;; compilation-nex-error-function assumes there is not an
-         ;; error at point-min, so we need a comment.
-         (insert "wisi syntax errors")
-         (newline)
-         (dolist (err lexer-errs)
-           (insert (wisi--lexer-error-message err))
-           (put-text-property (line-beginning-position) (1+ 
(line-beginning-position)) 'wisi-error-data err)
-           (newline 2))
-         (dolist (err parse-errs)
-           (insert (wisi--parse-error-message err))
-           (put-text-property (line-beginning-position) (1+ 
(line-beginning-position)) 'wisi-error-data err)
-           (newline 2))
-         (compilation--flush-parse (point-min) (point-max))
-         (compilation--ensure-parse (point-max))
-         (when compilation-filter-hook
-           (let ((compilation-filter-start (point-min)))
-             (run-hooks 'compilation-filter-hook)))
-
-         (setq buffer-read-only t)
-         (goto-char (point-min)))
-
-       (let ((win (display-buffer
-                   wisi-error-buffer
-                   (cons #'display-buffer-at-bottom
-                         (list (cons 'window-height 
#'shrink-window-if-larger-than-buffer))))))
-         (set-window-dedicated-p win t))
-
-       (with-current-buffer wisi-error-buffer
-         (setq window-size-fixed t))
-       (next-error))
-      ))
-
-   ((wisi-parse-try wisi--last-parse-action)
-    (message "need parse"))
-
-   (t
-    (message "parse succeeded"))
-   ))
-
-(defun wisi-kill-parser ()
-  "Kill the background process running the parser for the current buffer.
-Usefull if the parser appears to be hung."
-  (interactive)
-  (wisi-parse-kill wisi--parser)
-  ;; also force re-parse
-  (wisi-reset-parser)
-  )
-
-(defun wisi-partial-parse-p (begin end)
-  (and (wisi-process--parser-p wisi--parser)
-       (not (and (= begin (point-min))
-                (= end (point-max))))
-       (>= (point-max) wisi-partial-parse-threshold)))
-
-(defun wisi--run-parse (begin parse-end)
-  "Run the parser, on at least region BEGIN PARSE-END."
-  (unless (or (buffer-narrowed-p)
-             (= (point-min) (point-max))) ;; some parsers can’t handle an 
empty buffer.
-    (let* ((partial-parse-p (wisi-partial-parse-p begin parse-end))
-          (msg (when (> wisi-debug 0)
-                 (format "wisi: %sparsing %s %s:%d %d %d ..."
-                         (if partial-parse-p "partial " "")
-                         wisi--parse-action
-                         (buffer-name)
-                         begin
-                         (if (markerp parse-end) (marker-position parse-end) 
parse-end)
-                         (line-number-at-pos begin))))
-          (parsed-region nil))
-
-      (when msg
-       (message msg))
-
-      (setq wisi--last-parse-action wisi--parse-action)
-      (wisi-set-last-parse-region begin parse-end wisi--parse-action)
-
-      (unless (eq wisi--parse-action 'face)
-       (when (buffer-live-p wisi-error-buffer)
-         (with-current-buffer wisi-error-buffer
-           (setq buffer-read-only nil)
-           (erase-buffer)
-           (setq buffer-read-only t)
-           (when (get-buffer-window wisi-error-buffer)
-             (delete-window (get-buffer-window wisi-error-buffer))))))
-
-      (condition-case-unless-debug err
-         (save-excursion
-           (if partial-parse-p
-             (let ((send-region (wisi-parse-expand-region wisi--parser begin 
parse-end)))
-               (setq parsed-region (wisi-parse-current wisi--parser (car 
send-region) (cdr send-region) parse-end))
-               (wisi-cache-add-region parsed-region))
-
-             ;; parse full buffer
-             (setq parsed-region (cons (point-min) (point-max)))
-             (wisi-cache-set-region (wisi-parse-current wisi--parser 
(point-min) (point-max) (point-max))))
-
-           (when (> wisi-debug 0) (message "... parsed %s" parsed-region))
-           (setq wisi-parse-failed nil))
-       (wisi-parse-error
-        (cl-ecase wisi--parse-action
-          (face
-           ;; Caches set by failed elisp parse are ok, but some parse
-           ;; failures return 'nil' in parse-region.
-           (when (cdr parsed-region)
-             (wisi--delete-face-cache (cdr parsed-region))))
-
-          (navigate
-           ;; elisp parse partially resets caches
-           (wisi--delete-navigate-cache (point-min)))
-
-          (indent
-           ;; parse does not set caches; see `wisi-indent-region'
-           nil))
-        (setq wisi-parse-failed t)
-        ;; parser should have stored this error message in parser-error-msgs
-        (when (> wisi-debug 0)
-          (signal (car err) (cdr err)))
-        )
-       (error
-        ;; parser failed for other reason
-        (setq wisi-parse-failed t)
-        (signal (car err) (cdr err)))
-       )
-
-      (unless partial-parse-p
-       (wisi-fringe-display-errors
-        (append
-         (seq-map (lambda (err) (wisi--lexer-error-pos err)) 
(wisi-parser-lexer-errors wisi--parser))
-         (seq-map (lambda (err) (wisi--parse-error-pos err)) 
(wisi-parser-parse-errors wisi--parser)))))
-
-      (when (> wisi-debug 1)
-       (if (or (wisi-parser-lexer-errors wisi--parser)
-               (wisi-parser-parse-errors wisi--parser))
-           (progn
-             (message "%s error" msg)
-             (wisi-goto-error)
-             (error (or (and (wisi-parser-lexer-errors wisi--parser)
-                             (wisi--lexer-error-message (car 
(wisi-parser-lexer-errors wisi--parser))))
-                        (and (wisi-parser-parse-errors wisi--parser)
-                             (wisi--parse-error-message (car 
(wisi-parser-parse-errors wisi--parser))))
-                        )))
-
-         ;; no error
-         (message "%s done" msg))
-       ))))
-
-(defun wisi--check-change ()
-  "Process `wisi--change-beg', `wisi--change-end'.
-`wisi--parse-action' must be bound."
-  (when (and wisi--change-beg
-            wisi--change-end
-            (or (integerp wisi--change-beg)
-                (marker-buffer wisi--change-beg)) ;; this can fail after 
editing during ediff-regions.
-            (or (integerp wisi--change-end)
-                (marker-buffer wisi--change-end))
-            (<= wisi--change-beg wisi--change-end))
-    (wisi--post-change wisi--change-beg (marker-position wisi--change-end))
-    (setq wisi--change-beg most-positive-fixnum)
-    (move-marker wisi--change-end (point-min))
-    ))
-
-(defun wisi-validate-cache (begin end error-on-fail parse-action)
-  "Ensure cached data for PARSE-ACTION is valid in region BEGIN END in current 
buffer."
-  (if (and (not wisi-inhibit-parse)
-          (< (point-max) wisi-size-threshold))
-      (let ((wisi--parse-action parse-action))
-       (wisi--check-change)
-
-       ;; Now we can rely on wisi-cache-covers-region.
-       ;;
-       ;; If the last parse failed but was partial, and we are trying
-       ;; a different region, it may succeed. Otherwise, don't keep
-       ;; retrying a failed parse until the text changes again.
-       (cond
-        ((and (not wisi-parse-failed)
-              (wisi-cache-covers-region begin end))
-         (when (> wisi-debug 0)
-           (message "parse %s skipped: cache-covers-region %s %s.%s"
-                    parse-action
-                    (wisi-cache-covers-region begin end)
-                    begin end)))
-
-        ((and wisi-parse-failed
-              (equal (cons begin end) (wisi-last-parse-region parse-action))
-              (not (wisi-parse-try parse-action)))
-         (when (> wisi-debug 0)
-           (message "parse %s skipped: parse-failed" parse-action)))
-
-        (t
-         (progn
-           (wisi-set-parse-try nil)
-           (wisi--run-parse begin end))))
-
-       ;; We want this error even if we did not try to parse; it means
-       ;; the parse results are not valid.
-       (when (and error-on-fail wisi-parse-failed)
-         (error "parse %s failed" parse-action))
-       )
-    (when (> wisi-debug 0)
-      (message "parse %s skipped inihibit-parse %s wisi-size-threshold %d"
-              parse-action
-              wisi-inhibit-parse
-              wisi-size-threshold))))
-
-(defun wisi-fontify-region (begin end)
-  "For `jit-lock-functions'."
-  (wisi-validate-cache begin end nil 'face))
-
-(defun wisi-get-containing-cache (cache)
-  "Return cache from (wisi-cache-containing CACHE)."
-  (when cache
-    (let ((containing (wisi-cache-containing cache)))
-      (and containing
-          (wisi-get-cache containing)))))
-
-(defun wisi-cache-text (cache)
-  "Return property-less buffer substring designated by cache.
-Point must be at cache."
-  (buffer-substring-no-properties (point) (+ (point) (wisi-cache-last cache))))
-
-;;;; navigation
-
-(defun wisi-forward-find-class (class limit)
-  "Search at point or forward for a token that has a cache with CLASS.
-Return cache, or nil if at end of buffer.
-If LIMIT (a buffer position) is reached, throw an error."
-  (let ((cache (or (wisi-get-cache (point))
-                  (wisi-forward-cache))))
-    (while (not (eq class (wisi-cache-class cache)))
-      (setq cache (wisi-forward-cache))
-      (when (>= (point) limit)
-       (error "cache with class %s not found" class)))
-    cache))
-
-(defun wisi-forward-find-cache-token (ids limit)
-  "Search forward for a cache with token in IDS (a list of token ids).
-Return cache, or nil if at LIMIT or end of buffer."
-  (let ((cache (wisi-forward-cache)))
-    (while (and (< (point) limit)
-               (not (eobp))
-               (not (memq (wisi-cache-token cache) ids)))
-      (setq cache (wisi-forward-cache)))
-    cache))
-
-(defun wisi-forward-find-nonterm (nonterm limit)
-  "Search forward for a token that has a cache with NONTERM.
-NONTERM may be a list; stop on any cache that has a member of the list.
-Return cache, or nil if at end of buffer.
-If LIMIT (a buffer position) is reached, throw an error."
-  (let ((nonterm-list (cond
-                      ((listp nonterm) nonterm)
-                      (t (list nonterm))))
-       (cache (wisi-forward-cache)))
-    (while (not (memq (wisi-cache-nonterm cache) nonterm-list))
-      (setq cache (wisi-forward-cache))
-      (when (>= (point) limit)
-       (error "cache with nonterm %s not found" nonterm)))
-    cache))
-
-(defun wisi-goto-cache-next (cache)
-  (goto-char (wisi-cache-next cache))
-  (wisi-get-cache (point))
-  )
-
-(defun wisi-forward-statement-keyword ()
-  "If not at a cached token, move forward to next
-cache. Otherwise move to cache-next, or cache-end, or next cache
-if both nil.  Return cache found."
-  (unless (eobp)
-    (wisi-validate-cache (point-min) (point-max) t 'navigate)
-    (let ((cache (wisi-get-cache (point))))
-      (if (and cache
-              (not (eq (wisi-cache-class cache) 'statement-end)))
-         (let ((next (or (wisi-cache-next cache)
-                         (wisi-cache-end cache))))
-           (if next
-               (goto-char next)
-             (wisi-forward-cache)))
-       (wisi-forward-cache))
-      )
-    (wisi-get-cache (point))
-    ))
-
-(defun wisi-backward-statement-keyword ()
-  "If not at a cached token, move backward to prev
-cache. Otherwise move to cache-prev, or prev cache if nil."
-  (wisi-validate-cache (point-min) (point-max) t 'navigate)
-  (let ((cache (wisi-get-cache (point)))
-       prev)
-    (when cache
-      (setq prev (wisi-cache-prev cache))
-      (unless prev
-       (unless (eq 'statement-start (wisi-cache-class cache))
-         (setq prev (wisi-cache-containing cache)))))
-    (if prev
-       (goto-char prev)
-      (wisi-backward-cache))
-  ))
-
-(defun wisi-forward-sexp (&optional arg)
-  "For `forward-sexp-function'."
-  (interactive "^p")
-  (or arg (setq arg 1))
-  (cond
-   ((and (> arg 0) (= 4 (syntax-class (syntax-after (point)))))  ;; on open 
paren
-    (let ((forward-sexp-function nil))
-      (forward-sexp arg)))
-
-   ((and (< arg 0) (= 5 (syntax-class (syntax-after (1- (point)))))) ;; after 
close paren
-    (let ((forward-sexp-function nil))
-      (forward-sexp arg)))
-
-   ((and (> arg 0) (= 7 (syntax-class (syntax-after (point)))))  ;; on (open) 
string quote
-    (let ((forward-sexp-function nil))
-      (forward-sexp arg)))
-
-   ((and (< arg 0) (= 7 (syntax-class (syntax-after (1- (point)))))) ;; after 
(close) string quote
-    (let ((forward-sexp-function nil))
-      (forward-sexp arg)))
-
-   (t
-    (dotimes (_i (abs arg))
-      (if (> arg 0)
-         (wisi-forward-statement-keyword)
-       (wisi-backward-statement-keyword))))
-   ))
-
-(defun wisi-goto-containing (cache &optional error)
-  "Move point to containing token for CACHE, return cache at that point.
-If ERROR, throw error when CACHE has no container; else return nil."
-  (cond
-   ((and (markerp (wisi-cache-containing cache))
-
-        (not (= (wisi-cache-containing cache) (point))))
-    ;; This check is only needed if some cache points to itself as a
-    ;; container. Apparently that happend once that I caught in the
-    ;; debugger; emacs hung because we got here in the font-lock
-    ;; timer.
-
-    (goto-char (wisi-cache-containing cache))
-    (wisi-get-cache (point)))
-   (t
-    (when error
-      (error "already at outermost containing token")))
-   ))
-
-(defun wisi-goto-containing-paren (cache)
-  "Move point to just after the open-paren containing CACHE.
-Return cache for paren, or nil if no containing paren."
-  (while (and cache
-             (not (eq (wisi-cache-class cache) 'open-paren)))
-    (setq cache (wisi-goto-containing cache)))
-  (when cache
-    (forward-char 1))
-  cache)
-
-(defun wisi-goto-start (cache)
-  "Move point to containing ancestor of CACHE that has class statement-start.
-Return start cache."
-  ;; cache nil at bob, or on cache in partially parsed statement
-  (while (and cache
-             (not (eq (wisi-cache-class cache) 'statement-start)))
-    (setq cache (wisi-goto-containing cache)))
-  cache)
-
-(defun wisi-goto-end-1 (cache)
-  (goto-char (wisi-cache-end cache)))
-
-(defun wisi-goto-statement-start ()
-  "Move point to token at start of statement point is in or after.
-Return start cache."
-  (interactive)
-  (wisi-validate-cache (point-min) (point-max) t 'navigate)
-  (wisi-goto-start (or (wisi-get-cache (point))
-                      (wisi-backward-cache))))
-
-(defun wisi-goto-statement-end ()
-  "Move point to token at end of statement point is in or before."
-  (interactive)
-  (wisi-validate-cache (point-min) (point-max) t 'navigate)
-  (let ((cache (or (wisi-get-cache (point))
-                  (wisi-forward-cache))))
-    (when (wisi-cache-end cache)
-      ;; nil when cache is statement-end
-      (wisi-goto-end-1 cache))
-    ))
-
-(defun wisi-goto-containing-statement-start ()
-  "Move point to the start of the statement containing the current statement."
-  (interactive)
-  (wisi-validate-cache (point-min) (point-max) t 'navigate)
-  (let ((cache (or (wisi-get-cache (point))
-                  (wisi-backward-cache))))
-    (when cache
-      (setq cache (wisi-goto-start cache)))
-    (when cache
-      (setq cache (wisi-goto-containing cache nil)))
-    ))
-
-(defun wisi-next-statement-cache (cache)
-  "Move point to CACHE-next, return cache; error if nil."
-  (when (not (markerp (wisi-cache-next cache)))
-    (error "no next statement cache"))
-  (goto-char (wisi-cache-next cache))
-  (wisi-get-cache (point)))
-
-(defun wisi-prev-statement-cache (cache)
-  "Move point to CACHE-prev, return cache; error if nil."
-  (when (not (markerp (wisi-cache-prev cache)))
-    (error "no prev statement cache"))
-  (goto-char (wisi-cache-prev cache))
-  (wisi-get-cache (point)))
-
-;;;; indentation
-
-(defun wisi-comment-indent ()
-  "For `comment-indent-function'. Indent single line comment to
-the comment on the previous line."
-  ;; Called from `comment-indent', either to insert a new comment, or
-  ;; to indent the first line of an existing one.  In either case, the
-  ;; comment may be after code on the same line.  For an existing
-  ;; comment, point is at the start of the starting delimiter.
-  (or
-   (save-excursion
-     ;; Check for a preceding comment line; fail if comment follows code.
-     (when (forward-comment -1)
-       ;; For the case:
-       ;;
-       ;; code;-- comment
-       ;;
-       ;; point is on '--', and 'forward-comment' does not move point,
-       ;; returns nil.
-       (when (looking-at comment-start)
-         (current-column))))
-
-   (save-excursion
-     (back-to-indentation)
-     (if (looking-at comment-start)
-         ;; An existing comment, no code preceding comment, and
-         ;; no comment on preceding line. Return nil, so
-         ;; `comment-indent' will call `indent-according-to-mode'
-         nil
-
-       ;; A comment after code on the same line.
-       comment-column))
-   ))
-
-(defun wisi-indent-statement ()
-  "Indent region given by `wisi-goto-start', `wisi-cache-end'."
-  (interactive)
-  (wisi-validate-cache (point-min) (point-max) t 'navigate)
-
-  (save-excursion
-    (let ((cache (or (wisi-get-cache (point))
-                    (wisi-backward-cache))))
-      (when cache
-       ;; can be nil if in header comment
-       (let ((start (progn (wisi-goto-start cache) (point)))
-             (end (if (wisi-cache-end cache)
-                        ;; nil when cache is statement-end
-                        (wisi-cache-end cache)
-                      (point))))
-         (indent-region start end)
-         ))
-      )))
-
-(defun wisi-indent-containing-statement ()
-  "Indent region given by `wisi-goto-containing-statement-start', 
`wisi-cache-end'."
-  (interactive)
-  (wisi-validate-cache (point-min) (point-max) t 'navigate)
-
-  (save-excursion
-    (let ((cache (or (wisi-get-cache (point))
-                    (wisi-backward-cache))))
-      (when cache
-       ;; can be nil if in header comment
-       (let ((start (progn
-                      (setq cache (wisi-goto-containing (wisi-goto-start 
cache)))
-                      (point)))
-             (end (if (wisi-cache-end cache)
-                        ;; nil when cache is statement-end
-                        (wisi-cache-end cache)
-                      (point))))
-         (indent-region start end)
-         ))
-      )))
-
-(defvar-local wisi-indent-calculate-functions nil
-  "Functions to compute indentation special cases.
-Called with point at current indentation of a line; return
-indentation column, or nil if function does not know how to
-indent that line. Run after parser indentation, so other lines
-are indented correctly.")
-
-(defvar-local wisi-post-indent-fail-hook
-  "Function to reindent portion of buffer.
-Called from `wisi-indent-region' when a parse succeeds after
-failing; assumes user was editing code that is now syntactically
-correct. Must leave point at indentation of current line.")
-
-(defvar-local wisi-indent-failed nil
-  "Non-nil when wisi-indent-region fails due to parse failing; cleared when 
indent succeeds.")
-
-(defvar-local wisi-indent-region-fallback 'wisi-indent-region-fallback-default
-  "Function to compute indent for lines in region when wisi parse fails.
-Called with BEGIN END.")
-
-(defun wisi-indent-region-fallback-default (begin end)
-  ;; Assume there is no indent info at point; user is editing. Indent
-  ;; to previous lines.
-  (goto-char begin)
-  (forward-line -1);; safe at bob
-  (back-to-indentation)
-  (let ((col (current-column)))
-    (while (and (not (eobp))
-               (< (point) end))
-      (if (= 1 (forward-line 1))
-         (indent-line-to col)
-       ;; on last line of buffer; terminate loop
-       (goto-char (point-max)))
-      (when (bobp)
-       ;; single line in buffer; terminate loop
-       (goto-char (point-max))))))
-
-(defun wisi-list-memq (a b)
-  "Return non-nil if any member of A is a memq of B."
-  (let ((temp (copy-sequence a))
-       result)
-    (while (and (not result)
-               temp)
-      (when (memq (pop temp) b)
-       (setq result t)))
-    result))
-
-(defun wisi--get-cached-indent (begin end)
-  "Return cached indent for point (must be bol), after correcting
-for parse errors. BEGIN, END is the parsed region."
-  (let ((indent (get-text-property (1- (point)) 'wisi-indent)))
-    (if indent
-       (when (and (wisi-partial-parse-p begin end)
-                  (< 0 (length (wisi-parser-parse-errors wisi--parser))))
-         (dolist (err (wisi-parser-parse-errors wisi--parser))
-           (dolist (repair (wisi--parse-error-repair err))
-             ;; point is at bol; error pos may be at first token on same line.
-             (save-excursion
-               (back-to-indentation)
-               (when (>= (point) (wisi--parse-error-repair-pos repair))
-                 (setq indent (max 0 (wisi-parse-adjust-indent wisi--parser 
indent repair))))
-               ))))
-      ;; parse did not compute indent for point. Assume the error will
-      ;; go away soon as the user edits the code, so just return 0.
-      (if (= wisi-debug 0)
-         (setq indent 0)
-       (error "nil indent for line %d" (line-number-at-pos (point)))))
-
-    indent))
-
-(defun wisi-indent-region (begin end &optional indent-blank-lines)
-  "For `indent-region-function', using the wisi indentation engine.
-If INDENT-BLANK-LINES is non-nil, also indent blank lines (for use as
-`indent-line-function')."
-  (if wisi-inhibit-parse
-      (when (< 0 wisi-debug)
-       (message "wisi-indent-region %d %d skipped; wisi-inhibit-parse"
-                (wisi-safe-marker-pos begin)
-                (wisi-safe-marker-pos end)))
-
-    (let ((wisi--parse-action 'indent)
-         (parse-required nil)
-         (end-mark (copy-marker end))
-         (prev-indent-failed wisi-indent-failed))
-
-      (when (< 0 wisi-debug)
-       (message "wisi-indent-region %d %d"
-                (wisi-safe-marker-pos begin)
-                (wisi-safe-marker-pos end)))
-
-      (wisi--check-change)
-
-      ;; BEGIN is inclusive; END is exclusive.
-      (save-excursion
-       (goto-char begin)
-       (setq begin (line-beginning-position))
-
-       (when (bobp) (forward-line))
-       (while (and (not parse-required)
-                   (or (and (= begin end) (= (point) end))
-                       (< (point) end))
-                   (not (eobp)))
-         (unless (get-text-property (1- (point)) 'wisi-indent)
-           (setq parse-required t))
-         (forward-line))
-       )
-
-      ;; A parse either succeeds and sets the indent cache on all
-      ;; lines in the parsed region, or fails and leaves valid caches
-      ;; untouched.
-      (when (and parse-required
-                (or (not wisi-parse-failed)
-                    (wisi-parse-try 'indent)))
-
-       (wisi-set-parse-try nil)
-       (wisi--run-parse begin end)
-
-       ;; If there were errors corrected, the indentation is
-       ;; potentially ambiguous; see
-       ;; test/ada_mode-interactive_2.adb. Or it was a partial parse,
-       ;; where errors producing bad indent are pretty much expected.
-       (unless (wisi-partial-parse-p begin end)
-         (setq wisi-indent-failed (< 0 (+ (length (wisi-parser-lexer-errors 
wisi--parser))
-                                          (length (wisi-parser-parse-errors 
wisi--parser))))))
-       )
-
-      (if wisi-parse-failed
-         (progn
-           ;; primary indent failed
-           (setq wisi-indent-failed t)
-           (when (functionp wisi-indent-region-fallback)
-             (when (< 0 wisi-debug)
-               (message "wisi-indent-region fallback"))
-             (funcall wisi-indent-region-fallback begin end)))
-
-       (save-excursion
-         ;; Apply cached indents. Start from end, so indenting
-         ;; doesn't affect correcting for errors in
-         ;; wisi--get-cached-indent.
-         (goto-char (1- end)) ;; end is exclusive
-         (goto-char (line-beginning-position))
-         (let ((wisi-indenting-p t))
-           (while (and (not (bobp))
-                       (or (and (= begin end) (= (point) end))
-                           (>= (point) begin)))
-             (when (or indent-blank-lines (not (eolp)))
-               ;; ’indent-region’ doesn’t indent an empty line; ’indent-line’ 
does
-               (let ((indent (if (bobp) 0 (wisi--get-cached-indent begin 
end))))
-                 (indent-line-to indent))
-               )
-             (forward-line -1))
-
-           ;; Run wisi-indent-calculate-functions
-           (when wisi-indent-calculate-functions
-             (goto-char begin)
-             (while (and (not (eobp))
-                         (< (point) end-mark))
-               (back-to-indentation)
-               (let ((indent
-                      (run-hook-with-args-until-success 
'wisi-indent-calculate-functions)))
-                 (when indent
-                   (indent-line-to indent)))
-
-               (forward-line 1)))
-           )
-
-         (when
-             (and prev-indent-failed
-                  (not wisi-indent-failed))
-           ;; Previous parse failed or indent was potentially
-           ;; ambiguous, this one is not.
-           (goto-char end-mark)
-           (when (< 0 wisi-debug)
-             (message "wisi-indent-region post-parse-fail-hook"))
-           (run-hooks 'wisi-post-indent-fail-hook))
-         ))
-      )))
-
-(defun wisi-indent-line ()
-  "For `indent-line-function'."
-  (let ((savep (copy-marker (point)))
-       (to-indent nil))
-    (back-to-indentation)
-    (when (>= (point) savep)
-      (setq to-indent t))
-
-    (wisi-indent-region (line-beginning-position (1+ (- 
wisi-indent-context-lines))) (1+ (line-end-position)) t)
-
-    (goto-char savep)
-    (when to-indent (back-to-indentation))
-    ))
-
-(defun wisi-repair-error-1 (data)
-  "Repair error reported in DATA (a ’wisi--parse-error’ or 
’wisi--lexer-error’)"
-  (let ((wisi--parse-action 'navigate))
-    (cond
-     ((wisi--lexer-error-p data)
-      (goto-char (1+ (wisi--lexer-error-pos data)))
-      (insert (wisi--lexer-error-inserted data)))
-     ((wisi--parse-error-p data)
-      (dolist (repair (wisi--parse-error-repair data))
-       (goto-char (wisi--parse-error-repair-pos repair))
-       (when (< 0 (length (wisi--parse-error-repair-deleted repair)))
-         (delete-region (car (wisi--parse-error-repair-deleted-region repair))
-                        (cdr (wisi--parse-error-repair-deleted-region repair)))
-         (when (= ?  (char-after (point)))
-           (delete-char 1)))
-       (dolist (id (wisi--parse-error-repair-inserted repair))
-         (when (and (not (bobp))
-                    (not (= ?\( (char-before (point))))
-                    (member (syntax-class (syntax-after (1- (point)))) '(2 
3))) ;; word or symbol
-           (insert " "))
-         (insert (cdr (assoc id (wisi-parser-repair-image wisi--parser)))))
-       ))
-     )))
-
-(defun wisi-repair-error ()
-  "Repair the current error."
-  (interactive)
-  (let ((wisi-inhibit-parse t)) ;; don’t let the error list change while we 
are processing it.
-    (if (= 1 (+ (length (wisi-parser-lexer-errors wisi--parser))
-               (length (wisi-parser-parse-errors wisi--parser))))
-       (progn
-         (wisi-repair-error-1 (or (car (wisi-parser-lexer-errors wisi--parser))
-                                  (car (wisi-parser-parse-errors 
wisi--parser)))))
-      (if (buffer-live-p wisi-error-buffer)
-         (let ((err
-                (with-current-buffer wisi-error-buffer
-                  (get-text-property (point) 'wisi-error-data))))
-           (wisi-repair-error-1 err))
-       (error "no current error found")
-       ))))
-
-(defun wisi-repair-errors (&optional beg end)
-  "Repair errors reported by last parse.
-If non-nil, only repair errors in BEG END region."
-  (interactive)
-  (let ((wisi-inhibit-parse t)) ;; don’t let the error list change while we 
are processing it.
-    (dolist (data (wisi-parser-lexer-errors wisi--parser))
-      (when (or (null beg)
-               (and (not (= 0 (wisi--lexer-error-inserted data)))
-                    (wisi--lexer-error-pos data)
-                    (<= beg (wisi--lexer-error-pos data))
-                    (<= (wisi--lexer-error-pos data) end)))
-       (wisi-repair-error-1 data)))
-
-    (dolist (data (wisi-parser-parse-errors wisi--parser))
-      (when (or (null beg)
-               (and (wisi--parse-error-pos data)
-                    (<= beg (wisi--parse-error-pos data))
-                    (<= (wisi--parse-error-pos data) end)))
-       (wisi-repair-error-1 data)))
-    ))
-
-;;; xref integration
-
-(defun wisi-xref-identifier-at-point ()
-  (let ((ident (thing-at-point 'symbol)))
-    (when ident
-      (put-text-property
-       0 1
-       'xref-identifier
-       (list :file (buffer-file-name)
-            :line (line-number-at-pos)
-            :column (current-column))
-       ident)
-      ident)))
-
-(defun wisi-next-name-region ()
-  "Return the next region at or after point with text property 'wisi-name'."
-  (let* ((begin
-         (if (get-text-property (point) 'wisi-name)
-             (point)
-           (next-single-property-change (point) 'wisi-name)))
-        (end (next-single-property-change begin 'wisi-name)))
-    (cons begin end)))
-
-(defun wisi-prev-name-region ()
-  "Return the prev region at or before point with text property 'wisi-name'."
-  (let* ((end
-         (if (get-text-property (point) 'wisi-name)
-             (point)
-           (previous-single-property-change (point) 'wisi-name)))
-        (begin (previous-single-property-change end 'wisi-name)))
-    (cons begin end)))
-
-(defun wisi-next-name ()
-  "Return the text at or after point with text property 'wisi-name'."
-  (let ((region (wisi-next-name-region)))
-    (buffer-substring-no-properties (car region) (cdr region))))
-
-(defun wisi-prev-name ()
-  "Return the text at or before point with text property 'wisi-name'."
-  (let ((region (wisi-prev-name-region)))
-    (buffer-substring-no-properties (car region) (cdr region))))
-
-(defconst wisi-names-regexp "\\([^<]*\\)<\\([0-9]+\\)>"
-  "Match line number encoded into identifier by `wisi-names'.")
-
-(defun wisi-names (append-lines alist)
-  "List of names; each is text from one 'wisi-name property in current buffer.
-If APPEND-LINES is non-nil, each name has the line number it
-occurs on appended. If ALIST is non-nil, the result is an alist
-where the car is a list (FILE LINE COL)."
-  (when wisi--parser
-    ;; wisi--parser is nil in a non-language buffer, like Makefile
-    (wisi-validate-cache (point-min) (point-max) t 'navigate)
-    (let ((table nil)
-         (pos (point-min))
-         end-pos)
-      (while (setq pos (next-single-property-change pos 'wisi-name))
-       ;; We can’t store location data in a string text property -
-       ;; it does not survive completion. So we include the line
-       ;; number in the identifier string. This also serves to
-       ;; disambiguate overloaded identifiers in the user interface.
-       (setq end-pos (next-single-property-change pos 'wisi-name))
-       (let* ((line (line-number-at-pos pos))
-              (summary
-               (if append-lines
-                   (format "%s<%d>"
-                           (buffer-substring-no-properties pos end-pos)
-                           line)
-                 (buffer-substring-no-properties pos end-pos))))
-         (if alist
-             (save-excursion
-               (goto-char pos)
-               (push (cons summary (list (buffer-file-name) line 
(current-column)))
-                     table))
-           (push summary table)))
-       (setq pos end-pos)
-       )
-      table)))
-
-;;;; debugging
-
-(defun wisi-show-region ()
-  (interactive)
-  (cond
-   ((use-region-p)
-    (message "(%s . %s)" (region-beginning) (region-end)))
-   (t
-    (let ((string (read-from-minibuffer "region: ")))
-      (when (not (= ?\( (aref string 0)))
-       (setq string (concat "(" string ")")))
-
-      (let ((region (read string)))
-       (cond
-        ((consp (cdr region))
-         ;; region is a list; (begin end)
-         (set-mark  (nth 0 region))
-         (goto-char (nth 1 region)))
-
-        ((consp region)
-         ;; region is a cons; (begin . end)
-         (set-mark  (car region))
-         (goto-char (cdr region)))
-        ))))
-   ))
-
-(defun wisi-debug-keys ()
-  "Add debug key definitions to `global-map'."
-  (interactive)
-  (define-key global-map "\M-h" 'wisi-show-containing-or-previous-cache)
-  (define-key global-map "\M-i" 'wisi-show-indent)
-  (define-key global-map "\M-j" 'wisi-show-cache)
-  )
-
-(defun wisi-parse-buffer (&optional parse-action begin end)
-  (interactive)
-  (unless parse-action
-    (setq parse-action (wisi-read-parse-action)))
-  (if (use-region-p)
-      (progn
-       (setq begin (region-beginning))
-       (setq end   (region-end)))
-
-    (unless begin (setq begin (point-min)))
-    (unless end (setq end (point-max))))
-
-  (wisi-set-parse-try t parse-action)
-  (wisi-invalidate-cache parse-action begin)
-
-  (cl-ecase parse-action
-    (face
-     (with-silent-modifications
-       (remove-text-properties
-       begin end
-       (list
-        'font-lock-face nil
-        'fontified nil)))
-     (wisi-validate-cache begin end t parse-action)
-     (font-lock-ensure))
-
-    (navigate
-     (wisi-validate-cache begin end t parse-action))
-
-    (indent
-     (wisi-indent-region begin end))
-    ))
-
-(defun wisi-time (func count &optional report-wait-time)
-  "call FUNC COUNT times, show total time"
-  (interactive "afunction \nncount ")
-
-  (let ((start-time (float-time))
-       (start-gcs gcs-done)
-       (cum-wait-time 0.0)
-        (i 0)
-        diff-time
-       diff-gcs)
-    (while (not (eq (1+ count) (setq i (1+ i))))
-      (save-excursion
-        (funcall func))
-      (when report-wait-time
-       (setq cum-wait-time (+ cum-wait-time 
(wisi-process--parser-total-wait-time wisi--parser)))))
-    (setq diff-time (- (float-time) start-time))
-    (setq diff-gcs (- gcs-done start-gcs))
-    (if report-wait-time
-       (progn
-         (message "Total %f seconds, %d gcs; per iteration %f seconds %d gcs 
%d responses %f wait"
-                  diff-time
-                  diff-gcs
-                  (/ diff-time count)
-                  (/ (float diff-gcs) count)
-                  (wisi-process--parser-response-count wisi--parser)
-                  (/ cum-wait-time count)))
-
-      (message "Total %f seconds, %d gcs; per iteration %f seconds %d gcs"
-              diff-time
-              diff-gcs
-              (/ diff-time count)
-              (/ (float diff-gcs) count))
-      ))
-  nil)
-
-(defun wisi-time-indent-middle-line-cold-cache (count &optional 
report-wait-time)
-  (goto-char (point-min))
-  (forward-line (1- (/ (count-lines (point-min) (point-max)) 2)))
-  (let ((cum-wait-time 0.0))
-    (wisi-time
-     (lambda ()
-       (wisi-set-parse-try t 'indent)
-       (wisi-invalidate-cache 'indent (point-min))
-       (wisi-indent-line)
-       (when (wisi-process--parser-p wisi--parser)
-        (setq cum-wait-time (+ cum-wait-time 
(wisi-process--parser-total-wait-time wisi--parser)))))
-     count
-     report-wait-time)
-    ))
-
-(defun wisi-time-indent-middle-line-warm-cache (count)
-  (wisi-set-parse-try t 'indent)
-  (wisi-invalidate-cache 'indent (point-min))
-  (goto-char (point-min))
-  (forward-line (/ (count-lines (point-min) (point-max)) 2))
-  (wisi-indent-line)
-  (wisi-time #'wisi-indent-line count))
-
-(defun wisi-show-indent ()
-  "Show indent cache for current line."
-  (interactive)
-  (message "%s" (get-text-property (1- (line-beginning-position)) 
'wisi-indent)))
-
-(defun wisi-show-cache ()
-  "Show wisi text properties at point."
-  (interactive)
-  (message "%s:%s:%s:%s"
-          (wisi-get-cache (point))
-          (get-text-property (point) 'face)
-          (get-text-property (point) 'font-lock-face)
-          (get-text-property (point) 'wisi-name)
-          ))
-
-(defun wisi-show-containing-or-previous-cache ()
-  (interactive)
-  (let ((cache (wisi-get-cache (point))))
-    (push-mark)
-    (if cache
-       (message "containing %s" (wisi-goto-containing cache t))
-      (message "previous %s" (wisi-backward-cache)))
-    ))
-
-;;;;; setup
-
-(cl-defun wisi-setup (&key indent-calculate post-indent-fail parser)
-  "Set up a buffer for parsing files with wisi."
-  (when wisi--parser
-    (wisi-kill-parser))
-
-  (setq wisi--parser parser)
-  (setq wisi--cached-regions
-       (list
-        (cons 'face nil)
-        (cons 'navigate nil)
-        (cons 'indent nil)))
-
-  (setq wisi--parse-try
-       (list
-        (cons 'face t)
-        (cons 'navigate t)
-        (cons 'indent t)))
-
-  (setq wisi--last-parse-region
-       (list
-        (cons 'face nil)
-        (cons 'navigate nil)
-        (cons 'indent nil)))
-
-  (setq wisi-indent-calculate-functions (append 
wisi-indent-calculate-functions indent-calculate))
-  (set (make-local-variable 'indent-line-function) #'wisi-indent-line)
-  (set (make-local-variable 'indent-region-function) #'wisi-indent-region)
-  (set (make-local-variable 'forward-sexp-function) #'wisi-forward-sexp)
-
-  (setq wisi-post-indent-fail-hook post-indent-fail)
-  (setq wisi-indent-failed nil)
-
-  (add-hook 'before-change-functions #'wisi-before-change 'append t)
-  (add-hook 'after-change-functions #'wisi-after-change nil t)
-  (setq wisi--change-end (copy-marker (point-min) t))
-
-  (set (make-local-variable 'comment-indent-function) 'wisi-comment-indent)
-
-  (add-hook 'completion-at-point-functions #'wisi-completion-at-point -90 t)
-
-  (add-hook 'hack-local-variables-hook 'wisi-post-local-vars nil t)
-  )
-
-(defun wisi-post-local-vars ()
-  "See wisi-setup."
-  (remove-hook 'hack-local-variables-hook #'wisi-post-local-vars)
-
-  (unless wisi-disable-face
-    (jit-lock-register #'wisi-fontify-region)))
-
-
-(provide 'wisi)
-;;; wisi.el ends here
diff --git a/packages/wisi/wisi.gpr.gp b/packages/wisi/wisi.gpr.gp
deleted file mode 100644
index 1c17529..0000000
--- a/packages/wisi/wisi.gpr.gp
+++ /dev/null
@@ -1,64 +0,0 @@
---  Abstract :
---
---  Make installed and source ELPA package wisi Ada code available for
---  other projects.
---
---  Copyright (C) 2017, 2019 Free Software Foundation, Inc.
---
---  This program is free software; you can redistribute it and/or
---  modify it under terms of the GNU General Public License as
---  published by the Free Software Foundation; either version 3, 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
---  distributed with this program; see file COPYING. If not, write to
---  the Free Software Foundation, 51 Franklin Street, Suite 500, Boston,
---  MA 02110-1335, USA.
-
-with "gnatcoll";
-with "standard_common";
-#if ELPA="no"
-with "sal";
-with "wisitoken";
-#end if;
-project Wisi is
-
-   for Source_Dirs use (".");
-
-   case Standard_Common.Profile is
-   when "On" =>
-      for Object_Dir use "obj_pro";
-      for Exec_Dir use "exec_pro";
-
-   when "Off" =>
-      for Object_Dir use "obj";
-      for Exec_Dir use ".";
-   end case;
-
-   for Languages use ("Ada", "C"); -- C needed for wisitoken-bnf-generate; 
wisitoken_grammar_re2c.c
-
-   package Compiler is
-
-      case Standard_Common.Build is
-      when "Debug" =>
-         for Default_Switches ("Ada") use
-           Standard_Common.Compiler.Common_Switches &
-           Standard_Common.Compiler.Style_Checks &
-           Standard_Common.Compiler.Debug_Switches;
-
-         for Default_Switches ("C") use 
Standard_Common.Compiler.Debug_Switches_C;
-
-      when "Normal" =>
-         for Default_Switches ("Ada") use
-           Standard_Common.Compiler.Common_Switches &
-           Standard_Common.Compiler.Style_Checks &
-           Standard_Common.Compiler.Release_Switches;
-
-         for Default_Switches ("C") use 
Standard_Common.Compiler.Release_Switches_C;
-      end case;
-
-   end Compiler;
-
-end Wisi;
diff --git a/packages/wisi/wisi.info b/packages/wisi/wisi.info
deleted file mode 100644
index e24dcee..0000000
--- a/packages/wisi/wisi.info
+++ /dev/null
@@ -1,1294 +0,0 @@
-This is wisi.info, produced by makeinfo version 6.7 from wisi.texi.
-
-Copyright (C) 1999 - 2020 Free Software Foundation, Inc.
-
-     Permission is granted to copy, distribute and/or modify this
-     document under the terms of the GNU Free Documentation License,
-     Version 1.3 or any later version published by the Free Software
-     Foundation; with no Invariant Sections, with the Front-Cover texts
-     being "A GNU Manual", and with the Back-Cover Texts as in (a)
-     below.  A copy of the license is included in the section entitled
-     "GNU Free Documentation License".
-
-     (a) The FSF's Back-Cover Text is: "You have the freedom to copy and
-     modify this GNU manual.  Buying copies from the FSF supports it in
-     developing GNU and promoting software freedom."
-INFO-DIR-SECTION Emacs
-START-INFO-DIR-ENTRY
-* Wisi: (wisi).         Error-correcting LR parsers and project integration.
-END-INFO-DIR-ENTRY
-
-
-File: wisi.info,  Node: Top,  Next: Overview,  Up: (dir)
-
-Top
-***
-
-Wisi Version 3.1.2
-
-* Menu:
-
-* Overview::
-* Grammar actions::
-* Project extension::
-* GNU Free Documentation License::
-* Index::
-
-
-File: wisi.info,  Node: Overview,  Next: Grammar actions,  Prev: Top,  Up: Top
-
-1 Overview
-**********
-
-"wisi" used to be an acronym, but now it's just a name.
-
-   The wisi package provides an elisp interface to an external parser.
-It assumes the parser generator package WisiToken
-(<http://stephe-leake.org/ada/wisitoken.html>, implemented in Ada), but
-can use any parser that meets the same API. wisi provides several
-grammar actions, to implement indentation, navigating, and syntax
-highlighting (fontification).
-
-   wisi also provides an extension to Emacs 'project.el', providing
-operations useful for compilation and cross-reference.
-
-
-File: wisi.info,  Node: Grammar actions,  Next: Project extension,  Prev: 
Overview,  Up: Top
-
-2 Grammar Actions
-*****************
-
-Grammar actions are specified in the grammar file, in a nonterminal
-declaration.  We assume the user is familiar with parser grammars and
-grammar actions.  For example, a simple "if" statement can be declared
-as:
-
-     if_statement
-       : IF expression THEN statements elsif_list ELSE statements END IF 
SEMICOLON
-         %((wisi-statement-action [1 statement-start 3 motion 6 motion 10 
statement-end])
-           (wisi-motion-action [1 3 5 6 10])
-           (wisi-indent-action [nil
-                                [(wisi-hanging% ada-indent-broken (* 2 
ada-indent-broken))
-                                 ada-indent-broken]
-                                nil
-                                [ada-indent ada-indent] nil nil
-                                [ada-indent ada-indent] nil nil nil]))%
-
-   The item before ':' is the "left hand side", or "nonterminal".  The
-list of tokens after ':' is the "right hand side"; in general there can
-be more than one right hand side for each nonterminal (separated by
-'|').
-
-   The items enclosed in "%()%" are the grammar actions.  They are
-specified as list of elisp forms; an earlier version of the wisi package
-generated an elisp parser.  We keep the elisp form because it is
-compact, and easier to read and write than the equivalent Ada code.  The
-'wisi-bnf-generate' tool converts the elisp into the required Ada
-statements.
-
-   There are two classes of actions; in-parse and post-parse.  WisiToken
-calls these "semantic checks" and "user actions".  The in-parse actions
-are done as parsing procedes; they provide extra checks that can cause
-the parse to fail.  Currently the only one provided is 'match-names'; it
-is used to check that the declaration and end names in named Ada blocks
-are the same (which can aid significantly in error correction).  In the
-grammar file, in-parse actions are specified in a second '%()%' block,
-which can be omitted if empty.  In this document, the term "action"
-means "post-parse action", we use "in-parse action" unless the meaning
-is clear from context.
-
-   Executing the wisi grammar actions creates text properties in the
-source file; those text properties are then used by elisp code for
-various purposes.
-
-   The text properties applied are:
-
-'wisi-cache'
-     This should be named 'wisi-navigate', but isn't for historical
-     reasons (there used to be only one kind of text property).
-
-     The property contains a 'wisi-cache' object, containing:
-
-     'nonterm'
-          The nonterminal in the grammar production that specified the
-          action that produced this text property.
-
-     'token'
-          A token identifier naming a token in the production right hand
-          side containing the text this text property is applied to.
-
-     'last'
-          The position of the last character in the token, relative to
-          the first character (0 indexed).  The text property is only
-          applied to the first character in the token (mostly for
-          historical reasons).
-
-     'class'
-          A token class; see the list of possible values in
-          'wisi-statement-action' below.
-
-     'containing'
-          A marker pointing to the start of the containing token for
-          this token; only 'nil' for the outermost containing token in a
-          file.
-
-     'prev'
-          A marker pointing to the previous "motion token" in the
-          statement or declaration.  These are normally language
-          keywords, but can be other things.
-
-     'next'
-          A marker pointing to the next "motion token" in the statement
-          or declaration.
-
-     'end'
-          A marker pointing to the end of the statement or declaration.
-
-     wisi provides motion commands for going to the various markers.
-
-'wisi-name'
-     Contains no data, applied to a "name" of some sort.  wisi provides
-     commands for finding the next/previous name, and returning the
-     text.  Useful for the names of subprograms, which can then be used
-     to build a completion table; see
-     'wisi-xref-identifier-completion-table'.
-
-'font-lock-face'
-     The standard font-lock property, specifying the face for the text.
-
-     Some major modes do not use this for simple keywords; they use
-     font-lock regular expressions instead.  One reason for this is so
-     keywords are still highlighted when the parser fails, which can
-     happen if there are severe syntax errors.
-
-     Other items, like function and package names, are typically marked
-     with 'font-lock-face' by the parser.
-
-'fontified'
-     Another standard font-lock text property; applied whenever
-     'font-lock-face' is.
-
-'wisi-indent'
-     Contains the indent (in characters) for the next line; applied to
-     the newline character on the preceding line.  The first line in a
-     buffer is assumed to have indent 0.
-
-   Each action is classified as one of 'navigate, face, indent,
-in-parse'; when actions are executed, only one of the first three
-classes is executed (in-parse is always executed).  This reflects the
-reasons the parser is run; to figure out how to go somehere (end of
-current statement, start of current procedure, etc), to apply faces for
-syntax highlighting, or to indent the code.
-
-* Menu:
-
-* Navigate actions::
-* Face actions::
-* Indent actions::
-* In-parse actions::
-
-
-File: wisi.info,  Node: Navigate actions,  Next: Face actions,  Up: Grammar 
actions
-
-2.1 Navigate actions
-====================
-
-'wisi-statement-action [TOKEN CLASS ...]'
-     The argument is a vector; alternating items are a token index (an
-     integer or label indicating a token in the right hand side) and a
-     "token class"; one of:
-
-     'motion'
-          Create a 'wisi-cache' text property on the token, for use in a
-          subsequent 'wisi-motion-action'.
-
-     'statement-end'
-          Create a 'wisi-cache' text property on the token, enter a
-          pointer to it in the other 'wisi-cache' objects in the
-          statement or declaration.
-
-     'statement-start'
-          Create a 'wisi-cache' text property on the token, enter a
-          pointer to it in the other 'wisi-cache' objects (in the
-          'containing' slot) in the statement or declaration.
-
-     'statement-override'
-          Same as 'statement-start'; marks the token to be used as the
-          statement start if the first token is optional.
-
-     'misc'
-          Create a 'wisi-cache' text property on the token, to be used
-          for some other purpose.  It is good style to indicate the
-          purpose in a comment.
-
-          For example, ada-mode uses a 'misc' property on left
-          parentheses that start a subprogram parameter list; this
-          distinquishes them from other left parentheses, and makes it
-          possible to automatically call 'ada-format-paramlist' to
-          format the parameter list, instead of using the standard Emacs
-          'align'.
-
-'wisi-motion-action [TOKEN ...]'
-     The argument is a vector, where each element is either a token
-     index or a vector [INDEX ID].
-
-     Each terminal token must already have a 'wisi-cache' created by a
-     'wisi-statement-action' (this is checked at action execution, not
-     during grammar generation).  This action sets the 'prev, next'
-     slots for the chain of tokens, creating a chain of motion tokens.
-
-     If TOKEN is a nonterminal without an ID specified, the 'wisi-cache'
-     must be on the first token in the nonterminal, and it is assumed to
-     have a valid pointer in the 'next' slot, indicating a chain of
-     motion tokens.  That chain is linked into the chain for the current
-     right hand side.
-
-     If TOKEN is a nonterminal with an ID, the region contained by the
-     nonterminal is searched for all 'wisi-cache' with that token ID,
-     and for each one where prev/next is not already set, it is linked
-     into the motion chain.
-
-     Note that the "search" described here is done in the parser
-     process, on a tree data structure containing the data that will
-     eventually be stored in Emacs text properties.
-
-'wisi-name-action TOKEN'
-     TOKEN is a token index.  Create a 'wisi-name' text property on the
-     token.
-
-
-File: wisi.info,  Node: Face actions,  Next: Indent actions,  Prev: Navigate 
actions,  Up: Grammar actions
-
-2.2 Face actions
-================
-
-'wisi-face-mark-action [INDEX CLASS ...]'
-     The argument is a vector; alternating elements form pairs of INDEX
-     CLASS, where class is one of 'prefix, suffix'.
-
-     Mark the tokens as part of a compound name, for use by later face
-     actions.
-
-'wisi-face-apply-action [TOKEN PREFIX-FACE SUFFIX-FACE ...]'
-     The argument is a vector; triples of items specify TOKEN,
-     PREFIX-FACE, SUFFIX-FACE. The faces are the elisp names of face
-     objects (which must declared by an '%elisp_face' declaration).
-
-     If the token is a nonterminal, and it has been marked by a previous
-     'wisi-face-mark-action', the specified faces are applied to the
-     prefix and suffix in the token as 'font-lock-face' text properties.
-
-     If the token is a terminal, or a non-terminal with no face mark,
-     the suffix face is applied to the entire text contained by the
-     token.
-
-'wisi-face-apply-list-action [TOKEN PREFIX-FACE SUFFIX-FACE ...]'
-     Similar to ’wisi-face-apply-action’, but applies faces to all
-     tokens marked by 'wisi-face-mark-action' in each indicated
-     production token, and does not apply a face if there are no such
-     marks.
-
-
-File: wisi.info,  Node: Indent actions,  Next: In-parse actions,  Prev: Face 
actions,  Up: Grammar actions
-
-2.3 Indent actions
-==================
-
-Indents are computed for each line in a cumulative way as the grammar
-actions are executed.  Initially, each indent is set to 'nil', which
-means "not computed"; this is not the same as the value '0'.  The
-grammar actions are executed in a bottom-up fashion; low level
-productions are executed before higher level ones.  In general, the
-indent action for a production specifies a "delta indent"; the indent is
-incremented by that amount.  When all productions have been processed,
-the indent has been computed for all lines.
-
-   Indents are often given as a function call; the arguments to the
-function can be other function calls, or integer expressions.
-'wisitoken-bnf-generate' supports only simple integer expressions; those
-using integers, integer-valued variables, parenthesis, + (plus), -
-(minus), and * (multiply).
-
-'wisi-indent-action [INDENT ...]'
-     The argument is a vector, giving an indent for each token in the
-     production right-hand side.
-
-     For terminals, the indents only have meaning, and are only
-     computed, if the token is the first on a line.  For nonterminals
-     where the indent is not a variant of 'wisi-hanging', the indent is
-     only computed if the first terminal token in the nonterminal is the
-     first on a line.  See 'wisi-hanging' in *note Indent functions::
-     for the remaining case.
-
-     An indent can have several forms.  In the descriptions below, the
-     "current token" is given by the position of the indent expression
-     in the 'wisi-indent-action' argument list.
-
-     An integer
-          This gives a delta indent; it is added to the total indent for
-          the line.
-
-     A variable name
-          The name is translated to an Ada identifier by replacing "-"
-          with "_", and applying 'Camel_Case'.  The translated name must
-          identify a directly visible run-time Ada integer variable;
-          this is checked at Ada compile time.  It provides an integer
-          delta indent.
-
-          For example, in Ada two indent variable names are 'ada-indent'
-          and 'ada-indent-broken', giving the basic ident, and the
-          continuation line indent.  They are runtime variables so
-          different projects can specify them as part of a coding
-          standard.
-
-     A function call
-          A function that computes a delta indent.  See *note Indent
-          functions::.
-
-     [CODE-INDENT , COMMENT-INDENT]
-          A vector giving separate indents for code and comments.
-
-          Normally, the indent for trailing comments (on lines with no
-          code, after all code in the token) is given by the indent of
-          the following token in the production.  When the current token
-          is the last, or the following tokens may be empty, or the
-          indent of the following token would be wrong for some reason
-          (for example, it is a block end), the comment indent may be
-          specified separately.  If it is not specified, and the indent
-          from the next token is not available, the indent for the
-          current token is used for code and comments.
-
-          Comment lines that are not trailing are indented by
-          CODE-INDENT.
-
-     (label . INDENT)
-          If token labels are used in a right hand side, they must be
-          given explicitly in the indent arguments, using he lisp "cons"
-          syntax.  Labels are normally only used with EBNF grammars,
-          which expand into multiple right hand sides, with optional
-          tokens simply left out.  Explicit labels on the indent
-          arguments allow them to be left out as well.
-
-* Menu:
-
-* Indent functions::
-* Indent example::
-
-
-File: wisi.info,  Node: Indent functions,  Next: Indent example,  Up: Indent 
actions
-
-2.3.1 Indent functions
-----------------------
-
-'wisi-anchored TOKEN OFFSET'
-     Sets the indent for the current token to be OFFSET (an integer
-     expression) from the start of TOKEN (a token index); the current
-     token is "anchored to" TOKEN.
-
-'wisi-anchored* TOKEN OFFSET'
-     Sets the indent for the current token to be OFFSET from the start
-     of TOKEN, but only if TOKEN is the first token on a line; otherwise
-     no indent
-
-'wisi-anchored*- TOKEN OFFSET'
-     Sets the indent for the current token to be OFFSET from the start
-     of TOKEN, but only if TOKEN is the first token on a line and the
-     indent for the current token accumulated so far is nil.
-
-'wisi-anchored% TOKEN OFFSET'
-     If there is an opening parenthesis containing TOKEN in the line
-     containing TOKEN, set the current indent to OFFSET from that
-     parenthesis.  Otherwise, OFFSET gives an indent delta.
-
-'wisi-anchored%- TOKEN OFFSET'
-     Same as 'wisi-anchored%', but only if the current token accumulated
-     indent is nil.
-
-'wisi-hanging DELTA-1 DELTA-2'
-     The current token is assumed to be a nonterminal.  If the text it
-     contains spans multiple lines, use DELTA-1 for the first line,
-     DELTA-2 for the rest.  If the current token is only on one line,
-     use DELTA-1.
-
-     DELTA-1 and DELTA-2 can be any IDENT expression, except a variant
-     of 'wisi-hanging'.
-
-'wisi-hanging% DELTA-1 DELTA-2'
-     Similar to 'wisi-hanging'; if the first terminal token in the
-     current nonterminal is the first token on the first line, use
-     DELTA-1 for the first line and DELTA-2 for the rest.  Otherwise,
-     use DELTA-1 for all lines.
-
-'wisi-hanging%- DELTA-1 DELTA-2'
-     Same as 'wisi-hanging%', except applied only if the current token
-     accumulated indent is nil.
-
-'Language-specific function'
-     Language-specific indent functions are specified by an
-     '%elisp_indent' declaration in the grammar file.  Each function
-     specifies how many arguments it accepts; this is checked at action
-     runtime, not during grammar generation.  Each argument is an INDENT
-     as described above, or a token ID prefixed by ''' (to allow
-     distinguishing token IDs from variable names).
-
-
-File: wisi.info,  Node: Indent example,  Prev: Indent functions,  Up: Indent 
actions
-
-2.3.2 Indent example
---------------------
-
-The example 'if_statement' grammar nonterminal is:
-
-     if_statement
-       : IF expression THEN statements elsif_list ELSE statements END IF 
SEMICOLON
-         %((wisi-indent-action [nil
-                                [(wisi-hanging% ada-indent-broken (* 2 
ada-indent-broken))
-                                 ada-indent-broken]
-                                nil
-                                [ada-indent ada-indent] nil nil
-                                [ada-indent ada-indent] nil nil nil]))%
-
-   We trace how the indent is computed for this sample Ada code:
-
-      1: if A < B and
-      2:   C < D
-      3:   --  comment on expression
-      4: then
-      5:    if E then
-      6:       Do_E;
-      7:       -- comment on statement
-      8:    elsif F then
-      9:       G := A + Compute_Something
-     10:         (arg_1, arg_2);
-     11:    end if;
-     12: end if;
-
-   First, the indent for the lower-level nonterminals ('expression,
-statements, elsif_list') are computed.  Assume they set the indent for
-line 10 to 2 (for the hanging expression) and leave the rest at nil.
-
-   Next, the action for the inner 'if_statement' is executed.  Most of
-the tokens specify an indent of 'nil', which means the current
-accumulated indent is not changed.  For the others, the action is as
-follows:
-
-'expression:'
-     The expression 'E' is contained on one line, and it is not the
-     first token on that line, so the indent for line 5 is not changed.
-
-'statements: [ada-indent ada-indent]'
-     This specifies separate indents for code and trailing comments,
-     because otherwise the trailing comments would be indented with the
-     following 'THEN'; instead they are indented with the expression
-     code; see the comment on line 7.
-
-     Here 'ada-indent' is 3, so the indent for lines 6 and 7 (for the
-     first occurence of 'statments') is incremented from 'nil' to '3'.
-
-     For the second occurence of 'statements', line 9 is incremented
-     from 'nil' to '3', and line 10 from '2' to '5'.
-
-   At this point, the accumulated indents are (the indent is given after
-the line number):
-      1: nil : if A < B and
-      2: nil :   C < D
-      3: nil :   --  comment on expression
-      4: nil : then
-      5: nil :    if E then
-      6:   3 :       Do_E;
-      7:   3 :       -- comment on statement
-      8: nil :    elsif F then
-      9:   3 :       G := A + Compute_Something
-     10:   5 :         (arg_1, arg_2);
-     11: nil :    end if;
-     12: nil : end if;
-
-   Then the action is executed for the outer 'if_statement':
-
-'expression: [(wisi-hanging% ada-indent-broken (* 2 ada-indent-broken)) 
ada-indent-broken]'
-     This specifies separate indents for code and trailing comments,
-     because otherwise the trailing comments would be indented with the
-     following 'THEN'; instead they are indented with the expression
-     code; see the comment on line 3.
-
-     In this case, 'wisi-hanging%' returns DELTA-1, which is
-     'ada-indent-broken', which is 2.  So the indent for line 2 is
-     incremented from 'nil' to '2'.
-
-     The indent for line 3 is also incremented from 'nil' to '2'.
-
-'statements: [ada-indent ada-indent]'
-     Here there is only one statement; the nested 'if_statement'.  The
-     indent for lines 5 ..  11 are each incremented by 3.
-
-   The final result is:
-      1: nil : if A < B and
-      2:   2 :   C < D
-      3:   2 :   --  comment on expression
-      4: nil : then
-      5:   3 :    if E then
-      6:   6 :       Do_E;
-      7:   6 :       -- comment on statement
-      8:   3 :    elsif F then
-      9:   6 :       G := A + Compute_Something
-     10:   8 :         (arg_1, arg_2);
-     11:   6 :    end if;
-     12: nil : end if;
-
-   In a full grammar, the top production should specify an indent of 0,
-not nil, for tokens that are not indented; then every line will have a
-non-nil indent.  However, in normal operation a nil indent is treated as
-0; the 'wisi-indent' text property is not set for lines that have nil
-indent, and 'wisi-indent-region' detects that and uses 0 for the indent.
-You can set the variable 'wisi-debug' to a value > 0 to signal an error
-for nil indents; this is useful to catch indent errors during grammar
-development.
-
-
-File: wisi.info,  Node: In-parse actions,  Prev: Indent actions,  Up: Grammar 
actions
-
-2.4 In-parse actions
-====================
-
-'wisi-propagate-name TOKEN'
-     The argument is a token index.  Set the 'name' component of the
-     left-hand-side parse-time token object to the 'name' component of
-     the identified token, if it is not empty.  Otherwise use the
-     'byte_region' component.
-
-'wisi-merge-name FIRST-TOKEN, LAST-TOKEN'
-     The arguments are token indices, giving a range of tokens.
-     LAST-TOKEN may be omitted if it is the same as FIRST-TOKEN.
-
-     Set the 'name' component of the left-hand-side to the merger of the
-     'name' or 'byte-region' components of the identified tokens.
-
-'wisi-match-name START-TOKEN END-TOKEN'
-     The arguments are token indices.  Compare the text contained by the
-     'name' (or 'byte_region' if 'name' is empty) token components for
-     START-TOKEN and END-TOKEN; signal a parse error if they are
-     different.
-
-     The behavior when a name is missing is determined by the runtime
-     language variable given in the '%end_names_optional_option'
-     declaration; if True, a missing name that is supposed to match a
-     present name is an error.  Both names missing is not an error
-     (assuming that is allowed by the grammar).
-
-
-File: wisi.info,  Node: Project extension,  Next: GNU Free Documentation 
License,  Prev: Grammar actions,  Up: Top
-
-3 Project extension
-*******************
-
-wisi defines the 'cl-defstuct' 'wisi-prj', with operations suitable for
-compilation and cross-reference.
-
-   In order to use wisi projects, the user must write project files and
-customize 'project-find-functions' and 'xref-backend-functions'.
-
-* Menu:
-
-* Project files::
-* Selecting projects::
-* Casing exception files::
-* Other project functions::
-
-
-File: wisi.info,  Node: Project files,  Next: Selecting projects,  Up: Project 
extension
-
-3.1 Project files
-=================
-
-Project file names must have an extension given by
-'wisi-prj-file-extensions' (default '.adp, .prj').
-
-   Project files have a simple syntax; they may be edited directly.
-Each line specifies a project variable name and its value, separated by
-"=":
-
-     src_dir=/Projects/my_project/src_1
-     src_dir=/Projects/my_project/src_2
-
-   There must be no space between the variable name and "=", and no
-trailing spaces after the value.
-
-   Any line that does not have an "=" is a comment.
-
-   Some variables (like 'src_dir') are lists; each line in the project
-file specifies one element of the list.  The value on the last line is
-the last element in the list.
-
-   A variable name that starts with '$' is set as a process environment
-variable, for processes launched from Emacs for the project.
-
-   In values, process environment variables can be referenced using the
-normal '$var' syntax.
-
-   In values, relative file names are expanded relative to the directory
-containing the project file.
-
-   Here is the list of project variables defined by wisi; major modes
-may add more.
-
-'casing' [slot: 'case-exception-files']
-     List of files containing casing exceptions.  *Note Casing exception
-     files::.
-
-'src_dir' [slot: 'source-path']
-     A list of directories to search for source files.
-
-
-File: wisi.info,  Node: Selecting projects,  Next: Casing exception files,  
Prev: Project files,  Up: Project extension
-
-3.2 Selecting projects
-======================
-
-The current project can either be indicated by a global variable (called
-a "selected project"), or depend on the current buffer.
-
-   In addition, the project file can be parsed each time it is needed,
-or the result cached to improve response time,
-
-   One reason to use a selected project is to handle a hierarchy of
-projects; if projects B and C both depend on library project A, then
-when in a file of project A, there is no way to determine which of the
-three projects to return.  So the user must indicate which is active, by
-using one of 'wisi-prj-select-file' or 'wisi-prj-select-cache'.
-
-   In addition, if changing from one project to another requires setting
-global resources that must also be unset (such as a syntax propertize
-hook or compilation filter hook), then the project should define
-'wisi-prj-deselect' in addition to 'wisi-prj-select'.  Such projects
-require having a selected current project, so it can be deselected
-before a new one is selected.  One example of such projects is ada-mode.
-
-   One way to declare each project is to add a Local Variables section
-in the main Makefile for the project; when the Makefile is first
-visited, the project is declared.  In the examples here, we assume that
-approach is used; each gives an :eval line.
-
-   Note that 'wisi-prj-current-parse' and 'wisi-prj-current-cached'
-always succeed after some project is selected; no functions after them
-on 'project-find-functions' will be called.  That's why the depth is 90
-for those in the examples.
-
-No caching, current project depends on current buffer
-
-          (add-hook 'project-find-functions #'wisi-prj-find-dominating-parse 0)
-
-          :eval (wisi-prj-set-dominating "foo.prj" (foo-prj-default 
"prj-name"))
-
-     'wisi-prj-set-dominating' declares the name of a project file with
-     a default project object, and ensures that the current buffer file
-     name is in 'wisi-prj--dominating'.
-
-     'wisi-prj-find-dominating-parse' looks for the filenames in
-     'wisi-prj--dominiating' in the parent directories of the current
-     buffer.  When one is found, the associated project file is parsed,
-     using the default project object to dispatch to the appropriate
-     parsers.  Then the final project object is returned.
-
-Caching, current project depends on current buffer
-
-          (add-hook 'project-find-functions #'wisi-prj-find-dominating-cached 
0)
-
-          :eval (wisi-prj-cache-dominating "foo.prj" (foo-prj-default 
"prj-name"))
-
-     'wisi-prj-cache-dominating' declares the project file, parses it,
-     and saves the project object in a cache indexed by the absolute
-     project file name.
-
-     'wisi-prj-find-dominating-cached' finds the dominating project
-     file, and retrieves the object from the cache.
-
-No caching, last selected project is current
-
-          (add-hook 'project-find-functions #'wisi-prj-current-parse 90)
-
-          :eval: (wisi-prj-select-file <prj-file> (foo-prj-default "prj-name"))
-
-     'wisi-prj-select-file' sets the project file as the current
-     project, and saves the default project object.
-
-     'wisi-prj-current-parse' parses the current project file, using the
-     saved default project object, and returns the project object.
-
-Caching, last selected project is current
-
-          (add-hook 'project-find-functions #'wisi-prj-current-cached 90)
-
-          :eval: (wisi-prj-select-cache <prj-file> (foo-prj-default 
"prj-name"))
-
-     'wisi-prj-select-cache' parses the project file, caches the project
-     object.
-
-     'wisi-prj-current-cached' returns the cached current project
-     object.
-
-   In addition, the user should set 'xref-backend-functions'.
-Currently, there is only one choice for wisi projects:
-
-     (add-to-list 'xref-backend-functions #'wisi-prj-xref-backend 90)
-
-   'wisi-prj-xref-backend' returns the current wisi project object.
-
-
-File: wisi.info,  Node: Casing exception files,  Next: Other project 
functions,  Prev: Selecting projects,  Up: Project extension
-
-3.3 Casing exception files
-==========================
-
-Each line in a case exception file specifies the casing of one word or
-word fragment.  If an exception is defined in multiple files, the first
-occurrence is used.
-
-   If the word starts with an asterisk ('*'), it defines the casing of a
-word fragment (or "substring"); part of a word between two underscores
-or word boundary.
-
-   For example:
-
-     DOD
-     *IO
-     GNAT
-
-   The word fragment '*IO' applies to any word containing "_io";
-'Text_IO', 'Hardware_IO', etc.
-
-
-File: wisi.info,  Node: Other project functions,  Prev: Casing exception 
files,  Up: Project extension
-
-3.4 Other project functions
-===========================
-
-'wisi-refresh-prj-cache (not-full)'
-     Refreshes all cached data in the project, and re-selects the
-     project.  If NOT-FULL is non-nil, slow refresh operations are
-     skipped.
-
-     This reparses the project file, and any cross reference
-     information.
-
-'wisi-prj-select-dominating (dominating-file)'
-     Find a wisi-prj matching DOMINATING-FILE (defaults to the current
-     buffer file).  If the associated project is current, do nothing.
-     If it is not current, select it.
-
-     This is useful before running 'compilation-start', to ensure the
-     correct project is current.
-
-
-File: wisi.info,  Node: GNU Free Documentation License,  Next: Index,  Prev: 
Project extension,  Up: Top
-
-Appendix A GNU Free Documentation License
-*****************************************
-
-                     Version 1.3, 3 November 2008
-
-     Copyright (C) 2000, 2001, 2002, 2007, 2008, 2009 Free Software 
Foundation, Inc.
-     <http://fsf.org/>
-
-     Everyone is permitted to copy and distribute verbatim copies
-     of this license document, but changing it is not allowed.
-
-  0. PREAMBLE
-
-     The purpose of this License is to make a manual, textbook, or other
-     functional and useful document "free" in the sense of freedom: to
-     assure everyone the effective freedom to copy and redistribute it,
-     with or without modifying it, either commercially or
-     noncommercially.  Secondarily, this License preserves for the
-     author and publisher a way to get credit for their work, while not
-     being considered responsible for modifications made by others.
-
-     This License is a kind of "copyleft", which means that derivative
-     works of the document must themselves be free in the same sense.
-     It complements the GNU General Public License, which is a copyleft
-     license designed for free software.
-
-     We have designed this License in order to use it for manuals for
-     free software, because free software needs free documentation: a
-     free program should come with manuals providing the same freedoms
-     that the software does.  But this License is not limited to
-     software manuals; it can be used for any textual work, regardless
-     of subject matter or whether it is published as a printed book.  We
-     recommend this License principally for works whose purpose is
-     instruction or reference.
-
-  1. APPLICABILITY AND DEFINITIONS
-
-     This License applies to any manual or other work, in any medium,
-     that contains a notice placed by the copyright holder saying it can
-     be distributed under the terms of this License.  Such a notice
-     grants a world-wide, royalty-free license, unlimited in duration,
-     to use that work under the conditions stated herein.  The
-     "Document", below, refers to any such manual or work.  Any member
-     of the public is a licensee, and is addressed as "you".  You accept
-     the license if you copy, modify or distribute the work in a way
-     requiring permission under copyright law.
-
-     A "Modified Version" of the Document means any work containing the
-     Document or a portion of it, either copied verbatim, or with
-     modifications and/or translated into another language.
-
-     A "Secondary Section" is a named appendix or a front-matter section
-     of the Document that deals exclusively with the relationship of the
-     publishers or authors of the Document to the Document's overall
-     subject (or to related matters) and contains nothing that could
-     fall directly within that overall subject.  (Thus, if the Document
-     is in part a textbook of mathematics, a Secondary Section may not
-     explain any mathematics.)  The relationship could be a matter of
-     historical connection with the subject or with related matters, or
-     of legal, commercial, philosophical, ethical or political position
-     regarding them.
-
-     The "Invariant Sections" are certain Secondary Sections whose
-     titles are designated, as being those of Invariant Sections, in the
-     notice that says that the Document is released under this License.
-     If a section does not fit the above definition of Secondary then it
-     is not allowed to be designated as Invariant.  The Document may
-     contain zero Invariant Sections.  If the Document does not identify
-     any Invariant Sections then there are none.
-
-     The "Cover Texts" are certain short passages of text that are
-     listed, as Front-Cover Texts or Back-Cover Texts, in the notice
-     that says that the Document is released under this License.  A
-     Front-Cover Text may be at most 5 words, and a Back-Cover Text may
-     be at most 25 words.
-
-     A "Transparent" copy of the Document means a machine-readable copy,
-     represented in a format whose specification is available to the
-     general public, that is suitable for revising the document
-     straightforwardly with generic text editors or (for images composed
-     of pixels) generic paint programs or (for drawings) some widely
-     available drawing editor, and that is suitable for input to text
-     formatters or for automatic translation to a variety of formats
-     suitable for input to text formatters.  A copy made in an otherwise
-     Transparent file format whose markup, or absence of markup, has
-     been arranged to thwart or discourage subsequent modification by
-     readers is not Transparent.  An image format is not Transparent if
-     used for any substantial amount of text.  A copy that is not
-     "Transparent" is called "Opaque".
-
-     Examples of suitable formats for Transparent copies include plain
-     ASCII without markup, Texinfo input format, LaTeX input format,
-     SGML or XML using a publicly available DTD, and standard-conforming
-     simple HTML, PostScript or PDF designed for human modification.
-     Examples of transparent image formats include PNG, XCF and JPG.
-     Opaque formats include proprietary formats that can be read and
-     edited only by proprietary word processors, SGML or XML for which
-     the DTD and/or processing tools are not generally available, and
-     the machine-generated HTML, PostScript or PDF produced by some word
-     processors for output purposes only.
-
-     The "Title Page" means, for a printed book, the title page itself,
-     plus such following pages as are needed to hold, legibly, the
-     material this License requires to appear in the title page.  For
-     works in formats which do not have any title page as such, "Title
-     Page" means the text near the most prominent appearance of the
-     work's title, preceding the beginning of the body of the text.
-
-     The "publisher" means any person or entity that distributes copies
-     of the Document to the public.
-
-     A section "Entitled XYZ" means a named subunit of the Document
-     whose title either is precisely XYZ or contains XYZ in parentheses
-     following text that translates XYZ in another language.  (Here XYZ
-     stands for a specific section name mentioned below, such as
-     "Acknowledgements", "Dedications", "Endorsements", or "History".)
-     To "Preserve the Title" of such a section when you modify the
-     Document means that it remains a section "Entitled XYZ" according
-     to this definition.
-
-     The Document may include Warranty Disclaimers next to the notice
-     which states that this License applies to the Document.  These
-     Warranty Disclaimers are considered to be included by reference in
-     this License, but only as regards disclaiming warranties: any other
-     implication that these Warranty Disclaimers may have is void and
-     has no effect on the meaning of this License.
-
-  2. VERBATIM COPYING
-
-     You may copy and distribute the Document in any medium, either
-     commercially or noncommercially, provided that this License, the
-     copyright notices, and the license notice saying this License
-     applies to the Document are reproduced in all copies, and that you
-     add no other conditions whatsoever to those of this License.  You
-     may not use technical measures to obstruct or control the reading
-     or further copying of the copies you make or distribute.  However,
-     you may accept compensation in exchange for copies.  If you
-     distribute a large enough number of copies you must also follow the
-     conditions in section 3.
-
-     You may also lend copies, under the same conditions stated above,
-     and you may publicly display copies.
-
-  3. COPYING IN QUANTITY
-
-     If you publish printed copies (or copies in media that commonly
-     have printed covers) of the Document, numbering more than 100, and
-     the Document's license notice requires Cover Texts, you must
-     enclose the copies in covers that carry, clearly and legibly, all
-     these Cover Texts: Front-Cover Texts on the front cover, and
-     Back-Cover Texts on the back cover.  Both covers must also clearly
-     and legibly identify you as the publisher of these copies.  The
-     front cover must present the full title with all words of the title
-     equally prominent and visible.  You may add other material on the
-     covers in addition.  Copying with changes limited to the covers, as
-     long as they preserve the title of the Document and satisfy these
-     conditions, can be treated as verbatim copying in other respects.
-
-     If the required texts for either cover are too voluminous to fit
-     legibly, you should put the first ones listed (as many as fit
-     reasonably) on the actual cover, and continue the rest onto
-     adjacent pages.
-
-     If you publish or distribute Opaque copies of the Document
-     numbering more than 100, you must either include a machine-readable
-     Transparent copy along with each Opaque copy, or state in or with
-     each Opaque copy a computer-network location from which the general
-     network-using public has access to download using public-standard
-     network protocols a complete Transparent copy of the Document, free
-     of added material.  If you use the latter option, you must take
-     reasonably prudent steps, when you begin distribution of Opaque
-     copies in quantity, to ensure that this Transparent copy will
-     remain thus accessible at the stated location until at least one
-     year after the last time you distribute an Opaque copy (directly or
-     through your agents or retailers) of that edition to the public.
-
-     It is requested, but not required, that you contact the authors of
-     the Document well before redistributing any large number of copies,
-     to give them a chance to provide you with an updated version of the
-     Document.
-
-  4. MODIFICATIONS
-
-     You may copy and distribute a Modified Version of the Document
-     under the conditions of sections 2 and 3 above, provided that you
-     release the Modified Version under precisely this License, with the
-     Modified Version filling the role of the Document, thus licensing
-     distribution and modification of the Modified Version to whoever
-     possesses a copy of it.  In addition, you must do these things in
-     the Modified Version:
-
-       A. Use in the Title Page (and on the covers, if any) a title
-          distinct from that of the Document, and from those of previous
-          versions (which should, if there were any, be listed in the
-          History section of the Document).  You may use the same title
-          as a previous version if the original publisher of that
-          version gives permission.
-
-       B. List on the Title Page, as authors, one or more persons or
-          entities responsible for authorship of the modifications in
-          the Modified Version, together with at least five of the
-          principal authors of the Document (all of its principal
-          authors, if it has fewer than five), unless they release you
-          from this requirement.
-
-       C. State on the Title page the name of the publisher of the
-          Modified Version, as the publisher.
-
-       D. Preserve all the copyright notices of the Document.
-
-       E. Add an appropriate copyright notice for your modifications
-          adjacent to the other copyright notices.
-
-       F. Include, immediately after the copyright notices, a license
-          notice giving the public permission to use the Modified
-          Version under the terms of this License, in the form shown in
-          the Addendum below.
-
-       G. Preserve in that license notice the full lists of Invariant
-          Sections and required Cover Texts given in the Document's
-          license notice.
-
-       H. Include an unaltered copy of this License.
-
-       I. Preserve the section Entitled "History", Preserve its Title,
-          and add to it an item stating at least the title, year, new
-          authors, and publisher of the Modified Version as given on the
-          Title Page.  If there is no section Entitled "History" in the
-          Document, create one stating the title, year, authors, and
-          publisher of the Document as given on its Title Page, then add
-          an item describing the Modified Version as stated in the
-          previous sentence.
-
-       J. Preserve the network location, if any, given in the Document
-          for public access to a Transparent copy of the Document, and
-          likewise the network locations given in the Document for
-          previous versions it was based on.  These may be placed in the
-          "History" section.  You may omit a network location for a work
-          that was published at least four years before the Document
-          itself, or if the original publisher of the version it refers
-          to gives permission.
-
-       K. For any section Entitled "Acknowledgements" or "Dedications",
-          Preserve the Title of the section, and preserve in the section
-          all the substance and tone of each of the contributor
-          acknowledgements and/or dedications given therein.
-
-       L. Preserve all the Invariant Sections of the Document, unaltered
-          in their text and in their titles.  Section numbers or the
-          equivalent are not considered part of the section titles.
-
-       M. Delete any section Entitled "Endorsements".  Such a section
-          may not be included in the Modified Version.
-
-       N. Do not retitle any existing section to be Entitled
-          "Endorsements" or to conflict in title with any Invariant
-          Section.
-
-       O. Preserve any Warranty Disclaimers.
-
-     If the Modified Version includes new front-matter sections or
-     appendices that qualify as Secondary Sections and contain no
-     material copied from the Document, you may at your option designate
-     some or all of these sections as invariant.  To do this, add their
-     titles to the list of Invariant Sections in the Modified Version's
-     license notice.  These titles must be distinct from any other
-     section titles.
-
-     You may add a section Entitled "Endorsements", provided it contains
-     nothing but endorsements of your Modified Version by various
-     parties--for example, statements of peer review or that the text
-     has been approved by an organization as the authoritative
-     definition of a standard.
-
-     You may add a passage of up to five words as a Front-Cover Text,
-     and a passage of up to 25 words as a Back-Cover Text, to the end of
-     the list of Cover Texts in the Modified Version.  Only one passage
-     of Front-Cover Text and one of Back-Cover Text may be added by (or
-     through arrangements made by) any one entity.  If the Document
-     already includes a cover text for the same cover, previously added
-     by you or by arrangement made by the same entity you are acting on
-     behalf of, you may not add another; but you may replace the old
-     one, on explicit permission from the previous publisher that added
-     the old one.
-
-     The author(s) and publisher(s) of the Document do not by this
-     License give permission to use their names for publicity for or to
-     assert or imply endorsement of any Modified Version.
-
-  5. COMBINING DOCUMENTS
-
-     You may combine the Document with other documents released under
-     this License, under the terms defined in section 4 above for
-     modified versions, provided that you include in the combination all
-     of the Invariant Sections of all of the original documents,
-     unmodified, and list them all as Invariant Sections of your
-     combined work in its license notice, and that you preserve all
-     their Warranty Disclaimers.
-
-     The combined work need only contain one copy of this License, and
-     multiple identical Invariant Sections may be replaced with a single
-     copy.  If there are multiple Invariant Sections with the same name
-     but different contents, make the title of each such section unique
-     by adding at the end of it, in parentheses, the name of the
-     original author or publisher of that section if known, or else a
-     unique number.  Make the same adjustment to the section titles in
-     the list of Invariant Sections in the license notice of the
-     combined work.
-
-     In the combination, you must combine any sections Entitled
-     "History" in the various original documents, forming one section
-     Entitled "History"; likewise combine any sections Entitled
-     "Acknowledgements", and any sections Entitled "Dedications".  You
-     must delete all sections Entitled "Endorsements."
-
-  6. COLLECTIONS OF DOCUMENTS
-
-     You may make a collection consisting of the Document and other
-     documents released under this License, and replace the individual
-     copies of this License in the various documents with a single copy
-     that is included in the collection, provided that you follow the
-     rules of this License for verbatim copying of each of the documents
-     in all other respects.
-
-     You may extract a single document from such a collection, and
-     distribute it individually under this License, provided you insert
-     a copy of this License into the extracted document, and follow this
-     License in all other respects regarding verbatim copying of that
-     document.
-
-  7. AGGREGATION WITH INDEPENDENT WORKS
-
-     A compilation of the Document or its derivatives with other
-     separate and independent documents or works, in or on a volume of a
-     storage or distribution medium, is called an "aggregate" if the
-     copyright resulting from the compilation is not used to limit the
-     legal rights of the compilation's users beyond what the individual
-     works permit.  When the Document is included in an aggregate, this
-     License does not apply to the other works in the aggregate which
-     are not themselves derivative works of the Document.
-
-     If the Cover Text requirement of section 3 is applicable to these
-     copies of the Document, then if the Document is less than one half
-     of the entire aggregate, the Document's Cover Texts may be placed
-     on covers that bracket the Document within the aggregate, or the
-     electronic equivalent of covers if the Document is in electronic
-     form.  Otherwise they must appear on printed covers that bracket
-     the whole aggregate.
-
-  8. TRANSLATION
-
-     Translation is considered a kind of modification, so you may
-     distribute translations of the Document under the terms of section
-     4.  Replacing Invariant Sections with translations requires special
-     permission from their copyright holders, but you may include
-     translations of some or all Invariant Sections in addition to the
-     original versions of these Invariant Sections.  You may include a
-     translation of this License, and all the license notices in the
-     Document, and any Warranty Disclaimers, provided that you also
-     include the original English version of this License and the
-     original versions of those notices and disclaimers.  In case of a
-     disagreement between the translation and the original version of
-     this License or a notice or disclaimer, the original version will
-     prevail.
-
-     If a section in the Document is Entitled "Acknowledgements",
-     "Dedications", or "History", the requirement (section 4) to
-     Preserve its Title (section 1) will typically require changing the
-     actual title.
-
-  9. TERMINATION
-
-     You may not copy, modify, sublicense, or distribute the Document
-     except as expressly provided under this License.  Any attempt
-     otherwise to copy, modify, sublicense, or distribute it is void,
-     and will automatically terminate your rights under this License.
-
-     However, if you cease all violation of this License, then your
-     license from a particular copyright holder is reinstated (a)
-     provisionally, unless and until the copyright holder explicitly and
-     finally terminates your license, and (b) permanently, if the
-     copyright holder fails to notify you of the violation by some
-     reasonable means prior to 60 days after the cessation.
-
-     Moreover, your license from a particular copyright holder is
-     reinstated permanently if the copyright holder notifies you of the
-     violation by some reasonable means, this is the first time you have
-     received notice of violation of this License (for any work) from
-     that copyright holder, and you cure the violation prior to 30 days
-     after your receipt of the notice.
-
-     Termination of your rights under this section does not terminate
-     the licenses of parties who have received copies or rights from you
-     under this License.  If your rights have been terminated and not
-     permanently reinstated, receipt of a copy of some or all of the
-     same material does not give you any rights to use it.
-
-  10. FUTURE REVISIONS OF THIS LICENSE
-
-     The Free Software Foundation may publish new, revised versions of
-     the GNU Free Documentation License from time to time.  Such new
-     versions will be similar in spirit to the present version, but may
-     differ in detail to address new problems or concerns.  See
-     <http://www.gnu.org/copyleft/>.
-
-     Each version of the License is given a distinguishing version
-     number.  If the Document specifies that a particular numbered
-     version of this License "or any later version" applies to it, you
-     have the option of following the terms and conditions either of
-     that specified version or of any later version that has been
-     published (not as a draft) by the Free Software Foundation.  If the
-     Document does not specify a version number of this License, you may
-     choose any version ever published (not as a draft) by the Free
-     Software Foundation.  If the Document specifies that a proxy can
-     decide which future versions of this License can be used, that
-     proxy's public statement of acceptance of a version permanently
-     authorizes you to choose that version for the Document.
-
-  11. RELICENSING
-
-     "Massive Multiauthor Collaboration Site" (or "MMC Site") means any
-     World Wide Web server that publishes copyrightable works and also
-     provides prominent facilities for anybody to edit those works.  A
-     public wiki that anybody can edit is an example of such a server.
-     A "Massive Multiauthor Collaboration" (or "MMC") contained in the
-     site means any set of copyrightable works thus published on the MMC
-     site.
-
-     "CC-BY-SA" means the Creative Commons Attribution-Share Alike 3.0
-     license published by Creative Commons Corporation, a not-for-profit
-     corporation with a principal place of business in San Francisco,
-     California, as well as future copyleft versions of that license
-     published by that same organization.
-
-     "Incorporate" means to publish or republish a Document, in whole or
-     in part, as part of another Document.
-
-     An MMC is "eligible for relicensing" if it is licensed under this
-     License, and if all works that were first published under this
-     License somewhere other than this MMC, and subsequently
-     incorporated in whole or in part into the MMC, (1) had no cover
-     texts or invariant sections, and (2) were thus incorporated prior
-     to November 1, 2008.
-
-     The operator of an MMC Site may republish an MMC contained in the
-     site under CC-BY-SA on the same site at any time before August 1,
-     2009, provided the MMC is eligible for relicensing.
-
-ADDENDUM: How to use this License for your documents
-====================================================
-
-To use this License in a document you have written, include a copy of
-the License in the document and put the following copyright and license
-notices just after the title page:
-
-       Copyright (C)  YEAR  YOUR NAME.
-       Permission is granted to copy, distribute and/or modify this document
-       under the terms of the GNU Free Documentation License, Version 1.3
-       or any later version published by the Free Software Foundation;
-       with no Invariant Sections, no Front-Cover Texts, and no Back-Cover
-       Texts.  A copy of the license is included in the section entitled ``GNU
-       Free Documentation License''.
-
-   If you have Invariant Sections, Front-Cover Texts and Back-Cover
-Texts, replace the "with...Texts."  line with this:
-
-         with the Invariant Sections being LIST THEIR TITLES, with
-         the Front-Cover Texts being LIST, and with the Back-Cover Texts
-         being LIST.
-
-   If you have Invariant Sections without Cover Texts, or some other
-combination of the three, merge those two alternatives to suit the
-situation.
-
-   If your document contains nontrivial examples of program code, we
-recommend releasing these examples in parallel under your choice of free
-software license, such as the GNU General Public License, to permit
-their use in free software.
-
-
-File: wisi.info,  Node: Index,  Prev: GNU Free Documentation License,  Up: Top
-
-Index
-*****
-
-
-
-Tag Table:
-Node: Top920
-Node: Overview1119
-Node: Grammar actions1761
-Node: Navigate actions7174
-Node: Face actions10027
-Node: Indent actions11338
-Node: Indent functions15148
-Node: Indent example17443
-Node: In-parse actions21781
-Node: Project extension23077
-Node: Project files23586
-Node: Selecting projects25006
-Node: Casing exception files29008
-Node: Other project functions29666
-Node: GNU Free Documentation License30424
-Node: Index55580
-
-End Tag Table
-
-
-Local Variables:
-coding: utf-8
-End:
diff --git a/packages/wisi/wisi.texi b/packages/wisi/wisi.texi
deleted file mode 100644
index 3a7d3b3..0000000
--- a/packages/wisi/wisi.texi
+++ /dev/null
@@ -1,812 +0,0 @@
-\input texinfo  @c -*-texinfo-*-
-@settitle Wisi
-
-@copying
-Copyright @copyright{} 1999 - 2020  Free Software Foundation, Inc.
-
-@quotation
-Permission is granted to copy, distribute and/or modify this document
-under the terms of the GNU Free Documentation License, Version 1.3 or
-any later version published by the Free Software Foundation; with no
-Invariant Sections, with the Front-Cover texts being ``A GNU Manual'',
-and with the Back-Cover Texts as in (a) below.  A copy of the license
-is included in the section entitled ``GNU Free Documentation License''.
-
-(a) The FSF's Back-Cover Text is: ``You have the freedom to copy and
-modify this GNU manual.  Buying copies from the FSF supports it in
-developing GNU and promoting software freedom.''
-@end quotation
-@end copying
-
-@dircategory Emacs
-@direntry
-* Wisi: (wisi).         Error-correcting LR parsers and project integration.
-@end direntry
-
-@titlepage
-@sp 10
-@title Wisi Version 3.1.2
-@page
-@vskip 0pt plus 1filll
-@insertcopying
-@end titlepage
-
-@contents
-
-@ifnottex
-@node Top
-@top Top
-
-Wisi Version 3.1.2
-@end ifnottex
-
-@menu
-* Overview::
-* Grammar actions::
-* Project extension::
-* GNU Free Documentation License::
-* Index::
-@end menu
-
-@node Overview
-@chapter Overview
-``wisi'' used to be an acronym, but now it's just a name.
-
-The wisi package provides an elisp interface to an external parser. It
-assumes the parser generator package WisiToken
-(@url{http://stephe-leake.org/ada/wisitoken.html}, implemented in
-Ada), but can use any parser that meets the same API. wisi provides
-several grammar actions, to implement indentation, navigating, and
-syntax highlighting (fontification).
-
-wisi also provides an extension to Emacs @file{project.el}, providing
-operations useful for compilation and cross-reference.
-
-@node Grammar actions
-@chapter Grammar Actions
-
-Grammar actions are specified in the grammar file, in a nonterminal
-declaration. We assume the user is familiar with parser grammars and
-grammar actions. For example, a simple ``if'' statement can be
-declared as:
-
-@example
-if_statement
-  : IF expression THEN statements elsif_list ELSE statements END IF SEMICOLON
-    %((wisi-statement-action [1 statement-start 3 motion 6 motion 10 
statement-end])
-      (wisi-motion-action [1 3 5 6 10])
-      (wisi-indent-action [nil
-                           [(wisi-hanging% ada-indent-broken (* 2 
ada-indent-broken))
-                            ada-indent-broken]
-                           nil
-                           [ada-indent ada-indent] nil nil
-                           [ada-indent ada-indent] nil nil nil]))%
-@end example
-
-The item before @code{:} is the ``left hand side'', or
-``nonterminal''. The list of tokens after @code{:} is the ``right hand
-side''; in general there can be more than one right hand side for each
-nonterminal (separated by @code{|}).
-
-The items enclosed in ``%()%'' are the grammar actions. They are
-specified as list of elisp forms; an earlier version of the wisi
-package generated an elisp parser. We keep the elisp form because it
-is compact, and easier to read and write than the equivalent Ada
-code. The @code{wisi-bnf-generate} tool converts the elisp into the
-required Ada statements.
-
-There are two classes of actions; in-parse and post-parse. WisiToken
-calls these ``semantic checks'' and ``user actions''. The in-parse
-actions are done as parsing procedes; they provide extra checks that
-can cause the parse to fail. Currently the only one provided is
-@code{match-names}; it is used to check that the declaration and end
-names in named Ada blocks are the same (which can aid significantly in
-error correction). In the grammar file, in-parse actions are specified
-in a second @code{%()%} block, which can be omitted if empty. In this
-document, the term ``action'' means ``post-parse action'', we use
-``in-parse action'' unless the meaning is clear from context.
-
-Executing the wisi grammar actions creates text properties in the
-source file; those text properties are then used by elisp code for
-various purposes.
-
-The text properties applied are:
-
-@table @code
-@item wisi-cache
-This should be named @code{wisi-navigate}, but isn't for historical
-reasons (there used to be only one kind of text property).
-
-The property contains a @code{wisi-cache} object, containing:
-
-@table @code
-@item nonterm
-The nonterminal in the grammar production that specified the action
-that produced this text property.
-
-@item token
-A token identifier naming a token in the production right hand side
-containing the text this text property is applied to.
-
-@item last
-The position of the last character in the token, relative to the first
-character (0 indexed). The text property is only applied to the first
-character in the token (mostly for historical reasons).
-
-@item class
-A token class; see the list of possible values in
-@code{wisi-statement-action} below.
-
-@item containing
-A marker pointing to the start of the containing token for this token;
-only @code{nil} for the outermost containing token in a file.
-
-@item prev
-A marker pointing to the previous ``motion token'' in the statement or
-declaration. These are normally language keywords, but can be other
-things.
-
-@item next
-A marker pointing to the next ``motion token'' in the statement or
-declaration.
-
-@item end
-A marker pointing to the end of the statement or declaration.
-
-@end table
-
-wisi provides motion commands for going to the various markers.
-
-@item wisi-name
-Contains no data, applied to a ``name'' of some sort. wisi provides
-commands for finding the next/previous name, and returning the
-text. Useful for the names of subprograms, which can then be used to
-build a completion table; see @code{wisi-xref-identifier-completion-table}.
-
-@item font-lock-face
-The standard font-lock property, specifying the face for the
-text.
-
-Some major modes do not use this for simple keywords; they use
-font-lock regular expressions instead. One reason for this
-is so keywords are still highlighted when the parser fails, which
-can happen if there are severe syntax errors.
-
-Other items, like function and package names, are typically marked
-with @code{font-lock-face} by the parser.
-
-@item fontified
-Another standard font-lock text property; applied whenever
-@code{font-lock-face} is.
-
-@item wisi-indent
-Contains the indent (in characters) for the next line; applied to
-the newline character on the preceding line. The first line in a
-buffer is assumed to have indent 0.
-
-@end table
-
-Each action is classified as one of @code{navigate, face, indent,
-in-parse}; when actions are executed, only one of the first three classes
-is executed (in-parse is always executed). This reflects the reasons
-the parser is run; to figure out how to go somehere (end of current
-statement, start of current procedure, etc), to apply faces for syntax
-highlighting, or to indent the code.
-
-@menu
-* Navigate actions::
-* Face actions::
-* Indent actions::
-* In-parse actions::
-@end menu
-
-@node Navigate actions
-@section Navigate actions
-@table @code
-@item wisi-statement-action [TOKEN CLASS ...]
-The argument is a vector; alternating items are a token index (an
-integer or label indicating a token in the right hand side) and a
-``token class''; one of:
-
-@table @code
-@item motion
-Create a @code{wisi-cache} text property on the token, for use in a
-subsequent @code{wisi-motion-action}.
-
-@item statement-end
-Create a @code{wisi-cache} text property on the token, enter a pointer
-to it in the other @code{wisi-cache} objects in the statement or
-declaration.
-
-@item statement-start
-Create a @code{wisi-cache} text property on the token, enter a pointer
-to it in the other @code{wisi-cache} objects (in the @code{containing}
-slot) in the statement or declaration.
-
-@item statement-override
-Same as @code{statement-start}; marks the token to be used as the
-statement start if the first token is optional.
-
-@item misc
-Create a @code{wisi-cache} text property on the token, to be used for
-some other purpose. It is good style to indicate the purpose in a
-comment.
-
-For example, ada-mode uses a 'misc' property on left parentheses that
-start a subprogram parameter list; this distinquishes them from other
-left parentheses, and makes it possible to automatically call
-@code{ada-format-paramlist} to format the
-parameter list, instead of using the standard Emacs @code{align}.
-
-@end table
-
-@item wisi-motion-action [TOKEN ...]
-The argument is a vector, where each element is either a token index
-or a vector [INDEX ID].
-
-Each terminal token must already have a @code{wisi-cache} created by a
-@code{wisi-statement-action} (this is checked at action execution, not
-during grammar generation). This action sets the @code{prev, next}
-slots for the chain of tokens, creating a chain of motion tokens.
-
-If TOKEN is a nonterminal without an ID specified, the @code{wisi-cache}
-must be on the first token in the nonterminal, and it is assumed to
-have a valid pointer in the @code{next} slot, indicating a chain of
-motion tokens. That chain is linked into the chain for the current
-right hand side.
-
-If TOKEN is a nonterminal with an ID, the region contained by the
-nonterminal is searched for all @code{wisi-cache} with that token ID,
-and for each one where prev/next is not already set, it is linked into
-the motion chain.
-
-Note that the ``search'' described here is done in the parser process, on
-a tree data structure containing the data that will eventually be
-stored in Emacs text properties.
-
-@item wisi-name-action TOKEN
-TOKEN is a token index. Create a @code{wisi-name} text property on the
-token.
-
-@end table
-
-@node Face actions
-@section Face actions
-@table @code
-@item wisi-face-mark-action [INDEX CLASS ...]
-The argument is a vector; alternating elements form pairs of INDEX
-CLASS, where class is one of @code{prefix, suffix}.
-
-Mark the tokens as part of a compound name, for use by later face
-actions.
-
-@item wisi-face-apply-action [TOKEN PREFIX-FACE SUFFIX-FACE ...]
-The argument is a vector; triples of items specify TOKEN,
-PREFIX-FACE, SUFFIX-FACE. The faces are the elisp names of face
-objects (which must declared by an @code{%elisp_face} declaration).
-
-If the token is a nonterminal, and it has been marked by a previous
-@code{wisi-face-mark-action}, the specified faces are applied to the
-prefix and suffix in the token as @code{font-lock-face} text
-properties.
-
-If the token is a terminal, or a non-terminal with no face mark, the
-suffix face is applied to the entire text contained by the token.
-
-@item wisi-face-apply-list-action [TOKEN PREFIX-FACE SUFFIX-FACE ...]
-Similar to ’wisi-face-apply-action’, but applies faces to all tokens
-marked by @code{wisi-face-mark-action} in each indicated production
-token, and does not apply a face if there are no such marks.
-
-@end table
-
-@node Indent actions
-@section Indent actions
-
-Indents are computed for each line in a cumulative way as the grammar
-actions are executed. Initially, each indent is set to @code{nil},
-which means ``not computed''; this is not the same as the value
-@code{0}. The grammar actions are executed in a bottom-up fashion; low
-level productions are executed before higher level ones. In general,
-the indent action for a production specifies a ``delta indent''; the
-indent is incremented by that amount. When all productions have been
-processed, the indent has been computed for all lines.
-
-Indents are often given as a function call; the arguments to the
-function can be other function calls, or integer
-expressions. @code{wisitoken-bnf-generate} supports only simple integer
-expressions; those using integers, integer-valued variables,
-parenthesis, + (plus), - (minus), and * (multiply).
-
-@table @code
-@item wisi-indent-action [INDENT ...]
-The argument is a vector, giving an indent for each token in the
-production right-hand side.
-
-For terminals, the indents only have meaning, and are only computed,
-if the token is the first on a line. For nonterminals where the indent
-is not a variant of @code{wisi-hanging}, the indent is only computed
-if the first terminal token in the nonterminal is the first on a
-line. See @code{wisi-hanging} in @ref{Indent functions} for the
-remaining case.
-
-An indent can have several forms.  In the descriptions below, the
-``current token'' is given by the position of the indent expression in
-the @code{wisi-indent-action} argument list.
-
-@table @asis
-@item An integer
-This gives a delta indent; it is added to the total indent for the
-line.
-
-@item A variable name
-The name is translated to an Ada identifier by replacing ``-'' with
-``_'', and applying @code{Camel_Case}. The translated name must
-identify a directly visible run-time Ada integer variable; this is
-checked at Ada compile time. It provides an integer delta indent.
-
-For example, in Ada two indent variable names are @code{ada-indent}
-and @code{ada-indent-broken}, giving the basic ident, and the
-continuation line indent. They are runtime variables so different
-projects can specify them as part of a coding standard.
-
-@item A function call
-A function that computes a delta indent. See @ref{Indent functions}.
-
-@item [CODE-INDENT , COMMENT-INDENT]
-A vector giving separate indents for code and comments.
-
-Normally, the indent for trailing comments (on lines with no code,
-after all code in the token) is given by the indent of the following
-token in the production. When the current token is the last, or the
-following tokens may be empty, or the indent of the following token
-would be wrong for some reason (for example, it is a block end), the
-comment indent may be specified separately. If it is not specified,
-and the indent from the next token is not available, the indent for
-the current token is used for code and comments.
-
-Comment lines that are not trailing are indented by CODE-INDENT.
-
-@item (label . INDENT)
-If token labels are used in a right hand side, they must be given
-explicitly in the indent arguments, using he lisp ``cons''
-syntax. Labels are normally only used with EBNF grammars, which expand
-into multiple right hand sides, with optional tokens simply left
-out. Explicit labels on the indent arguments allow them to be left out
-as well.
-
-@end table
-
-@end table
-
-@menu
-* Indent functions::
-* Indent example::
-@end menu
-
-@node Indent functions
-@subsection Indent functions
-@table @code
-@item wisi-anchored TOKEN OFFSET
-Sets the indent for the current token to be OFFSET (an integer
-expression) from the start of TOKEN (a token index); the
-current token is ``anchored to'' TOKEN.
-
-@item wisi-anchored* TOKEN OFFSET
-Sets the indent for the current token to be OFFSET from the start of
-TOKEN, but only if TOKEN is the first token on a line; otherwise no indent
-
-@item wisi-anchored*- TOKEN OFFSET
-Sets the indent for the current token to be OFFSET from the start of
-TOKEN, but only if TOKEN is the first token on a line and the indent
-for the current token accumulated so far is nil.
-
-@item wisi-anchored% TOKEN OFFSET
-If there is an opening parenthesis containing TOKEN in the line
-containing TOKEN, set the current indent to OFFSET from that
-parenthesis. Otherwise, OFFSET gives an indent delta.
-
-@item wisi-anchored%- TOKEN OFFSET
-Same as @code{wisi-anchored%}, but only if the current token
-accumulated indent is nil.
-
-@item wisi-hanging DELTA-1 DELTA-2
-The current token is assumed to be a nonterminal. If the text it
-contains spans multiple lines, use DELTA-1 for the first line, DELTA-2
-for the rest. If the current token is only on one line, use DELTA-1.
-
-DELTA-1 and DELTA-2 can be any IDENT expression, except a variant of
-@code{wisi-hanging}.
-
-@item wisi-hanging% DELTA-1 DELTA-2
-Similar to @code{wisi-hanging}; if the first terminal token in the
-current nonterminal is the first token on the first line, use DELTA-1
-for the first line and DELTA-2 for the rest. Otherwise, use DELTA-1
-for all lines.
-
-@item wisi-hanging%- DELTA-1 DELTA-2
-Same as @code{wisi-hanging%}, except applied only if the current token
-accumulated indent is nil.
-
-@item Language-specific function
-Language-specific indent functions are specified by an
-@code{%elisp_indent} declaration in the grammar file. Each function
-specifies how many arguments it accepts; this is checked at action
-runtime, not during grammar generation. Each argument is an INDENT as
-described above, or a token ID prefixed by @code{'} (to allow
-distinguishing token IDs from variable names).
-@end table
-
-@node Indent example
-@subsection Indent example
-
-The example @code{if_statement} grammar nonterminal is:
-
-@example
-if_statement
-  : IF expression THEN statements elsif_list ELSE statements END IF SEMICOLON
-    %((wisi-indent-action [nil
-                           [(wisi-hanging% ada-indent-broken (* 2 
ada-indent-broken))
-                            ada-indent-broken]
-                           nil
-                           [ada-indent ada-indent] nil nil
-                           [ada-indent ada-indent] nil nil nil]))%
-@end example
-
-We trace how the indent is computed for this sample Ada code:
-
-@example
- 1: if A < B and
- 2:   C < D
- 3:   --  comment on expression
- 4: then
- 5:    if E then
- 6:       Do_E;
- 7:       -- comment on statement
- 8:    elsif F then
- 9:       G := A + Compute_Something
-10:         (arg_1, arg_2);
-11:    end if;
-12: end if;
-@end example
-
-First, the indent for the lower-level nonterminals (@code{expression,
-statements, elsif_list}) are computed. Assume they set the indent for
-line 10 to 2 (for the hanging expression) and leave the rest at nil.
-
-Next, the action for the inner @code{if_statement} is executed. Most
-of the tokens specify an indent of @code{nil}, which means the current
-accumulated indent is not changed. For the others, the action is as
-follows:
-
-@table @code
-@item expression:
-The expression @code{E} is contained on one line, and it is not the
-first token on that line, so the indent for line 5 is not changed.
-
-@item statements: [ada-indent ada-indent]
-This specifies separate indents for code and trailing comments,
-because otherwise the trailing comments would be indented with the
-following @code{THEN}; instead they are indented with the expression
-code; see the comment on line 7.
-
-Here @code{ada-indent} is 3, so the indent for lines 6 and 7 (for the
-first occurence of @code{statments}) is
-incremented from @code{nil} to @code{3}.
-
-For the second occurence of @code{statements}, line 9 is incremented
-from @code{nil} to @code{3}, and line 10 from @code{2} to @code{5}.
-@end table
-
-At this point, the accumulated indents are (the indent is given after
-the line number):
-@example
- 1: nil : if A < B and
- 2: nil :   C < D
- 3: nil :   --  comment on expression
- 4: nil : then
- 5: nil :    if E then
- 6:   3 :       Do_E;
- 7:   3 :       -- comment on statement
- 8: nil :    elsif F then
- 9:   3 :       G := A + Compute_Something
-10:   5 :         (arg_1, arg_2);
-11: nil :    end if;
-12: nil : end if;
-@end example
-
-Then the action is executed for the outer @code{if_statement}:
-
-@table @code
-@item expression: [(wisi-hanging% ada-indent-broken (* 2 ada-indent-broken)) 
ada-indent-broken]
-This specifies separate indents for code and trailing comments,
-because otherwise the trailing comments would be indented with the
-following @code{THEN}; instead they are indented with the expression
-code; see the comment on line 3.
-
-In this case, @code{wisi-hanging%} returns DELTA-1, which is
-@code{ada-indent-broken}, which is 2. So the indent for line 2 is
-incremented from @code{nil} to @code{2}.
-
-The indent for line 3 is also incremented from @code{nil} to @code{2}.
-
-@item statements: [ada-indent ada-indent]
-Here there is only one statement; the nested @code{if_statement}. The
-indent for lines 5 .. 11 are each incremented by 3.
-@end table
-
-The final result is:
-@example
- 1: nil : if A < B and
- 2:   2 :   C < D
- 3:   2 :   --  comment on expression
- 4: nil : then
- 5:   3 :    if E then
- 6:   6 :       Do_E;
- 7:   6 :       -- comment on statement
- 8:   3 :    elsif F then
- 9:   6 :       G := A + Compute_Something
-10:   8 :         (arg_1, arg_2);
-11:   6 :    end if;
-12: nil : end if;
-@end example
-
-In a full grammar, the top production should specify an indent of 0,
-not nil, for tokens that are not indented; then every line will have a
-non-nil indent. However, in normal operation a nil indent is treated
-as 0; the @code{wisi-indent} text property is not set for lines that
-have nil indent, and @code{wisi-indent-region} detects that and uses 0
-for the indent. You can set the variable @code{wisi-debug} to a value
-> 0 to signal an error for nil indents; this is useful to catch indent
-errors during grammar development.
-
-@node In-parse actions
-@section In-parse actions
-@table @code
-
-@item wisi-propagate-name TOKEN
-The argument is a token index. Set the @code{name} component of the
-left-hand-side parse-time token object to the @code{name} component of
-the identified token, if it is not empty. Otherwise use the
-@code{byte_region} component.
-
-@item wisi-merge-name FIRST-TOKEN, LAST-TOKEN
-The arguments are token indices, giving a range of
-tokens. LAST-TOKEN may be omitted if it is the same as FIRST-TOKEN.
-
-Set the @code{name} component of the left-hand-side to the merger of
-the @code{name} or @code{byte-region} components of the identified tokens.
-
-@item wisi-match-name START-TOKEN END-TOKEN
-The arguments are token indices. Compare the text contained by the
-@code{name} (or @code{byte_region} if @code{name} is empty) token
-components for START-TOKEN and END-TOKEN; signal a parse error if they
-are different.
-
-The behavior when a name is missing is determined by the runtime
-language variable given in the @code{%end_names_optional_option}
-declaration; if True, a missing name that is supposed to match a
-present name is an error. Both names missing is not an error (assuming
-that is allowed by the grammar).
-
-@end table
-
-@node Project extension
-@chapter Project extension
-wisi defines the @code{cl-defstuct} @code{wisi-prj}, with operations
-suitable for compilation and cross-reference.
-
-In order to use wisi projects, the user must write project files and
-customize @code{project-find-functions} and
-@code{xref-backend-functions}.
-
-@menu
-* Project files::
-* Selecting projects::
-* Casing exception files::
-* Other project functions::
-@end menu
-
-@node Project files
-@section Project files
-
-Project file names must have an extension given by
-@code{wisi-prj-file-extensions} (default @file{.adp, .prj}).
-
-Project files have a simple syntax; they may be edited directly. Each
-line specifies a project variable name and its value, separated by
-``='':
-
-@example
-src_dir=/Projects/my_project/src_1
-src_dir=/Projects/my_project/src_2
-@end example
-
-There must be no space between the variable name and ``='', and no
-trailing spaces after the value.
-
-Any line that does not have an ``='' is a comment.
-
-Some variables (like @code{src_dir}) are lists; each line in the
-project file specifies one element of the list. The value on the last
-line is the last element in the list.
-
-A variable name that starts with @code{$} is set as a process
-environment variable, for processes launched from Emacs for the
-project.
-
-In values, process environment variables can be referenced
-using the normal @code{$var} syntax.
-
-In values, relative file names are expanded relative to the
-directory containing the project file.
-
-Here is the list of project variables defined by wisi; major modes may
-add more.
-
-@table @asis
-@item @code{casing}         [slot: @code{case-exception-files}]
-List of files containing casing exceptions. @xref{Casing exception files}.
-
-@item @code{src_dir}        [slot: @code{source-path}]
-A list of directories to search for source files.
-
-@end table
-
-@node Selecting projects
-@section Selecting projects
-The current project can either be indicated by a global variable
-(called a ``selected project''), or depend on the current buffer.
-
-In addition, the project file can be parsed each time it is needed, or
-the result cached to improve response time,
-
-One reason to use a selected project is to handle a hierarchy of
-projects; if projects B and C both depend on library project A, then
-when in a file of project A, there is no way to determine which of the
-three projects to return. So the user must indicate which is active,
-by using one of @code{wisi-prj-select-file} or
-@code{wisi-prj-select-cache}.
-
-In addition, if changing from one project to another requires setting
-global resources that must also be unset (such as a syntax propertize
-hook or compilation filter hook), then the project should define
-@code{wisi-prj-deselect} in addition to @code{wisi-prj-select}. Such
-projects require having a selected current project, so it can be
-deselected before a new one is selected. One example of such projects
-is ada-mode.
-
-One way to declare each project is to add a Local Variables section
-in the main Makefile for the project; when the Makefile is first
-visited, the project is declared. In the examples here, we assume
-that approach is used; each gives an :eval line.
-
-Note that @code{wisi-prj-current-parse} and
-@code{wisi-prj-current-cached} always succeed after some project is
-selected; no functions after them on @code{project-find-functions} will
-be called. That's why the depth is 90 for those in the examples.
-
-@table @asis
-@item No caching, current project depends on current buffer
-
-@example
-(add-hook 'project-find-functions #'wisi-prj-find-dominating-parse 0)
-
-:eval (wisi-prj-set-dominating "foo.prj" (foo-prj-default "prj-name"))
-@end example
-
-@code{wisi-prj-set-dominating} declares the name of a project file with a
-default project object, and ensures that the current buffer file name
-is in @code{wisi-prj--dominating}.
-
-@code{wisi-prj-find-dominating-parse} looks for the filenames in
-@code{wisi-prj--dominiating} in the parent directories of the current
-buffer. When one is found, the associated project file is parsed,
-using the default project object to dispatch to the appropriate
-parsers. Then the final project object is returned.
-
-@item Caching, current project depends on current buffer
-
-@example
-(add-hook 'project-find-functions #'wisi-prj-find-dominating-cached 0)
-
-:eval (wisi-prj-cache-dominating "foo.prj" (foo-prj-default "prj-name"))
-@end example
-
-@code{wisi-prj-cache-dominating} declares the project file, parses it,
-and saves the project object in a cache indexed by the absolute
-project file name.
-
-@code{wisi-prj-find-dominating-cached} finds the dominating
-project file, and retrieves the object from the cache.
-
-@item No caching, last selected project is current
-
-@example
-(add-hook 'project-find-functions #'wisi-prj-current-parse 90)
-
-:eval: (wisi-prj-select-file <prj-file> (foo-prj-default "prj-name"))
-@end example
-
-@code{wisi-prj-select-file} sets the project file as the current
-project, and saves the default project object.
-
-@code{wisi-prj-current-parse} parses the current project file, using
-the saved default project object, and returns the project object.
-
-@item Caching, last selected project is current
-
-@example
-(add-hook 'project-find-functions #'wisi-prj-current-cached 90)
-
-:eval: (wisi-prj-select-cache <prj-file> (foo-prj-default "prj-name"))
-@end example
-
-@code{wisi-prj-select-cache} parses the project file, caches the
-project object.
-
-@code{wisi-prj-current-cached} returns the cached current project
-object.
-
-@end table
-
-In addition, the user should set @code{xref-backend-functions}. Currently,
-there is only one choice for wisi projects:
-
-@example
-(add-to-list 'xref-backend-functions #'wisi-prj-xref-backend 90)
-@end example
-
-@code{wisi-prj-xref-backend} returns the current wisi project object.
-
-@node Casing exception files
-@section Casing exception files
-Each line in a case exception
-file specifies the casing of one word or word fragment. If an
-exception is defined in multiple files, the first occurrence is used.
-
-If the word starts with an asterisk (@code{*}), it defines the casing
-of a word fragment (or ``substring''); part of a word between two
-underscores or word boundary.
-
-For example:
-
-@example
-DOD
-*IO
-GNAT
-@end example
-
-The word fragment @code{*IO} applies to any word containing ``_io'';
-@code{Text_IO}, @code{Hardware_IO}, etc.
-
-@node Other project functions
-@section Other project functions
-
-@table @code
-@item wisi-refresh-prj-cache (not-full)
-Refreshes all cached data in the project, and re-selects the
-project. If NOT-FULL is non-nil, slow refresh operations are skipped.
-
-This reparses the project file, and any cross reference information.
-
-@item wisi-prj-select-dominating (dominating-file)
-  Find a wisi-prj matching DOMINATING-FILE (defaults to the current
-buffer file). If the associated project is current, do nothing. If it
-is not current, select it.
-
-This is useful before running `compilation-start', to ensure the correct
-project is current.
-
-@end table
-
-@node GNU Free Documentation License
-@appendix GNU Free Documentation License
-@include doclicense.texi
-
-@node Index,  , GNU Free Documentation License, Top
-@unnumbered Index
-
-@printindex fn
-
-@bye
diff --git a/packages/wisi/wisitoken-bnf-generate.adb 
b/packages/wisi/wisitoken-bnf-generate.adb
deleted file mode 100644
index 821ef6f..0000000
--- a/packages/wisi/wisitoken-bnf-generate.adb
+++ /dev/null
@@ -1,634 +0,0 @@
---  Abstract :
---
---  Parser for Wisi grammar files, producing Ada source
---  files for a parser.
---
---  Copyright (C) 2012 - 2015, 2017 - 2020 Free Software Foundation, Inc.
---
---  The WisiToken package is free software; you can redistribute it
---  and/or modify it under terms of the GNU General Public License as
---  published by the Free Software Foundation; either version 3, or
---  (at your option) any later version. This library 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.
---
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-with Ada.Command_Line;
-with Ada.Directories;
-with Ada.Exceptions;
-with Ada.Real_Time;
-with Ada.Strings.Fixed;
-with Ada.Strings.Maps;
-with Ada.Strings.Unbounded;
-with Ada.Text_IO;
-with GNAT.Traceback.Symbolic;
-with WisiToken.BNF.Generate_Utils;
-with WisiToken.BNF.Output_Ada;
-with WisiToken.BNF.Output_Ada_Common;
-with WisiToken.BNF.Output_Ada_Emacs;
-with WisiToken.BNF.Output_Elisp_Common;
-with WisiToken.Generate.LR.LALR_Generate;
-with WisiToken.Generate.LR.LR1_Generate;
-with WisiToken.Generate.Packrat;
-with WisiToken.Parse.LR.Parser_No_Recover; -- for reading BNF file
-with WisiToken.Productions;
-with WisiToken.Syntax_Trees;
-with WisiToken.Text_IO_Trace;
-with WisiToken_Grammar_Runtime;
-with Wisitoken_Grammar_Actions;
-with Wisitoken_Grammar_Main;
-procedure WisiToken.BNF.Generate
-is
-   procedure Put_Usage
-   is
-      use Ada.Text_IO;
-      First : Boolean := True;
-   begin
-      Put_Line (Standard_Error, "version 2.1"); -- matches release version in 
Docs/wisitoken.html
-      Put_Line (Standard_Error, "wisitoken-bnf-generate [options] {wisi 
grammar file}");
-      Put_Line (Standard_Error, "Generate source code implementing a parser 
for the grammar.");
-      New_Line (Standard_Error);
-      Put_Line (Standard_Error, "The following grammar file directives control 
parser generation:");
-      Put_Line (Standard_Error,
-                "%generate <algorithm> <output language> [<lexer>] 
[<interface>] [text_rep]");
-      Put_Line (Standard_Error, "   specify one of each generate parameter. 
May be repeated.");
-      Put (Standard_Error, "   algorithm: ");
-      for I of Generate_Algorithm_Image loop
-         if First then
-            First := False;
-         else
-            Put (Standard_Error, " | ");
-         end if;
-         Put (Standard_Error, I.all);
-      end loop;
-      New_Line (Standard_Error);
-
-      Put (Standard_Error, "   output language: ");
-      First := True;
-      for I of Output_Language_Image loop
-         if First then
-            First := False;
-         else
-            Put (Standard_Error, " | ");
-         end if;
-         Put (Standard_Error, I.all);
-      end loop;
-      New_Line (Standard_Error);
-
-      Put_Line (Standard_Error, "   interface: interface Process | Module");
-      Put_Line (Standard_Error, "      only valid with Ada_Emacs:");
-      Put_Line (Standard_Error, "      Process is for an external subprocess 
communicating with Emacs.");
-      Put_Line (Standard_Error, "      Module  is for a dynamically loaded 
Emacs module.");
-      Put (Standard_Error, "   lexer: ");
-      First := True;
-      for I of Output_Language_Image loop
-         if First then
-            First := False;
-         else
-            Put (Standard_Error, " | ");
-         end if;
-         Put (Standard_Error, I.all);
-      end loop;
-      New_Line (Standard_Error);
-      Put_Line
-        (Standard_Error, "   text_rep: output LR parse table in a text file, 
not as source code; for large tables");
-
-      New_Line (Standard_Error);
-      Put_Line (Standard_Error, "options:");
-      Put_Line (Standard_Error, "  --help: show this help");
-
-      --  verbosity meaning is actually determined by output choice;
-      --  they should be consistent with this description.
-      Put_Line
-        (Standard_Error, "  -v <EBNF level> <Table level> <Minimal_Complete 
level>: sets verbosity (default 0):");
-      Put_Line (Standard_Error, "     0 - only error messages to standard 
error");
-      Put_Line (Standard_Error, "     1 - add diagnostics to standard out");
-      Put_Line (Standard_Error, "     2 - more diagnostics to standard out, 
ignore unused tokens, unknown conflicts");
-      Put_Line (Standard_Error, "  --generate ...: override grammar file 
%generate directive");
-      Put_Line (Standard_Error, "  --output_bnf <file_name> : output 
translated BNF source to file_name");
-      Put_Line (Standard_Error, "  --suffix <string>; appended to grammar file 
name");
-      Put_Line (Standard_Error, "  --ignore_conflicts; ignore excess/unknown 
conflicts");
-      Put_Line (Standard_Error,
-                "  --test_main; generate standalone main program for running 
the generated parser, modify file names");
-      Put_Line (Standard_Error, "  --time; output execution time of various 
stages");
-
-   end Put_Usage;
-
-   Language_Name         : Ada.Strings.Unbounded.Unbounded_String; -- The 
language the grammar defines
-   Output_File_Name_Root : Ada.Strings.Unbounded.Unbounded_String;
-   Suffix                : Ada.Strings.Unbounded.Unbounded_String;
-   BNF_File_Name         : Ada.Strings.Unbounded.Unbounded_String;
-   Output_BNF            : Boolean := False;
-   Ignore_Conflicts      : Boolean := False;
-   Test_Main             : Boolean := False;
-
-   Command_Generate_Set : Generate_Set_Access; -- override grammar file 
declarations
-
-   Trace          : aliased WisiToken.Text_IO_Trace.Trace 
(Wisitoken_Grammar_Actions.Descriptor'Access);
-   Input_Data     : aliased WisiToken_Grammar_Runtime.User_Data_Type;
-   Grammar_Parser : WisiToken.Parse.LR.Parser_No_Recover.Parser;
-
-   procedure Use_Input_File (File_Name : in String)
-   is
-      use Ada.Strings.Unbounded;
-      use Ada.Text_IO;
-   begin
-      Output_File_Name_Root := +Ada.Directories.Base_Name (File_Name) & Suffix;
-
-      Wisitoken_Grammar_Main.Create_Parser
-        (Parser    => Grammar_Parser,
-         Trace     => Trace'Unchecked_Access,
-         User_Data => Input_Data'Unchecked_Access);
-
-      Grammar_Parser.Lexer.Reset_With_File (File_Name);
-
-      declare
-         Language_Name_Dir   : constant Integer := Ada.Strings.Fixed.Index
-           (File_Name, Ada.Strings.Maps.To_Set ("/\"), Going => 
Ada.Strings.Backward);
-         Language_Name_Ext   : constant Integer := Ada.Strings.Fixed.Index 
(File_Name, ".wy");
-      begin
-         Language_Name := +WisiToken.BNF.Output_Elisp_Common.Elisp_Name_To_Ada
-           (File_Name
-              ((if Language_Name_Dir = 0
-                then File_Name'First
-                else Language_Name_Dir + 1) ..
-                 Language_Name_Ext - 1),
-            Append_ID => False,
-            Trim      => 0);
-      end;
-   exception
-   when Name_Error | Use_Error =>
-      raise Name_Error with "input file '" & File_Name & "' could not be 
opened.";
-   end Use_Input_File;
-
-begin
-   declare
-      use Ada.Command_Line;
-      Arg_Next : Integer := 1;
-   begin
-      loop
-         exit when Argument (Arg_Next)(1) /= '-';
-
-         --   --help, -v first, then alphabetical
-
-         if Argument (Arg_Next) = "--help" then
-            Put_Usage;
-            return;
-
-         elsif Argument (Arg_Next) = "-v" then
-            Arg_Next  := Arg_Next + 1;
-            WisiToken.Trace_Generate_EBNF := Integer'Value (Argument 
(Arg_Next));
-            Arg_Next  := Arg_Next + 1;
-            WisiToken.Trace_Generate_Table := Integer'Value (Argument 
(Arg_Next));
-            Arg_Next  := Arg_Next + 1;
-            WisiToken.Trace_Generate_Minimal_Complete := Integer'Value 
(Argument (Arg_Next));
-            Arg_Next  := Arg_Next + 1;
-
-         elsif Argument (Arg_Next) = "--ignore_conflicts" then
-            Ignore_Conflicts := True;
-            Arg_Next         := Arg_Next + 1;
-
-         elsif Argument (Arg_Next) = "--generate" then
-            Arg_Next  := Arg_Next + 1;
-            declare
-               Tuple : Generate_Tuple;
-               Done  : Boolean := False;
-            begin
-               begin
-                  Tuple.Gen_Alg := Generate_Algorithm'Value (Argument 
(Arg_Next));
-                  Arg_Next     := Arg_Next + 1;
-               exception
-               when Constraint_Error =>
-                  raise User_Error with "invalid value for 
generator_algorithm: '" & Argument (Arg_Next) & ";";
-               end;
-               if Tuple.Gen_Alg /= None then
-                  begin
-                     Tuple.Out_Lang := To_Output_Language (Argument 
(Arg_Next));
-                     Arg_Next       := Arg_Next + 1;
-                  end;
-
-                  loop
-                     exit when Done;
-                     declare
-                        Text : constant String := Argument (Arg_Next);
-                     begin
-                        if Text = "text_rep" then
-                           Tuple.Text_Rep := True;
-                           Arg_Next := Arg_Next + 1;
-
-                        elsif (for some I of Lexer_Image => To_Lower (Text) =  
I.all) then
-                           Tuple.Lexer := To_Lexer (Text);
-                           Arg_Next := Arg_Next + 1;
-
-                        elsif (for some I in Valid_Interface =>
-                                 To_Lower (Text) = To_Lower 
(Valid_Interface'Image (I)))
-                        then
-                           Tuple.Interface_Kind := 
WisiToken.BNF.Valid_Interface'Value (Text);
-                           Arg_Next := Arg_Next + 1;
-
-                        else
-                           Done := True;
-                        end if;
-                     end;
-                  end loop;
-               end if;
-               Add (Command_Generate_Set, Tuple);
-            end;
-
-         elsif Argument (Arg_Next) = "--output_bnf" then
-            Output_BNF    := True;
-            Arg_Next      := Arg_Next + 1;
-            BNF_File_Name := +Argument (Arg_Next);
-            Arg_Next      := Arg_Next + 1;
-
-         elsif Argument (Arg_Next) = "--suffix" then
-            Arg_Next := Arg_Next + 1;
-            Suffix   := +Argument (Arg_Next);
-            Arg_Next := Arg_Next + 1;
-
-         elsif Argument (Arg_Next) = "--test_main" then
-            Arg_Next  := Arg_Next + 1;
-            Test_Main := True;
-
-         elsif Argument (Arg_Next) = "--time" then
-            Arg_Next := Arg_Next + 1;
-            WisiToken.Trace_Time := True;
-
-         else
-            raise User_Error with "invalid argument '" & Argument (Arg_Next) & 
"'";
-         end if;
-      end loop;
-
-      Use_Input_File (Argument (Arg_Next));
-
-      if Arg_Next /= Argument_Count then
-         raise User_Error with "arg count" & Integer'Image (Argument_Count) &
-           " different from expected count" & Integer'Image (Arg_Next);
-      end if;
-   end;
-
-   begin
-      Grammar_Parser.Parse;
-   exception
-   when WisiToken.Syntax_Error =>
-      Grammar_Parser.Put_Errors;
-      raise;
-   when E : WisiToken.Parse_Error =>
-      WisiToken.Generate.Put_Error (Ada.Exceptions.Exception_Message (E));
-      raise;
-   end;
-
-   declare
-      use all type Ada.Strings.Unbounded.Unbounded_String;
-      use Ada.Text_IO;
-
-      Generate_Set    : Generate_Set_Access;
-      Multiple_Tuples : Boolean;
-
-      Lexer_Done : Lexer_Set := (others => False);
-
-      --  In general, all of the data in Generate_Utils.Generate_Data
-      --  depends on the generate tuple parameters. However, if
-      --  'If_Lexer_Present' is false, then they don't depend on the lexer,
-      --  and if 'If_Parser_Present' is false, then they don't depend on the
-      --  Gen_Alg, except for the parser table. But it's not worth trying to
-      --  cache results in those cases; they only happen in test grammars,
-      --  which are small.
-
-      procedure Parse_Check
-        (Lexer  : in Lexer_Type;
-         Parser : in Generate_Algorithm;
-         Phase  : in WisiToken_Grammar_Runtime.Action_Phase)
-      is
-         use all type Ada.Containers.Count_Type;
-         use all type WisiToken_Grammar_Runtime.Action_Phase;
-         use all type WisiToken_Grammar_Runtime.Meta_Syntax;
-      begin
-         Input_Data.User_Parser := Parser;
-         Input_Data.User_Lexer  := Lexer;
-         --  Specifying the parser and lexer can change the parsed grammar, due
-         --  to %if {parser | lexer}.
-
-         Input_Data.Reset; -- only resets Other data
-
-         Input_Data.Phase := Phase;
-         Grammar_Parser.Execute_Actions;
-
-         case Phase is
-         when Meta =>
-            case Input_Data.Meta_Syntax is
-            when Unknown =>
-               Input_Data.Meta_Syntax := BNF_Syntax;
-
-            when BNF_Syntax =>
-               null;
-
-            when EBNF_Syntax =>
-               declare
-                  Tree  : WisiToken.Syntax_Trees.Tree renames 
Grammar_Parser.Parsers.First_State_Ref.Tree;
-               begin
-                  if Trace_Generate_EBNF > Outline then
-                     Ada.Text_IO.Put_Line ("Translate EBNF tree to BNF");
-                  end if;
-
-                  if Trace_Generate_EBNF > Detail then
-                     Ada.Text_IO.Put_Line ("EBNF tree:");
-                     Tree.Print_Tree
-                       (Wisitoken_Grammar_Actions.Descriptor,
-                        Image_Action => 
WisiToken_Grammar_Runtime.Image_Grammar_Action'Access);
-                  end if;
-
-                  WisiToken_Grammar_Runtime.Translate_EBNF_To_BNF (Tree, 
Input_Data);
-
-                  if Trace_Generate_EBNF > Detail then
-                     Ada.Text_IO.New_Line;
-                     Ada.Text_IO.Put_Line ("BNF tree:");
-                     Tree.Print_Tree
-                       (Wisitoken_Grammar_Actions.Descriptor,
-                        Image_Action => 
WisiToken_Grammar_Runtime.Image_Grammar_Action'Access);
-                  end if;
-
-                  if Output_BNF then
-                     WisiToken_Grammar_Runtime.Print_Source (-BNF_File_Name, 
Tree, Input_Data);
-                  end if;
-
-                  if WisiToken.Generate.Error then
-                     raise WisiToken.Grammar_Error with "errors during 
translating EBNF to BNF: aborting";
-                  end if;
-               end;
-            end case;
-
-         when Other =>
-            if Input_Data.Rule_Count = 0 or Input_Data.Tokens.Rules.Length = 0 
then
-               raise WisiToken.Grammar_Error with "no rules";
-            end if;
-         end case;
-      exception
-      when E : WisiToken.Syntax_Error | WisiToken.Parse_Error =>
-         Ada.Text_IO.Put_Line (Ada.Text_IO.Standard_Error, 
Ada.Exceptions.Exception_Message (E));
-         Grammar_Parser.Put_Errors;
-         raise;
-      end Parse_Check;
-
-   begin
-      --  Get the the input file quads, translate EBNF
-      Parse_Check (None, None, WisiToken_Grammar_Runtime.Meta);
-
-      if Command_Generate_Set = null then
-         if Input_Data.Generate_Set = null then
-            raise User_Error with
-              WisiToken.Generate.Error_Message
-                (Input_Data.Grammar_Lexer.File_Name, 1,
-                 "generate algorithm, output_language, lexer, interface not 
specified");
-         end if;
-
-         Generate_Set := Input_Data.Generate_Set;
-      else
-         Generate_Set := Command_Generate_Set;
-      end if;
-
-      Multiple_Tuples := Generate_Set'Length > 1;
-
-      for Tuple of Generate_Set.all loop
-         Parse_Check
-           (Lexer  => Tuple.Lexer,
-            Parser => Tuple.Gen_Alg,
-            Phase  => WisiToken_Grammar_Runtime.Other);
-
-         declare
-            use Ada.Real_Time;
-
-            Time_Start : Time;
-            Time_End   : Time;
-
-            Generate_Data : aliased WisiToken.BNF.Generate_Utils.Generate_Data 
:=
-              WisiToken.BNF.Generate_Utils.Initialize (Input_Data, 
Ignore_Conflicts);
-
-            Packrat_Data : WisiToken.Generate.Packrat.Data
-              (Generate_Data.Descriptor.First_Terminal, 
Generate_Data.Descriptor.First_Nonterminal,
-               Generate_Data.Descriptor.Last_Nonterminal);
-
-            Parse_Table_File_Name : constant String :=
-              (if WisiToken.Trace_Generate_Table = 0 and Tuple.Gen_Alg in LALR 
.. Packrat_Proc
-               then -Output_File_Name_Root & "_" & To_Lower 
(Generate_Algorithm'Image (Tuple.Gen_Alg)) &
-                 (if Input_Data.If_Lexer_Present
-                  then "_" & Lexer_Image (Input_Data.User_Lexer).all
-                  else "") &
-                  ".parse_table"
-               else "");
-
-            procedure Parse_Table_Append_Stats
-            is
-               Parse_Table_File : File_Type;
-            begin
-               Open (Parse_Table_File, Append_File, Parse_Table_File_Name);
-               Set_Output (Parse_Table_File);
-               Generate_Data.Parser_State_Count :=
-                 Generate_Data.LR_Parse_Table.State_Last - 
Generate_Data.LR_Parse_Table.State_First + 1;
-               WisiToken.BNF.Generate_Utils.Put_Stats (Input_Data, 
Generate_Data);
-               Set_Output (Standard_Output);
-               Close (Parse_Table_File);
-            end Parse_Table_Append_Stats;
-
-         begin
-            if not Lexer_Done (Input_Data.User_Lexer) then
-               Lexer_Done (Input_Data.User_Lexer) := True;
-               case Input_Data.User_Lexer is
-               when re2c_Lexer =>
-                  WisiToken.BNF.Output_Ada_Common.Create_re2c
-                    (Input_Data, Tuple, Generate_Data, -Output_File_Name_Root);
-               when others =>
-                  null;
-               end case;
-            end if;
-
-            case Tuple.Gen_Alg is
-            when None =>
-               --  Just translate EBNF to BNF, done in Parse_Check
-               null;
-
-            when LALR =>
-
-               Time_Start := Clock;
-
-               if Generate_Data.Grammar 
(Generate_Data.Descriptor.Accept_ID).LHS = Invalid_Token_ID then
-                  WisiToken.Generate.Put_Error
-                    (WisiToken.Generate.Error_Message
-                       (Grammar_Parser.Lexer.File_Name, 1,
-                        "%start token not specified or not found; no LALR 
parse table generated"));
-               else
-                  Generate_Data.LR_Parse_Table := 
WisiToken.Generate.LR.LALR_Generate.Generate
-                    (Generate_Data.Grammar,
-                     Generate_Data.Descriptor.all,
-                     Generate_Utils.To_Conflicts
-                       (Generate_Data, Input_Data.Conflicts, 
Input_Data.Grammar_Lexer.File_Name),
-                     Generate_Utils.To_McKenzie_Param (Generate_Data, 
Input_Data.McKenzie_Recover),
-                     Parse_Table_File_Name,
-                     Include_Extra     => Test_Main,
-                     Ignore_Conflicts  => Ignore_Conflicts,
-                     Partial_Recursion => 
Input_Data.Language_Params.Partial_Recursion);
-
-                  if WisiToken.Trace_Time then
-                     Time_End := Clock;
-
-                     Put_Line
-                       (Standard_Error,
-                        "LALR " & Lexer_Image (Tuple.Lexer).all & " generate 
time:" &
-                          Duration'Image (To_Duration (Time_End - 
Time_Start)));
-                  end if;
-
-                  if Parse_Table_File_Name /= "" then
-                     Parse_Table_Append_Stats;
-                  end if;
-               end if;
-
-            when LR1 =>
-               Time_Start := Clock;
-
-               if Generate_Data.Grammar 
(Generate_Data.Descriptor.Accept_ID).LHS = Invalid_Token_ID then
-                  WisiToken.Generate.Put_Error
-                    (WisiToken.Generate.Error_Message
-                       (Grammar_Parser.Lexer.File_Name, 1,
-                        "%start token not specified or not found; no LALR 
parse table generated"));
-               else
-                  Generate_Data.LR_Parse_Table := 
WisiToken.Generate.LR.LR1_Generate.Generate
-                    (Generate_Data.Grammar,
-                     Generate_Data.Descriptor.all,
-                     Generate_Utils.To_Conflicts
-                       (Generate_Data, Input_Data.Conflicts, 
Input_Data.Grammar_Lexer.File_Name),
-                     Generate_Utils.To_McKenzie_Param (Generate_Data, 
Input_Data.McKenzie_Recover),
-                     Parse_Table_File_Name,
-                     Include_Extra     => Test_Main,
-                     Ignore_Conflicts  => Ignore_Conflicts,
-                     Partial_Recursion => 
Input_Data.Language_Params.Partial_Recursion);
-
-                  if Trace_Time then
-                     Time_End := Clock;
-
-                     Put_Line
-                       (Standard_Error,
-                        "LR1 " & Lexer_Image (Tuple.Lexer).all & " generate 
time:" &
-                          Duration'Image (To_Duration (Time_End - 
Time_Start)));
-                  end if;
-
-                  if Parse_Table_File_Name /= "" then
-                     Parse_Table_Append_Stats;
-                  end if;
-               end if;
-
-            when Packrat_Generate_Algorithm =>
-               --  The only significant computation done for Packrat is First, 
done
-               --  in Initialize; not worth timing.
-
-               Packrat_Data := WisiToken.Generate.Packrat.Initialize
-                 (Input_Data.Grammar_Lexer.File_Name, Generate_Data.Grammar, 
Generate_Data.Source_Line_Map,
-                  Generate_Data.Descriptor.First_Terminal);
-
-               if Parse_Table_File_Name /= "" then
-                  declare
-                     Parse_Table_File : File_Type;
-                  begin
-                     Create (Parse_Table_File, Out_File, 
Parse_Table_File_Name);
-                     Set_Output (Parse_Table_File);
-                     Put_Line ("Tokens:");
-                     WisiToken.Put_Tokens (Generate_Data.Descriptor.all);
-                     New_Line;
-                     Put_Line ("Productions:");
-                     WisiToken.Productions.Put (Generate_Data.Grammar, 
Generate_Data.Descriptor.all);
-                     Set_Output (Standard_Output);
-                     Close (Parse_Table_File);
-                  end;
-               end if;
-
-               Packrat_Data.Check_All (Generate_Data.Descriptor.all);
-
-            when External =>
-               null;
-            end case;
-
-            if WisiToken.Generate.Error then
-               raise WisiToken.Grammar_Error with "errors: aborting";
-            end if;
-
-            case Tuple.Gen_Alg is
-            when LR_Generate_Algorithm =>
-               if Tuple.Text_Rep then
-                  WisiToken.Generate.LR.Put_Text_Rep
-                    (Generate_Data.LR_Parse_Table.all,
-                     -Output_File_Name_Root & "_" &
-                       To_Lower (Generate_Algorithm_Image (Tuple.Gen_Alg).all) 
&
-                       "_parse_table.txt",
-                     Generate_Data.Action_Names.all, 
Generate_Data.Check_Names.all);
-               end if;
-
-            when others =>
-               null;
-            end case;
-
-            if Tuple.Gen_Alg /= None then
-               case Tuple.Out_Lang is
-               when Ada_Lang =>
-                  WisiToken.BNF.Output_Ada
-                    (Input_Data, -Output_File_Name_Root, Generate_Data, 
Packrat_Data, Tuple, Test_Main,
-                     Multiple_Tuples);
-
-               when Ada_Emacs_Lang =>
-                  WisiToken.BNF.Output_Ada_Emacs
-                    (Input_Data, -Output_File_Name_Root, Generate_Data, 
Packrat_Data, Tuple,
-                     Test_Main, Multiple_Tuples, -Language_Name);
-
-               end case;
-               if WisiToken.Generate.Error then
-                  raise WisiToken.Grammar_Error with "errors: aborting";
-               end if;
-            end if;
-         end;
-      end loop;
-   end;
-exception
-when WisiToken.Syntax_Error | WisiToken.Parse_Error =>
-   --  error message already output
-   Ada.Command_Line.Set_Exit_Status (Ada.Command_Line.Failure);
-
-when E : User_Error =>
-   declare
-      use Ada.Command_Line;
-      use Ada.Exceptions;
-      use Ada.Text_IO;
-   begin
-      Put_Line (Standard_Error, Exception_Message (E));
-      Put_Command_Line (Ada_Comment);
-      Set_Exit_Status (Failure);
-      Put_Usage;
-   end;
-
-when E : WisiToken.Grammar_Error =>
-   --  error message not already output
-   declare
-      use Ada.Command_Line;
-      use Ada.Exceptions;
-      use Ada.Text_IO;
-   begin
-      Put_Line (Standard_Error, Exception_Message (E));
-      Set_Exit_Status (Failure);
-   end;
-
-when E :  others =>
-   --  IMPROVEME: for some exceptions, Error message already output via 
wisi.utils.Put_Error
-   declare
-      use Ada.Text_IO;
-      use Ada.Exceptions;
-      use Ada.Command_Line;
-   begin
-      Put_Line (Standard_Error, Exception_Name (E) & ": " & Exception_Message 
(E));
-      Put_Line (Standard_Error, GNAT.Traceback.Symbolic.Symbolic_Traceback 
(E));
-      Set_Exit_Status (Failure);
-   end;
-
-end WisiToken.BNF.Generate;
diff --git a/packages/wisi/wisitoken-bnf-generate_grammar.adb 
b/packages/wisi/wisitoken-bnf-generate_grammar.adb
deleted file mode 100644
index cd165c4..0000000
--- a/packages/wisi/wisitoken-bnf-generate_grammar.adb
+++ /dev/null
@@ -1,86 +0,0 @@
---  Abstract :
---
---  Output Ada source code to recreate Grammar.
---
---  Copyright (C) 2018 - 2019 Free Software Foundation, Inc.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-with Ada.Text_IO; use Ada.Text_IO;
-with WisiToken.Generate;
-with WisiToken.Productions;
-procedure WisiToken.BNF.Generate_Grammar
-  (Grammar      : in WisiToken.Productions.Prod_Arrays.Vector;
-   Action_Names : in WisiToken.Names_Array_Array)
-is
-   use all type Ada.Containers.Count_Type;
-   use Ada.Strings.Unbounded;
-   use WisiToken.Generate;
-   use WisiToken.Productions;
-   Text : Unbounded_String;
-   Need_Comma : Boolean := False;
-begin
-   Indent_Line
-     ("Grammar.Set_First_Last (" & Trimmed_Image (Grammar.First_Index) & ", " &
-        Trimmed_Image (Grammar.Last_Index) & ");");
-
-   for Prod of Grammar loop
-      Indent_Line ("declare");
-      Indent_Line ("   Prod : Instance;");
-      Indent_Line ("begin");
-      Indent := Indent + 3;
-      Indent_Line ("Prod.LHS := " & Trimmed_Image (Prod.LHS) & ";");
-      Indent_Line ("Prod.RHSs.Set_First_Last (0, " & Trimmed_Image 
(Prod.RHSs.Last_Index) & ");");
-      for RHS_Index in Prod.RHSs.First_Index .. Prod.RHSs.Last_Index loop
-         declare
-            RHS : Right_Hand_Side renames Prod.RHSs (RHS_Index);
-         begin
-            Indent_Line ("declare");
-            Indent_Line ("   RHS : Right_Hand_Side;");
-            Indent_Line ("begin");
-            Indent := Indent + 3;
-            if RHS.Tokens.Length > 0 then
-               Indent_Line
-                 ("RHS.Tokens.Set_First_Last (1, " & Trimmed_Image (Prod.RHSs 
(RHS_Index).Tokens.Last_Index) & ");");
-
-               if RHS.Tokens.Length = 1 then
-                  Indent_Line ("To_Vector ((1 => " & Trimmed_Image (RHS.Tokens 
(1)) & "), RHS.Tokens);");
-               else
-                  Need_Comma := False;
-                  Text := +"To_Vector ((";
-                  for ID of RHS.Tokens  loop
-                     if Need_Comma then
-                        Text := Text & ", ";
-                     else
-                        Need_Comma := True;
-                     end if;
-                     Text := Text & Trimmed_Image (ID);
-                  end loop;
-                  Text := Text & "), RHS.Tokens);";
-                  Indent_Wrap (-Text);
-               end if;
-            end if;
-            if Action_Names (Prod.LHS) /= null and then Action_Names 
(Prod.LHS)(RHS_Index) /= null then
-               Indent_Line ("RHS.Action     := " & Action_Names 
(Prod.LHS)(RHS_Index).all & "'Access;");
-            end if;
-            Indent_Line ("Prod.RHSs (" & Trimmed_Image (RHS_Index) & ") := 
RHS;");
-            Indent := Indent - 3;
-            Indent_Line ("end;");
-         end;
-      end loop;
-      Indent_Line ("Grammar (" & Trimmed_Image (Prod.LHS) & ") := Prod;");
-      Indent := Indent - 3;
-      Indent_Line ("end;");
-   end loop;
-end WisiToken.BNF.Generate_Grammar;
diff --git a/packages/wisi/wisitoken-bnf-generate_packrat.adb 
b/packages/wisi/wisitoken-bnf-generate_packrat.adb
deleted file mode 100644
index b4592e5..0000000
--- a/packages/wisi/wisitoken-bnf-generate_packrat.adb
+++ /dev/null
@@ -1,333 +0,0 @@
---  Abstract :
---
---  Generate Ada code for a Packrat parser.
---
---  References:
---
---  See wisitoken-parse-packrat.ads.
---
---  Copyright (C) 2018, 2020 Free Software Foundation, Inc.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-with Ada.Text_IO; use Ada.Text_IO;
-with WisiToken.BNF.Generate_Utils;
-with WisiToken.Generate.Packrat;
-with WisiToken.Productions;
-procedure WisiToken.BNF.Generate_Packrat
-  (Data          : in WisiToken.Generate.Packrat.Data;
-   Generate_Data : in WisiToken.BNF.Generate_Utils.Generate_Data)
-is
-   use WisiToken.Generate;
-
-   Descriptor   : WisiToken.Descriptor renames Generate_Data.Descriptor.all;
-   Action_Names : Names_Array_Array renames Generate_Data.Action_Names.all;
-
-   subtype Terminal is Token_ID range Descriptor.First_Terminal .. 
Descriptor.Last_Terminal;
-
-   --  FIXME: optimize memoizing? small productions not worth the memory cost?
-   --  or just use langkit space optimization.
-
-   function Parser_Name (Nonterm : in Token_ID) return String
-   is begin
-      return "Parse_" & Image (Nonterm, Descriptor);
-   end Parser_Name;
-
-   procedure Put_Parser_Spec (Name : in String)
-   is begin
-      Indent_Line ("function " & Name);
-      Indent_Start ("  (Parser : in out Generated.Parser; Last_Pos : in 
Base_Token_Index) return Result_Type");
-   end Put_Parser_Spec;
-
-   function Var_Suffix (I, J : in Integer) return String
-   is begin
-      return Trimmed_Image (I) & '_' & Trimmed_Image (J);
-   end Var_Suffix;
-
-   procedure Generate_Parser_Body (Prod : in Productions.Instance)
-   is
-      use all type Ada.Containers.Count_Type;
-
-      Result_ID : constant String := Trimmed_Image (Prod.LHS);
-   begin
-      --  We use gotos and function scope vars rather than nested if/declare
-      --  to avoid excessive indenting for long productions.
-
-      Put_Parser_Spec (Parser_Name (Prod.LHS)); New_Line;
-      Indent_Line ("is");
-      Indent := Indent + 3;
-
-      Indent_Line ("Descriptor : WisiToken.Descriptor renames 
Parser.Trace.Descriptor.all;");
-      Indent_Line ("Start_Pos  : constant Token_Index := Last_Pos + 1; --  
first token in current nonterm");
-      Indent_Line ("Pos        : Base_Token_Index := Last_Pos; --  last token 
parsed.");
-
-      for RHS_Index in Prod.RHSs.First_Index .. Prod.RHSs.Last_Index loop
-         declare
-            RHS : Productions.Right_Hand_Side renames Prod.RHSs (RHS_Index);
-         begin
-            for Token_Index in RHS.Tokens.First_Index .. RHS.Tokens.Last_Index 
loop
-               if RHS.Tokens (Token_Index) in Descriptor.First_Terminal .. 
Descriptor.Last_Terminal then
-                  Indent_Line ("Pos_" & Var_Suffix (RHS_Index, Token_Index) & 
"  : Token_Index;");
-               else
-                  Indent_Line ("Memo_" & Var_Suffix (RHS_Index, Token_Index) & 
" : Memo_Entry;");
-               end if;
-            end loop;
-         end;
-      end loop;
-
-      if Data.Direct_Left_Recursive (Prod.LHS) then
-         Indent_Line ("Pos_Recurse_Last : Base_Token_Index := Last_Pos;");
-         Indent_Line ("Result_Recurse   : Memo_Entry;");
-      end if;
-
-      Indent := Indent - 3;
-      Indent_Line ("begin");
-      Indent := Indent + 3;
-
-      Indent_Line ("if Pos = Parser.Terminals.Last_Index then");
-      Indent_Line ("   return (State => Failure);");
-      Indent_Line ("end if;");
-      Indent_Line ("declare");
-      Indent_Line ("   Memo : Memo_Entry renames Parser.Derivs (" & Result_ID 
& ")(Start_Pos);");
-      Indent_Line ("begin");
-      Indent := Indent + 3;
-      Indent_Line ("case Memo.State is");
-      Indent_Line ("when Success =>");
-      Indent_Line ("   return Parser.Derivs (" & Result_ID & ")(Start_Pos);");
-      Indent_Line ("when Failure =>");
-
-      --  FIXME: Could simplify this when not doing left recursion
-      Indent_Line ("   goto RHS_" & Trimmed_Image (Prod.RHSs.Last_Index) & 
"_Fail;");
-
-      Indent_Line ("when No_Result =>");
-      Indent_Line ("   if Memo.Recursive then");
-      Indent_Start ("      raise Recursive with Image (" & Result_ID & ", 
Descriptor) &");
-      Put_Line (" Token_Index'Image (Start_Pos) & "": recursive"";");
-      Indent_Line ("   end if;");
-      Indent_Line ("   Memo.Recursive := True;");
-      Indent_Line ("end case;");
-      Indent := Indent - 3;
-      Indent_Line ("end;");
-      New_Line;
-
-      if Data.Direct_Left_Recursive (Prod.LHS) then
-         --  This is the top of the 'while' loop in [warth 2008] figure 3 
Grow-LR.
-         Indent_Line ("Parser.Derivs (" & Result_ID & ").Replace_Element 
(Start_Pos, (State => Failure));");
-         Indent_Line ("<<Recurse_Start>>");
-      end if;
-
-      for RHS_Index in Prod.RHSs.First_Index .. Prod.RHSs.Last_Index loop
-         declare
-            RHS : Productions.Right_Hand_Side renames Prod.RHSs (RHS_Index);
-
-            procedure Finish
-            is begin
-               if Data.Direct_Left_Recursive (Prod.LHS) then
-                  Indent_Line ("Result_Recurse :=");
-                  Indent := Indent + 2;
-               else
-                  Indent_Line ("Parser.Derivs (" & Result_ID & 
").Replace_Element");
-                  Indent_Line ("  (Start_Pos,");
-                  Indent := Indent + 3;
-               end if;
-               Indent_Line ("(State              => Success,");
-               Indent_Line (" Result             => Parser.Tree.Add_Nonterm");
-
-               Indent := Indent + 3;
-               Indent_Line ("(Production      => (" & Result_ID & ", " & 
Trimmed_Image (RHS_Index) & "),");
-               Indent_Line
-                 (" Action          => " &
-                    (if Action_Names (Prod.LHS) = null or else Action_Names 
(Prod.LHS)(RHS_Index) = null
-                     then "null,"
-                     else Action_Names (Prod.LHS)(RHS_Index).all & 
"'Access,"));
-
-               if RHS.Tokens.Length = 0 then
-                  Indent_Line (" Children        => (1 .. 0 => 
Invalid_Node_Index),");
-
-               elsif RHS.Tokens.Length = 1 then
-                  Indent_Start (" Children        => ");
-                  if RHS.Tokens (RHS.Tokens.First_Index) in Terminal then
-                     Put ("(1 => Tree_Index (Pos_" & Var_Suffix (RHS_Index, 
RHS.Tokens.First_Index) & ")),");
-                  else
-                     Put ("(1 => Memo_" & Var_Suffix (RHS_Index, 
RHS.Tokens.First_Index) & ".Result),");
-                  end if;
-
-               else
-                  Indent_Line (" Children        =>");
-
-                  for Token_Index in RHS.Tokens.First_Index .. 
RHS.Tokens.Last_Index loop
-                     if RHS.Tokens (Token_Index) in Terminal then
-                        Indent_Start
-                          ((if Token_Index = RHS.Tokens.First_Index
-                            then "  ("
-                            else "   ") &
-                             "Tree_Index (Pos_" & Var_Suffix (RHS_Index, 
Token_Index) & ")");
-                     else
-                        Indent_Start
-                          ((if Token_Index = RHS.Tokens.First_Index
-                            then "  ("
-                            else "   ") &
-                             "Memo_" & Var_Suffix (RHS_Index, Token_Index) & 
".Result");
-                     end if;
-                     if Token_Index = RHS.Tokens.Last_Index then
-                        Put_Line ("),");
-                     else
-                        Put_Line (",");
-                     end if;
-                  end loop;
-               end if;
-
-               Indent_Line (" Default_Virtual => False),");
-               Indent := Indent - 3;
-               Indent_Start (" Last_Token      => Pos)");
-
-               if Data.Direct_Left_Recursive (Prod.LHS) then
-                  Put_Line (";");
-                  Indent := Indent - 2;
-                  Indent_Line ("goto Finish;");
-               else
-                  Put_Line (");");
-                  Indent := Indent - 3;
-                  Indent_Line ("goto Succeed;");
-               end if;
-            end Finish;
-
-         begin
-            Indent_Wrap_Comment (Productions.Image (Prod.LHS, RHS_Index, 
RHS.Tokens, Descriptor), Ada_Comment);
-            Indent_Line ("Pos := Last_Pos;");
-
-            if RHS.Tokens.Length = 0 then
-               Finish;
-            else
-               for Token_Index in RHS.Tokens.First_Index .. 
RHS.Tokens.Last_Index loop
-                  declare
-                     ID      : constant String := Trimmed_Image (RHS.Tokens 
(Token_Index));
-                     Var_Suf : constant String := Var_Suffix (RHS_Index, 
Token_Index);
-                  begin
-                     if RHS.Tokens (Token_Index) in Terminal then
-                        Indent_Line ("if Parser.Terminals (Pos + 1).ID = " & 
ID & " then");
-                        Indent := Indent + 3;
-                        Indent_Line ("Pos := Pos + 1;");
-                        Indent_Line ("Pos_" & Var_Suf & " := Pos;");
-                        if Token_Index = RHS.Tokens.Last_Index then
-                           Finish;
-                        end if;
-                        Indent := Indent - 3;
-                        Indent_Line ("else");
-                        Indent_Line ("   goto RHS_" & Trimmed_Image 
(RHS_Index) & "_Fail;");
-                        Indent_Line ("end if;");
-
-                     else -- nonterminal
-                        Indent_Line
-                          ("Memo_" & Var_Suf & " := Parse_" & Image 
(RHS.Tokens (Token_Index), Descriptor) &
-                             " (Parser, Pos);");
-                        Indent_Line ("case Result_States'(Memo_" & Var_Suf & 
".State) is");
-                        Indent_Line ("when Success =>");
-                        Indent := Indent + 3;
-                        Indent_Line ("Pos := Memo_" & Var_Suf & 
".Last_Token;");
-                        if Token_Index = RHS.Tokens.Last_Index then
-                           Finish;
-                        end if;
-                        Indent := Indent - 3;
-                        Indent_Line ("when Failure =>");
-                        Indent_Line ("   goto RHS_" & Trimmed_Image 
(RHS_Index) & "_Fail;");
-                        Indent_Line ("end case;");
-                     end if;
-                  end;
-               end loop;
-            end if;
-
-            Indent_Line ("<<RHS_" & Trimmed_Image (RHS_Index) & "_Fail>>");
-            New_Line;
-         end;
-      end loop;
-
-      --  We get here if the last alternative fails.
-      if Data.Direct_Left_Recursive (Prod.LHS) then
-         Indent_Line ("Result_Recurse := (State => Failure);");
-      else
-         Indent_Line ("Parser.Derivs (" & Result_ID & ").Replace_Element 
(Start_Pos, (State => Failure));");
-         Indent_Line ("return Parser.Derivs (" & Result_ID & ")(Start_Pos);");
-      end if;
-
-      if Data.Direct_Left_Recursive (Prod.LHS) then
-         Indent_Line ("<<Finish>>");
-         Indent_Line ("if Result_Recurse.State = Success then");
-         Indent := Indent + 3;
-         Indent_Line ("if Pos > Pos_Recurse_Last then");
-         --  made progress, try again
-         Indent := Indent + 3;
-         Indent_Line ("Parser.Derivs (" & Result_ID & ").Replace_Element 
(Start_Pos, Result_Recurse);");
-         Indent_Line ("Pos_Recurse_Last := Pos;");
-         Indent_Line ("if WisiToken.Trace_Parse > Detail then");
-         Indent_Line ("   Parser.Trace.Put_Line");
-         Indent_Line
-           ("     (Parser.Tree.Image (Result_Recurse.Result, Descriptor, 
Include_Children => True));");
-         Indent_Line ("end if;");
-         Indent_Line ("goto Recurse_Start;");
-         Indent := Indent - 3;
-         Indent_Line
-           ("elsif Pos = Pos_Recurse_Last and then " &
-              "Parser.Tree.Buffer_Region_Is_Empty (Result_Recurse.Result) 
then");
-         --  Parse succeeded producing an empty nonterm; don't try again. This
-         --  special case is not in [warth 2008].
-         Indent_Line ("   Parser.Derivs (" & Result_ID & ").Replace_Element 
(Start_Pos, Result_Recurse);");
-         Indent_Line ("end if;");
-         Indent := Indent - 3;
-         Indent_Line ("end if;");
-      end if;
-      New_Line;
-
-      if not Data.Direct_Left_Recursive (Prod.LHS) then
-         Indent_Line ("<<Succeed>>");
-         Indent_Line ("if WisiToken.Trace_Parse > Detail then");
-         Indent := Indent + 3;
-         Indent_Line ("Parser.Trace.Put_Line");
-         Indent_Line ("  (Parser.Tree.Image");
-         Indent_Line
-           ("    (Parser.Derivs (" & Result_ID & ")(Start_Pos).Result, 
Descriptor, Include_Children => True));");
-         Indent := Indent - 3;
-         Indent_Line ("end if;");
-      end if;
-
-      Indent_Line ("return Parser.Derivs (" & Result_ID & ")(Start_Pos);");
-      Indent := Indent - 3;
-      Indent_Line ("end " & Parser_Name (Prod.LHS) & ";");
-      New_Line;
-   end Generate_Parser_Body;
-
-begin
-   Indent_Line ("use WisiToken;");
-   Indent_Line ("use WisiToken.Parse.Packrat;");
-   Indent_Line ("use WisiToken.Parse.Packrat.Generated;");
-
-   for Prod of Data.Grammar loop
-      Put_Parser_Spec (Parser_Name (Prod.LHS)); Put_Line (";");
-   end loop;
-   New_Line;
-
-   for Prod of Data.Grammar loop
-      Generate_Parser_Body (Prod);
-   end loop;
-
-   Indent_Line ("function Parse_wisitoken_accept_1");
-   Indent_Line
-     --  WORKAROUND: using Parse.Packrat.Parser'Class here generates GNAT bug 
box with GPL 2018
-     ("  (Parser : in out WisiToken.Parse.Base_Parser'Class; Last_Pos : in 
Base_Token_Index) return Result_Type");
-   Indent_Line ("is begin");
-   Indent_Line ("   return Parse_wisitoken_accept (Generated.Parser (Parser), 
Last_Pos);");
-   Indent_Line ("end Parse_wisitoken_accept_1;");
-   New_Line;
-
-end WisiToken.BNF.Generate_Packrat;
diff --git a/packages/wisi/wisitoken-bnf-generate_utils.adb 
b/packages/wisi/wisitoken-bnf-generate_utils.adb
deleted file mode 100644
index b5622d0..0000000
--- a/packages/wisi/wisitoken-bnf-generate_utils.adb
+++ /dev/null
@@ -1,724 +0,0 @@
---  Abstract :
---
---  see spec
---
---  Copyright (C) 2014, 2015, 2017 - 2020  All Rights Reserved.
---
---  This program is free software; you can redistribute it and/or
---  modify it under terms of the GNU General Public License as
---  published by the Free Software Foundation; either version 3, 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
---  distributed with this program; see file COPYING. If not, write to
---  the Free Software Foundation, 51 Franklin Street, Suite 500, Boston,
---  MA 02110-1335, USA.
-
-pragma License (GPL);
-
-with Ada.Exceptions;
-with Ada.Text_IO;
-with WisiToken.Generate; use WisiToken.Generate;
-with WisiToken.Syntax_Trees;
-with WisiToken.Wisi_Ada;
-package body WisiToken.BNF.Generate_Utils is
-
-   --  For Constant_Reference
-   Aliased_EOI_Name              : aliased constant 
Ada.Strings.Unbounded.Unbounded_String := +EOI_Name;
-   Aliased_WisiToken_Accept_Name : aliased constant 
Ada.Strings.Unbounded.Unbounded_String :=
-     +WisiToken_Accept_Name;
-
-   --  body specs, as needed.
-
-   ----------
-   --  Body subprograms
-
-   function Find_Kind (Data : aliased Generate_Data; Target_Kind : in String) 
return Token_ID
-   is begin
-      for Cursor in All_Tokens (Data).Iterate loop
-         if Kind (Cursor) = Target_Kind then
-            return ID (Cursor);
-         end if;
-      end loop;
-      return Invalid_Token_ID;
-   end Find_Kind;
-
-   function Name_1 (Cursor : in Token_Cursor) return String
-   is begin
-      --   This function is used to compute Descriptor.Image
-      case Cursor.Kind is
-      when Non_Grammar_Kind =>
-         return -Cursor.Data.Tokens.Non_Grammar (Cursor.Token_Kind).Tokens 
(Cursor.Token_Item).Name;
-
-      when Terminals_Keywords =>
-         return -Cursor.Data.Tokens.Keywords (Cursor.Keyword).Name;
-
-      when Terminals_Others =>
-         return -Cursor.Data.Tokens.Tokens (Cursor.Token_Kind).Tokens 
(Cursor.Token_Item).Name;
-
-      when EOI =>
-         return EOI_Name;
-
-      when WisiToken_Accept =>
-         return WisiToken_Accept_Name;
-
-      when Nonterminal =>
-         return -Cursor.Data.Tokens.Rules (Cursor.Nonterminal).Left_Hand_Side;
-
-      when Done =>
-         raise SAL.Programmer_Error with "token cursor is done";
-      end case;
-   end Name_1;
-
-   procedure To_Grammar
-     (Data             : aliased in out Generate_Data;
-      Source_File_Name :         in     String;
-      Start_Token      :         in     String)
-   is
-      use WisiToken.Wisi_Ada;
-      Descriptor : WisiToken.Descriptor renames Data.Descriptor.all;
-   begin
-      Data.Grammar.Set_First_Last (Descriptor.First_Nonterminal, 
Descriptor.Last_Nonterminal);
-      Data.Source_Line_Map.Set_First_Last (Descriptor.First_Nonterminal, 
Descriptor.Last_Nonterminal);
-
-      Data.Action_Names := new Names_Array_Array (Descriptor.First_Nonterminal 
.. Descriptor.Last_Nonterminal);
-      Data.Check_Names  := new Names_Array_Array (Descriptor.First_Nonterminal 
.. Descriptor.Last_Nonterminal);
-
-      pragma Assert (Descriptor.Accept_ID = Descriptor.First_Nonterminal);
-
-      Data.Source_Line_Map (Descriptor.Accept_ID).Line := 
Line_Number_Type'First;
-      Data.Source_Line_Map (Descriptor.Accept_ID).RHS_Map.Set_First_Last (0, 
0);
-      Data.Source_Line_Map (Descriptor.Accept_ID).RHS_Map (0) := 
Line_Number_Type'First;
-
-      if Start_Token = "" then
-         Put_Error (Error_Message (Source_File_Name, 1, "%start not 
specified"));
-      else
-         begin
-            Data.Grammar (Descriptor.Accept_ID) :=
-              Descriptor.Accept_ID <= Only
-                (Find_Token_ID (Data, Start_Token) & Descriptor.EOI_ID + 
WisiToken.Syntax_Trees.Null_Action);
-         exception
-         when Not_Found =>
-            Put_Error
-              (Error_Message
-                 (Source_File_Name, 1,
-                  "start token '" & (Start_Token) & "' not found"));
-         end;
-      end if;
-
-      for Rule of Data.Tokens.Rules loop
-         declare
-            RHS_Index        : Natural := 0;
-            RHSs             : WisiToken.Productions.RHS_Arrays.Vector;
-            LHS              : Token_ID; -- not initialized for exception 
handler
-            Action_Names     : Names_Array (0 .. Integer 
(Rule.Right_Hand_Sides.Length) - 1);
-            Action_All_Empty : Boolean := True;
-            Check_Names      : Names_Array (0 .. Integer 
(Rule.Right_Hand_Sides.Length) - 1);
-            Check_All_Empty  : Boolean := True;
-         begin
-            LHS := Find_Token_ID (Data, -Rule.Left_Hand_Side);
-
-            RHSs.Set_First_Last (RHS_Index, Natural 
(Rule.Right_Hand_Sides.Length) - 1);
-
-            Data.Source_Line_Map (LHS).Line := Rule.Source_Line;
-            Data.Source_Line_Map (LHS).RHS_Map.Set_First_Last 
(RHSs.First_Index, RHSs.Last_Index);
-
-            for Right_Hand_Side of Rule.Right_Hand_Sides loop
-               declare
-                  use Ada.Strings.Unbounded;
-                  use all type Ada.Containers.Count_Type;
-                  Tokens : WisiToken.Token_ID_Arrays.Vector;
-                  I      : Integer := 1;
-               begin
-                  if Right_Hand_Side.Tokens.Length > 0 then
-                     Tokens.Set_First_Last (I, Integer 
(Right_Hand_Side.Tokens.Length));
-                     for Token of Right_Hand_Side.Tokens loop
-                        Tokens (I) := Find_Token_ID (Data, -Token.Identifier);
-                        I := I + 1;
-                     end loop;
-                  end if;
-                  RHSs (RHS_Index) :=
-                    (Tokens => Tokens, Action => null, Check => null, 
Recursion => <>);
-                  if Length (Right_Hand_Side.Action) > 0 then
-                     Action_All_Empty := False;
-                     Action_Names (RHS_Index) := new String'
-                       (-Rule.Left_Hand_Side & '_' & WisiToken.Trimmed_Image 
(RHS_Index));
-                  end if;
-                  if Length (Right_Hand_Side.Check) > 0 then
-                     Check_All_Empty := False;
-                     Check_Names (RHS_Index) := new String'
-                       (-Rule.Left_Hand_Side & '_' & WisiToken.Trimmed_Image 
(RHS_Index) & "_check");
-                  end if;
-
-                  Data.Source_Line_Map (LHS).RHS_Map (RHS_Index) := 
Right_Hand_Side.Source_Line;
-               exception
-               when E : Not_Found =>
-                  --  From "&"
-                  Put_Error
-                    (Error_Message
-                       (Source_File_Name, Right_Hand_Side.Source_Line, 
Ada.Exceptions.Exception_Message (E)));
-               end;
-               RHS_Index := RHS_Index + 1;
-            end loop;
-
-            Data.Grammar (LHS) := LHS <= RHSs;
-            if not Action_All_Empty then
-               Data.Action_Names (LHS) := new Names_Array'(Action_Names);
-            end if;
-            if not Check_All_Empty then
-               Data.Check_Names (LHS) := new Names_Array'(Check_Names);
-            end if;
-
-         exception
-         when E : Not_Found =>
-            --  From Find_Token_ID (left_hand_side)
-            Put_Error
-              (Error_Message
-                 (Source_File_Name, Rule.Source_Line, 
Ada.Exceptions.Exception_Message (E)));
-         end;
-      end loop;
-
-      WisiToken.Generate.Check_Consistent (Data.Grammar, Descriptor, 
Source_File_Name);
-   end To_Grammar;
-
-   ----------
-   --  Public subprograms, declaration order
-
-   function Initialize
-     (Input_Data       : aliased in WisiToken_Grammar_Runtime.User_Data_Type;
-      Ignore_Conflicts :         in Boolean := False)
-     return Generate_Data
-   is
-      EOI_ID : constant Token_ID := Token_ID
-        (Count (Input_Data.Tokens.Non_Grammar) + Count 
(Input_Data.Tokens.Tokens)) + Token_ID
-          (Input_Data.Tokens.Keywords.Length) + Token_ID'First;
-   begin
-      return Result : aliased Generate_Data :=
-        (Tokens => Input_Data.Tokens'Access,
-
-         Descriptor => new WisiToken.Descriptor
-           (First_Terminal    =>
-              (if Count (Input_Data.Tokens.Non_Grammar) > 0
-               then Token_ID (Count (Input_Data.Tokens.Non_Grammar)) + 
Token_ID'First
-               else Token_ID'First),
-            Last_Terminal     => EOI_ID,
-            EOI_ID            => EOI_ID,
-            Accept_ID         => EOI_ID + 1,
-            First_Nonterminal => EOI_ID + 1,
-            Last_Nonterminal  => EOI_ID + 1 + Token_ID 
(Input_Data.Tokens.Rules.Length)),
-
-         others => <>)
-      do
-         Result.Descriptor.Case_Insensitive := 
Input_Data.Language_Params.Case_Insensitive;
-         Result.Descriptor.New_Line_ID      := Find_Kind (Result, "new-line");
-         Result.Descriptor.String_1_ID      := Find_Kind (Result, 
"string-single");
-         Result.Descriptor.String_2_ID      := Find_Kind (Result, 
"string-double");
-
-         --  Image set in loop below, which also updates these widths.
-         Result.Descriptor.Terminal_Image_Width := 0;
-         Result.Descriptor.Image_Width          := 0;
-
-         Result.Descriptor.Last_Lookahead       :=
-           (case (Input_Data.User_Parser) is
-            when None                                  => Invalid_Token_ID,
-            when LR1                                   => 
Result.Descriptor.Last_Terminal,
-            when LALR                                  => 
Result.Descriptor.First_Nonterminal,
-            when Packrat_Generate_Algorithm | External => Invalid_Token_ID);
-
-         for Cursor in All_Tokens (Result).Iterate loop
-            Result.Descriptor.Image (ID (Cursor)) := new String'(Name_1 
(Cursor));
-         end loop;
-
-         for ID in Result.Descriptor.Image'Range loop
-            if ID in Result.Descriptor.First_Terminal .. 
Result.Descriptor.Last_Terminal then
-               if Result.Descriptor.Image (ID).all'Length > 
Result.Descriptor.Terminal_Image_Width then
-                  Result.Descriptor.Terminal_Image_Width := 
Result.Descriptor.Image (ID).all'Length;
-               end if;
-            end if;
-
-            if Result.Descriptor.Image (ID).all'Length > 
Result.Descriptor.Image_Width then
-               Result.Descriptor.Image_Width := Result.Descriptor.Image 
(ID).all'Length;
-            end if;
-         end loop;
-
-         To_Grammar (Result, Input_Data.Grammar_Lexer.File_Name, 
-Input_Data.Language_Params.Start_Token);
-         Result.Ignore_Conflicts := Ignore_Conflicts;
-      end return;
-   end Initialize;
-
-   function Find_Token_ID (Data : aliased in Generate_Data; Token : in String) 
return Token_ID
-   is begin
-      for Cursor in All_Tokens (Data).Iterate loop
-         if Name (Cursor) = Token then
-            return ID (Cursor);
-         end if;
-      end loop;
-      raise Not_Found with "token '" & Token & "' not found";
-   end Find_Token_ID;
-
-   function All_Tokens (Data : aliased in Generate_Data) return Token_Container
-   is begin
-      return (Data => Data'Access);
-   end All_Tokens;
-
-   function Constant_Reference
-     (Container : aliased in Token_Container'Class;
-      Cursor    :         in Token_Cursor)
-     return Token_Constant_Reference_Type
-   is begin
-      case Cursor.Kind is
-      when Non_Grammar_Kind =>
-         return
-           (Element => Container.Data.Tokens.Non_Grammar 
(Cursor.Token_Kind).Tokens (Cursor.Token_Item).Name'Access);
-
-      when Terminals_Keywords =>
-         return (Element => Container.Data.Tokens.Keywords 
(Cursor.Keyword).Name'Access);
-
-      when Terminals_Others =>
-         return (Element => Container.Data.Tokens.Tokens 
(Cursor.Token_Kind).Tokens (Cursor.Token_Item).Name'Access);
-
-      when EOI =>
-         return (Element => Aliased_EOI_Name'Access);
-
-      when WisiToken_Accept =>
-         return (Element => Aliased_WisiToken_Accept_Name'Access);
-
-      when Nonterminal =>
-         return (Element => Container.Data.Tokens.Rules 
(Cursor.Nonterminal).Left_Hand_Side'Access);
-
-      when Done =>
-         raise SAL.Programmer_Error with "token cursor is done";
-      end case;
-   end Constant_Reference;
-
-   type Iterator (Container : not null access constant Token_Container)
-   is new Iterator_Interfaces.Forward_Iterator with record
-      Non_Grammar  : Boolean;
-      Nonterminals : Boolean;
-   end record;
-
-   overriding function First (Object : Iterator) return Token_Cursor;
-   overriding function Next (Object : Iterator; Position : Token_Cursor) 
return Token_Cursor;
-
-   overriding function First (Object : Iterator) return Token_Cursor
-   is begin
-      return First (Object.Container.Data.all, Object.Non_Grammar, 
Object.Nonterminals);
-   end First;
-
-   overriding function Next (Object  : Iterator; Position : Token_Cursor) 
return Token_Cursor
-   is
-      Next_Position : Token_Cursor := Position;
-   begin
-      Next (Next_Position, Object.Nonterminals);
-      return Next_Position;
-   end Next;
-
-   function Iterate
-     (Container    : aliased    Token_Container;
-      Non_Grammar  :         in Boolean := True;
-      Nonterminals :         in Boolean := True)
-     return Iterator_Interfaces.Forward_Iterator'Class
-   is begin
-      return Iterator'(Container'Access, Non_Grammar, Nonterminals);
-   end Iterate;
-
-   function Next_Kind_Internal
-     (Cursor       : in out Token_Cursor;
-      Nonterminals : in     Boolean)
-     return Boolean
-   is begin
-      --  Advance Cursor to the next kind; return True if any of that
-      --  kind exist, or kind is Done; False otherwise.
-      case Cursor.Kind is
-      when Non_Grammar_Kind =>
-
-         Cursor :=
-           (Data        => Cursor.Data,
-            Kind        => Terminals_Keywords,
-            ID          => Cursor.Data.Descriptor.First_Terminal,
-            Token_Kind  => WisiToken.BNF.Token_Lists.No_Element,
-            Token_Item  => String_Triple_Lists.No_Element,
-            Keyword     => Cursor.Data.Tokens.Keywords.First,
-            Nonterminal => Rule_Lists.No_Element);
-
-         return String_Pair_Lists.Has_Element (Cursor.Keyword);
-
-      when Terminals_Keywords =>
-
-         Cursor :=
-           (Data        => Cursor.Data,
-            Kind        => Terminals_Others,
-            ID          => Cursor.ID,
-            Token_Kind  => Cursor.Data.Tokens.Tokens.First,
-            Token_Item  => String_Triple_Lists.No_Element,
-            Keyword     => String_Pair_Lists.No_Element,
-            Nonterminal => Rule_Lists.No_Element);
-
-         if WisiToken.BNF.Token_Lists.Has_Element (Cursor.Token_Kind) then
-            Cursor.Token_Item := Cursor.Data.Tokens.Tokens 
(Cursor.Token_Kind).Tokens.First;
-            return WisiToken.BNF.String_Triple_Lists.Has_Element 
(Cursor.Token_Item);
-         else
-            return False;
-         end if;
-
-      when Terminals_Others =>
-
-         Cursor :=
-           (Data        => Cursor.Data,
-            Kind        => EOI,
-            ID          => Cursor.ID,
-            Token_Kind  => WisiToken.BNF.Token_Lists.No_Element,
-            Token_Item  => String_Triple_Lists.No_Element,
-            Keyword     => String_Pair_Lists.No_Element,
-            Nonterminal => Rule_Lists.No_Element);
-
-         return True;
-
-      when EOI =>
-         if Nonterminals then
-            if Rule_Lists.Has_Element (Cursor.Data.Tokens.Rules.First) then
-               Cursor :=
-                 (Data        => Cursor.Data,
-                  Kind        => WisiToken_Accept,
-                  ID          => Cursor.ID,
-                  Token_Kind  => WisiToken.BNF.Token_Lists.No_Element,
-                  Token_Item  => String_Triple_Lists.No_Element,
-                  Keyword     => String_Pair_Lists.No_Element,
-                  Nonterminal => Rule_Lists.No_Element);
-            else
-               Cursor.Kind := Done;
-            end if;
-            return True;
-         else
-            Cursor.Kind := Done;
-            return True;
-         end if;
-
-      when WisiToken_Accept =>
-
-         Cursor :=
-           (Data        => Cursor.Data,
-            Kind        => Nonterminal,
-            ID          => Cursor.ID,
-            Token_Kind  => WisiToken.BNF.Token_Lists.No_Element,
-            Token_Item  => String_Triple_Lists.No_Element,
-            Keyword     => String_Pair_Lists.No_Element,
-            Nonterminal => Cursor.Data.Tokens.Rules.First);
-
-         --  Can't get here with no rules
-         return True;
-
-      when Nonterminal =>
-         Cursor.Kind := Done;
-         return True;
-
-      when Done =>
-         return True;
-      end case;
-   end Next_Kind_Internal;
-
-   function First
-     (Data         : aliased in Generate_Data;
-      Non_Grammar  :         in Boolean;
-      Nonterminals :         in Boolean)
-     return Token_Cursor
-   is
-      Cursor : Token_Cursor :=
-        (Data        => Data'Access,
-         Kind        => Non_Grammar_Kind,
-         ID          => Token_ID'First,
-         Token_Kind  => Data.Tokens.Non_Grammar.First,
-         Token_Item  => String_Triple_Lists.No_Element,
-         Keyword     => String_Pair_Lists.No_Element,
-         Nonterminal => Rule_Lists.No_Element);
-   begin
-      if Non_Grammar then
-         if WisiToken.BNF.Token_Lists.Has_Element (Cursor.Token_Kind) then
-            Cursor.Token_Item := Cursor.Data.Tokens.Non_Grammar 
(Cursor.Token_Kind).Tokens.First;
-            if WisiToken.BNF.String_Triple_Lists.Has_Element 
(Cursor.Token_Item) then
-               return Cursor;
-            end if;
-         end if;
-      end if;
-
-      --  There are no non_grammar tokens, or Non_Grammar false
-      loop
-         exit when Next_Kind_Internal (Cursor, Nonterminals);
-      end loop;
-      return Cursor;
-   end First;
-
-   procedure Next (Cursor : in out Token_Cursor; Nonterminals : in Boolean)
-   is begin
-      Cursor.ID := Cursor.ID + 1;
-
-      case Cursor.Kind is
-      when Non_Grammar_Kind =>
-         String_Triple_Lists.Next (Cursor.Token_Item);
-         if String_Triple_Lists.Has_Element (Cursor.Token_Item) then
-            return;
-         else
-            WisiToken.BNF.Token_Lists.Next (Cursor.Token_Kind);
-
-            if WisiToken.BNF.Token_Lists.Has_Element (Cursor.Token_Kind) then
-               Cursor.Token_Item := Cursor.Data.Tokens.Non_Grammar 
(Cursor.Token_Kind).Tokens.First;
-               if String_Triple_Lists.Has_Element (Cursor.Token_Item) then
-                  return;
-               end if;
-            end if;
-         end if;
-
-         loop
-            exit when Next_Kind_Internal (Cursor, Nonterminals);
-         end loop;
-         return;
-
-      when Terminals_Keywords =>
-         --  Keywords before other terminals, so they have precedence over 
Identifiers
-
-         String_Pair_Lists.Next (Cursor.Keyword);
-         if String_Pair_Lists.Has_Element (Cursor.Keyword) then
-            return;
-         end if;
-
-         loop
-            exit when Next_Kind_Internal (Cursor, Nonterminals);
-         end loop;
-         return;
-
-      when Terminals_Others =>
-         WisiToken.BNF.String_Triple_Lists.Next (Cursor.Token_Item);
-         if WisiToken.BNF.String_Triple_Lists.Has_Element (Cursor.Token_Item) 
then
-            return;
-         else
-            WisiToken.BNF.Token_Lists.Next (Cursor.Token_Kind);
-            if WisiToken.BNF.Token_Lists.Has_Element (Cursor.Token_Kind) then
-               Cursor.Token_Item := Cursor.Data.Tokens.Tokens 
(Cursor.Token_Kind).Tokens.First;
-               if WisiToken.BNF.String_Triple_Lists.Has_Element 
(Cursor.Token_Item) then
-                  return;
-               end if;
-            end if;
-         end if;
-
-         loop
-            exit when Next_Kind_Internal (Cursor, Nonterminals);
-         end loop;
-         return;
-
-      when EOI =>
-         if Next_Kind_Internal (Cursor, Nonterminals) then
-            return;
-         else
-            raise SAL.Programmer_Error;
-         end if;
-
-      when WisiToken_Accept =>
-         if Next_Kind_Internal (Cursor, Nonterminals) then
-            return;
-         else
-            raise SAL.Programmer_Error;
-         end if;
-
-      when Nonterminal =>
-         Rule_Lists.Next (Cursor.Nonterminal);
-         if Rule_Lists.Has_Element (Cursor.Nonterminal) then
-            return;
-         end if;
-
-         loop
-            exit when Next_Kind_Internal (Cursor, Nonterminals);
-         end loop;
-         return;
-
-      when Done =>
-         null;
-      end case;
-   end Next;
-
-   function Is_Done (Cursor : in Token_Cursor) return Boolean
-   is begin
-      return Cursor.Kind = Done;
-   end Is_Done;
-
-   function ID (Cursor : in Token_Cursor) return Token_ID
-   is begin
-      return Cursor.ID;
-   end ID;
-
-   function Name (Cursor : in Token_Cursor) return String
-   is begin
-      return Cursor.Data.Descriptor.Image (Cursor.ID).all;
-   end Name;
-
-   function Kind (Cursor : in Token_Cursor) return String
-   is begin
-      case Cursor.Kind is
-      when Non_Grammar_Kind =>
-         return -Cursor.Data.Tokens.Non_Grammar (Cursor.Token_Kind).Kind;
-
-      when Terminals_Keywords =>
-         return "keyword";
-
-      when Terminals_Others =>
-         return -Cursor.Data.Tokens.Tokens (Cursor.Token_Kind).Kind;
-
-      when EOI =>
-         return "EOI";
-
-      when WisiToken_Accept =>
-         return "accept";
-
-      when Nonterminal =>
-         return "nonterminal";
-
-      when Done =>
-         raise SAL.Programmer_Error with "token cursor is done";
-      end case;
-   end Kind;
-
-   function Value (Cursor : in Token_Cursor) return String
-   is begin
-      case Cursor.Kind is
-      when Non_Grammar_Kind =>
-         return -Cursor.Data.Tokens.Non_Grammar (Cursor.Token_Kind).Tokens 
(Cursor.Token_Item).Value;
-
-      when Terminals_Keywords =>
-         return -Cursor.Data.Tokens.Keywords (Cursor.Keyword).Value;
-
-      when Terminals_Others =>
-         return -Cursor.Data.Tokens.Tokens (Cursor.Token_Kind).Tokens 
(Cursor.Token_Item).Value;
-
-      when EOI | WisiToken_Accept | Nonterminal =>
-            return "";
-
-      when Done =>
-         raise SAL.Programmer_Error with "token cursor is done";
-      end case;
-   end Value;
-
-   function Repair_Image (Cursor : in Token_Cursor) return String
-   is begin
-      case Cursor.Kind is
-      when Non_Grammar_Kind =>
-         return -Cursor.Data.Tokens.Non_Grammar (Cursor.Token_Kind).Tokens 
(Cursor.Token_Item).Repair_Image;
-
-      when Terminals_Keywords =>
-         return "";
-
-      when Terminals_Others =>
-         return -Cursor.Data.Tokens.Tokens (Cursor.Token_Kind).Tokens 
(Cursor.Token_Item).Repair_Image;
-
-      when EOI | WisiToken_Accept | Nonterminal =>
-            return "";
-
-      when Done =>
-         raise SAL.Programmer_Error with "token cursor is done";
-      end case;
-   end Repair_Image;
-
-   function To_Conflicts
-     (Data             : aliased in out Generate_Data;
-      Conflicts        :         in     WisiToken.BNF.Conflict_Lists.List;
-      Source_File_Name :         in     String)
-     return WisiToken.Generate.LR.Conflict_Lists.List
-   is
-      use WisiToken.Generate.LR;
-      Result   : WisiToken.Generate.LR.Conflict_Lists.List;
-      Conflict : WisiToken.Generate.LR.Conflict;
-   begin
-      for Item of Conflicts loop
-         begin
-            Conflict :=
-              (Conflict_Parse_Actions'Value (-Item.Action_A),
-               Find_Token_ID (Data, -Item.LHS_A),
-               Conflict_Parse_Actions'Value (-Item.Action_B),
-               Find_Token_ID (Data, -Item.LHS_B),
-               -1,
-               Find_Token_ID (Data, -Item.On));
-
-            Result.Append (Conflict);
-         exception
-         when E : Not_Found =>
-            if not Data.Ignore_Conflicts then
-               Put_Error
-                 (Error_Message
-                    (Source_File_Name, Item.Source_Line, 
Ada.Exceptions.Exception_Message (E)));
-            end if;
-         end;
-      end loop;
-      return Result;
-   end To_Conflicts;
-
-   function To_Nonterminal_ID_Set
-     (Data : aliased in Generate_Data;
-      Item :         in String_Lists.List)
-     return Token_ID_Set
-   is
-      Result : Token_ID_Set := (Data.Descriptor.First_Nonterminal .. 
Data.Descriptor.Last_Nonterminal => False);
-   begin
-      for Token of Item loop
-         Result (Find_Token_ID (Data, Token)) := True;
-      end loop;
-      return Result;
-   end To_Nonterminal_ID_Set;
-
-   function To_McKenzie_Param
-     (Data : aliased in Generate_Data;
-      Item :         in McKenzie_Recover_Param_Type)
-     return WisiToken.Parse.LR.McKenzie_Param_Type
-   is
-      use Ada.Strings.Unbounded;
-
-      Result : WisiToken.Parse.LR.McKenzie_Param_Type :=
-        --  We use an aggregate, and overwrite some below, so the compiler
-        --  reminds us to change this when we modify McKenzie_Param_Type.
-        (Data.Descriptor.First_Terminal,
-         Data.Descriptor.Last_Terminal,
-         Data.Descriptor.First_Nonterminal,
-         Data.Descriptor.Last_Nonterminal,
-         Insert                      => (others => Item.Default_Insert),
-         Delete                      => (others => 
Item.Default_Delete_Terminal),
-         Push_Back                   => (others => Item.Default_Push_Back),
-         Undo_Reduce                 => (others => Item.Default_Push_Back), -- 
no separate default for undo_reduce
-         Minimal_Complete_Cost_Delta => Item.Minimal_Complete_Cost_Delta,
-         Fast_Forward                => Item.Fast_Forward,
-         Matching_Begin              => Item.Matching_Begin,
-         Ignore_Check_Fail           => Item.Ignore_Check_Fail,
-         Task_Count                  => 0,
-         Check_Limit                 => Item.Check_Limit,
-         Check_Delta_Limit           => Item.Check_Delta_Limit,
-         Enqueue_Limit               => Item.Enqueue_Limit);
-   begin
-      for Pair of Item.Delete loop
-         Result.Delete (Find_Token_ID (Data, -Pair.Name)) := Natural'Value 
(-Pair.Value);
-      end loop;
-      for Pair of Item.Insert loop
-         Result.Insert (Find_Token_ID (Data, -Pair.Name)) := Natural'Value 
(-Pair.Value);
-      end loop;
-      for Pair of Item.Push_Back loop
-         Result.Push_Back (Find_Token_ID (Data, -Pair.Name)) := Natural'Value 
(-Pair.Value);
-      end loop;
-      for Pair of Item.Undo_Reduce loop
-         Result.Undo_Reduce (Find_Token_ID (Data, -Pair.Name)) := 
Natural'Value (-Pair.Value);
-      end loop;
-
-      return Result;
-   end To_McKenzie_Param;
-
-   procedure Put_Stats
-     (Input_Data    : in WisiToken_Grammar_Runtime.User_Data_Type;
-      Generate_Data : in Generate_Utils.Generate_Data)
-   is
-      use Ada.Text_IO;
-   begin
-      New_Line;
-      Put_Line
-        (Integer'Image (Input_Data.Rule_Count) & " rules," &
-           Integer'Image (Input_Data.Action_Count) & " user actions," &
-           Integer'Image (Input_Data.Check_Count) & " checks," &
-           WisiToken.State_Index'Image (Generate_Data.Parser_State_Count) & " 
states");
-   end Put_Stats;
-
-end WisiToken.BNF.Generate_Utils;
diff --git a/packages/wisi/wisitoken-bnf-generate_utils.ads 
b/packages/wisi/wisitoken-bnf-generate_utils.ads
deleted file mode 100644
index a2f31a2..0000000
--- a/packages/wisi/wisitoken-bnf-generate_utils.ads
+++ /dev/null
@@ -1,174 +0,0 @@
---  Abstract :
---
---  Utilities for translating input file structures to WisiToken
---  structures needed for LALR.Generate.
---
---  Copyright (C) 2014, 2015, 2017 - 2020 Free Software Foundation, Inc.
---
---  The WisiToken package is free software; you can redistribute it
---  and/or modify it under terms of the GNU General Public License as
---  published by the Free Software Foundation; either version 3, or
---  (at your option) any later version. This library 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.
---
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-with Ada.Iterator_Interfaces;
-with WisiToken.Generate.LR;
-with WisiToken.Parse.LR;
-with WisiToken.Productions;
-with WisiToken_Grammar_Runtime;
-package WisiToken.BNF.Generate_Utils is
-
-   EOI_Name : constant String := "Wisi_EOI";
-   --  EOI_Name is used for Descriptor.EOI_ID token; it must match Emacs 
ada-mode
-   --  wisi.el wisi-eoi-term. It must be a valid Ada identifier when
-   --  "_ID" is appended.
-
-   WisiToken_Accept_Name : constant String := "wisitoken_accept";
-
-   type Generate_Data (Tokens : not null access constant WisiToken.BNF.Tokens) 
is limited record
-      Descriptor : WisiToken.Descriptor_Access;
-      Grammar    : WisiToken.Productions.Prod_Arrays.Vector;
-
-      Action_Names : Names_Array_Array_Access;
-      Check_Names  : Names_Array_Array_Access;
-      --  Names of subprograms for each grammar semantic action and check;
-      --  non-null only if there is an action or check in the grammar.
-
-      Start_ID        : WisiToken.Token_ID;
-      Source_Line_Map : WisiToken.Productions.Source_Line_Maps.Vector;
-
-      --  The following fields are LR specific; so far, it's not worth
-      --  splitting them out.
-
-      Ignore_Conflicts   : Boolean                       := False;
-      Conflicts          : WisiToken.Generate.LR.Conflict_Lists.List;
-      LR_Parse_Table     : WisiToken.Parse.LR.Parse_Table_Ptr;
-      Parser_State_Count : WisiToken.Unknown_State_Index := 0;
-   end record;
-
-   function Initialize
-     (Input_Data       : aliased in WisiToken_Grammar_Runtime.User_Data_Type;
-      Ignore_Conflicts :         in Boolean := False)
-     return Generate_Data;
-
-   function Find_Token_ID (Data : aliased in Generate_Data; Token : in String) 
return Token_ID;
-
-   type Token_Container (Data : not null access constant Generate_Data) is 
tagged null record
-   with
-     Constant_Indexing => Constant_Reference,
-     Default_Iterator  => Iterate,
-     Iterator_Element  => Ada.Strings.Unbounded.Unbounded_String;
-   --  We need a container type to define an iterator; the actual data is
-   --  in Data.Tokens. The Iterator_Element is given by Token_Name below.
-
-   function All_Tokens (Data : aliased in Generate_Data) return 
Token_Container;
-
-   type Token_Constant_Reference_Type
-     (Element : not null access constant 
Ada.Strings.Unbounded.Unbounded_String)
-     is null record
-   with Implicit_Dereference => Element;
-
-   type Token_Cursor (<>) is private;
-   --  Iterate thru Keywords, Tokens, Rules in a canonical order:
-   --
-   --  1. Non_Grammar
-   --  2. Keywords
-   --  3. other terminal tokens, in declaration order
-   --  4. EOI
-   --  5. Accept
-   --  6. Nonterminals
-   --
-   --  Within each group, tokens occur in the order they were declared in
-   --  the grammar file.
-
-   function Constant_Reference
-     (Container : aliased in Token_Container'Class;
-      Cursor    :         in Token_Cursor)
-     return Token_Constant_Reference_Type;
-
-   function Is_Done (Cursor : in Token_Cursor) return Boolean;
-   function Has_Element (Cursor : in Token_Cursor) return Boolean is (not 
Is_Done (Cursor));
-   package Iterator_Interfaces is new Ada.Iterator_Interfaces (Token_Cursor, 
Has_Element);
-   function Iterate
-     (Container    : aliased    Token_Container;
-      Non_Grammar  :         in Boolean := True;
-      Nonterminals :         in Boolean := True)
-     return Iterator_Interfaces.Forward_Iterator'Class;
-
-   function First
-     (Data         : aliased in Generate_Data;
-      Non_Grammar  :         in Boolean;
-      Nonterminals :         in Boolean)
-     return Token_Cursor;
-   procedure Next (Cursor : in out Token_Cursor; Nonterminals : in Boolean);
-
-   function ID (Cursor : in Token_Cursor) return Token_ID;
-
-   function Name (Cursor : in Token_Cursor) return String;
-   --  Return the token name from the .wy file:
-   --  Keywords: Keywords (i).name
-   --  Tokens  : Tokens (i).Tokens (j).name
-   --  Rules   : Rules (i).Left_Hand_Side
-
-   function Kind (Cursor : in Token_Cursor) return String;
-   --  Return the token kind from the .wy file:
-   --  Keywords: "keyword"
-   --  Tokens  : Tokens (i).Kind
-   --  Rules   : "nonterminal"
-
-   function Value (Cursor : in Token_Cursor) return String;
-   --  Return the token value from the .wy file:
-   --  Keywords: Keywords (i).value
-   --  Tokens  : Tokens (i).Tokens (j).Value
-   --  Rules   : empty string (they have no Value)
-
-   function Repair_Image (Cursor : in Token_Cursor) return String;
-   --  Return the token repair image from the .wy file:
-   --  Keywords: empty string
-   --  Tokens  : Tokens (i).Tokens (j).Repair_Image
-   --  Rules   : empty string
-
-   function To_Conflicts
-     (Data             : aliased in out Generate_Data;
-      Conflicts        :         in     WisiToken.BNF.Conflict_Lists.List;
-      Source_File_Name :         in     String)
-     return WisiToken.Generate.LR.Conflict_Lists.List;
-   --  Not included in Initialize because algorithms have no conflicts.
-
-   function To_Nonterminal_ID_Set
-     (Data : aliased in Generate_Data;
-      Item :         in String_Lists.List)
-     return Token_ID_Set;
-
-   function To_McKenzie_Param
-     (Data : aliased in Generate_Data;
-      Item :         in McKenzie_Recover_Param_Type)
-     return WisiToken.Parse.LR.McKenzie_Param_Type;
-
-   procedure Put_Stats
-     (Input_Data    : in WisiToken_Grammar_Runtime.User_Data_Type;
-      Generate_Data : in Generate_Utils.Generate_Data);
-
-private
-
-   type Token_Cursor_Kind is
-     (Non_Grammar_Kind, Terminals_Keywords, Terminals_Others, EOI, 
WisiToken_Accept, Nonterminal, Done);
-
-   type Token_Cursor (Data : not null access constant Generate_Data) is record
-      Kind        : Token_Cursor_Kind;
-      ID          : Token_ID;
-      Token_Kind  : WisiToken.BNF.Token_Lists.Cursor; -- Non_Grammar or 
Tokens, depending on Kind
-      Token_Item  : String_Triple_Lists.Cursor;
-      Keyword     : String_Pair_Lists.Cursor;
-      Nonterminal : Rule_Lists.Cursor;
-   end record;
-
-end WisiToken.BNF.Generate_Utils;
diff --git a/packages/wisi/wisitoken-bnf-output_ada.adb 
b/packages/wisi/wisitoken-bnf-output_ada.adb
deleted file mode 100644
index 3857a0f..0000000
--- a/packages/wisi/wisitoken-bnf-output_ada.adb
+++ /dev/null
@@ -1,512 +0,0 @@
---  Abstract :
---
---  Output Ada code implementing the grammar defined by input
---  parameters, and a parser for that grammar. The grammar parser
---  actions must be Ada.
---
---  Copyright (C) 2017 - 2020 Free Software Foundation, Inc.
---
---  The WisiToken package is free software; you can redistribute it
---  and/or modify it under terms of the GNU General Public License as
---  published by the Free Software Foundation; either version 3, or
---  (at your option) any later version. This library 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.
---
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (Modified_GPL);
-
-with Ada.Strings.Fixed;
-with Ada.Text_IO; use Ada.Text_IO;
-with GNAT.Regexp;
-with WisiToken.BNF.Generate_Packrat;
-with WisiToken.BNF.Generate_Utils;
-with WisiToken.BNF.Output_Ada_Common; use WisiToken.BNF.Output_Ada_Common;
-with WisiToken.Generate.Packrat;
-with WisiToken_Grammar_Runtime;
-procedure WisiToken.BNF.Output_Ada
-  (Input_Data            :         in WisiToken_Grammar_Runtime.User_Data_Type;
-   Output_File_Name_Root :         in String;
-   Generate_Data         : aliased in 
WisiToken.BNF.Generate_Utils.Generate_Data;
-   Packrat_Data          :         in WisiToken.Generate.Packrat.Data;
-   Tuple                 :         in Generate_Tuple;
-   Test_Main             :         in Boolean;
-   Multiple_Tuples       :         in Boolean)
-is
-   Common_Data : Output_Ada_Common.Common_Data := 
WisiToken.BNF.Output_Ada_Common.Initialize
-     (Input_Data, Tuple, Output_File_Name_Root, Check_Interface => False);
-
-   Gen_Alg_Name : constant String :=
-     (if Test_Main or Multiple_Tuples
-      then "_" & Generate_Algorithm_Image (Common_Data.Generate_Algorithm).all
-      else "");
-
-   function Symbol_Regexp (Item : in String) return String
-   is begin
-      --  Return a regular expression string that matches Item as a symbol;
-      --  it must be preceded and followed by non-symbol characters.
-      --
-      --  GNAT.Regexp does not have a char for 'end of string', so we hope
-      --  that doesn't occur. Sigh.
-      return ".*[ (\.]" & Item & "[ );\.,].*";
-   end Symbol_Regexp;
-
-   procedure Create_Ada_Actions_Body
-     (Action_Names : not null access WisiToken.Names_Array_Array;
-      Check_Names  : not null access WisiToken.Names_Array_Array;
-      Label_Count  : in              Ada.Containers.Count_Type;
-      Package_Name : in              String)
-   is
-      use all type Ada.Containers.Count_Type;
-      use GNAT.Regexp;
-      use Generate_Utils;
-      use WisiToken.Generate;
-
-      File_Name : constant String := Output_File_Name_Root & "_actions.adb";
-
-      User_Data_Regexp : constant Regexp := Compile (Symbol_Regexp 
("User_Data"), Case_Sensitive => False);
-      Tree_Regexp      : constant Regexp := Compile (Symbol_Regexp ("Tree"), 
Case_Sensitive      => False);
-      Nonterm_Regexp   : constant Regexp := Compile (Symbol_Regexp 
("Nonterm"), Case_Sensitive   => False);
-      Tokens_Regexp    : constant Regexp := Compile (Symbol_Regexp ("Tokens"), 
Case_Sensitive    => False);
-
-      Body_File : File_Type;
-   begin
-      Create (Body_File, Out_File, File_Name);
-      Set_Output (Body_File);
-      Indent := 1;
-      Put_File_Header (Ada_Comment, Use_Tuple => True, Tuple => Tuple);
-      Put_Raw_Code (Ada_Comment, Input_Data.Raw_Code (Copyright_License));
-      Put_Raw_Code (Ada_Comment, Input_Data.Raw_Code (Actions_Body_Context));
-      New_Line;
-
-      if Label_Count > 0 then
-         Put_Line ("with SAL;");
-      end if;
-
-      Put_Line ("package body " & Package_Name & " is");
-      Indent := Indent + 3;
-      New_Line;
-
-      if Input_Data.Check_Count > 0 then
-         Indent_Line ("use WisiToken.Semantic_Checks;");
-         New_Line;
-      end if;
-
-      Put_Raw_Code (Ada_Comment, Input_Data.Raw_Code (Actions_Body_Pre));
-
-      --  generate Action and Check subprograms.
-
-      for Rule of Input_Data.Tokens.Rules loop
-         --  No need for a Token_Cursor here, since we only need the
-         --  nonterminals.
-         declare
-            use Ada.Strings.Unbounded;
-
-            LHS_ID    : constant WisiToken.Token_ID := Find_Token_ID 
(Generate_Data, -Rule.Left_Hand_Side);
-            RHS_Index : Integer                     := 0;
-
-            function Is_Elisp (Action : in Unbounded_String) return Boolean
-            is begin
-               return Length (Action) >= 6 and then
-                 (Slice (Action, 1, 6) = "(progn" or
-                    Slice (Action, 1, 5) = "wisi-");
-            end Is_Elisp;
-
-            procedure Put_Labels (RHS : in RHS_Type; Line : in String)
-            is
-               Output : array (Rule.Labels.First_Index .. 
Rule.Labels.Last_Index) of Boolean := (others => False);
-
-               procedure Update_Output (Label : in String)
-               is begin
-                  for I in Rule.Labels.First_Index .. Rule.Labels.Last_Index 
loop
-                     if Label = Rule.Labels (I) then
-                        Output (I) := True;
-                     end if;
-                  end loop;
-               end Update_Output;
-            begin
-               for I in RHS.Tokens.First_Index .. RHS.Tokens.Last_Index loop
-                  if Length (RHS.Tokens (I).Label) > 0 then
-                     declare
-                        Label : constant String := -RHS.Tokens (I).Label;
-                     begin
-                        if Match (Line, Compile (Symbol_Regexp (Label), 
Case_Sensitive => False)) then
-                           Indent_Line
-                             (Label & " : constant SAL.Peek_Type :=" & 
SAL.Peek_Type'Image (I) & ";");
-                           Update_Output (Label);
-                        end if;
-                     end;
-                  end if;
-               end loop;
-
-               for I in Rule.Labels.First_Index .. Rule.Labels.Last_Index loop
-                  if not Output (I) and
-                    Match (Line, Compile (Symbol_Regexp (-Rule.Labels (I)), 
Case_Sensitive => False))
-                  then
-                     Indent_Line (-Rule.Labels (I) & " : constant 
SAL.Base_Peek_Type := SAL.Base_Peek_Type'First;");
-                  end if;
-               end loop;
-            end Put_Labels;
-
-         begin
-            for RHS of Rule.Right_Hand_Sides loop
-               if Length (RHS.Action) > 0 and then not Is_Elisp (RHS.Action) 
then
-                  declare
-                     Line : constant String := -RHS.Action;
-                     --  Actually multiple lines; we assume the formatting is 
adequate.
-
-                     Name : constant String := Action_Names 
(LHS_ID)(RHS_Index).all;
-
-                     Unref_User_Data : Boolean := True;
-                     Unref_Tree      : Boolean := True;
-                     Unref_Nonterm   : Boolean := True;
-                     Unref_Tokens    : Boolean := True;
-                     Need_Comma      : Boolean := False;
-
-                     procedure Check_Unref (Line : in String)
-                     is begin
-                        if Match (Line, User_Data_Regexp) then
-                           Unref_User_Data := False;
-                        end if;
-                        if Match (Line, Tree_Regexp) then
-                           Unref_Tree := False;
-                        end if;
-                        if Match (Line, Nonterm_Regexp) then
-                           Unref_Nonterm := False;
-                        end if;
-                        if Match (Line, Tokens_Regexp) then
-                           Unref_Tokens := False;
-                        end if;
-                     end Check_Unref;
-                  begin
-                     Check_Unref (Line);
-                     Indent_Line ("procedure " & Name);
-                     Indent_Line (" (User_Data : in out 
WisiToken.Syntax_Trees.User_Data_Type'Class;");
-                     Indent_Line ("  Tree      : in out 
WisiToken.Syntax_Trees.Tree;");
-                     Indent_Line ("  Nonterm   : in     
WisiToken.Valid_Node_Index;");
-                     Indent_Line ("  Tokens    : in     
WisiToken.Valid_Node_Index_Array)");
-                     Indent_Line ("is");
-
-                     Indent := Indent + 3;
-                     if Unref_User_Data or Unref_Tree or Unref_Nonterm or 
Unref_Tokens then
-                        Indent_Start ("pragma Unreferenced (");
-
-                        if Unref_User_Data then
-                           Put ("User_Data");
-                           Need_Comma := True;
-                        end if;
-                        if Unref_Tree then
-                           Put ((if Need_Comma then ", " else "") & "Tree");
-                           Need_Comma := True;
-                        end if;
-                        if Unref_Nonterm then
-                           Put ((if Need_Comma then ", " else "") & "Nonterm");
-                           Need_Comma := True;
-                        end if;
-                        if Unref_Tokens then
-                           Put ((if Need_Comma then ", " else "") & "Tokens");
-                           Need_Comma := True;
-                        end if;
-                        Put_Line (");");
-                     end if;
-
-                     Put_Labels (RHS, Line);
-                     Indent := Indent - 3;
-                     Indent_Line ("begin");
-                     Indent := Indent + 3;
-
-                     Indent_Line (Line);
-                     Indent := Indent - 3;
-                     Indent_Line ("end " & Name & ";");
-                     New_Line;
-                  end;
-               end if;
-
-               if Length (RHS.Check) > 0 and then not Is_Elisp (RHS.Check) then
-                  declare
-                     use Ada.Strings.Fixed;
-                     Line          : constant String  := -RHS.Check;
-                     Name          : constant String  := Check_Names 
(LHS_ID)(RHS_Index).all;
-                     Unref_Lexer   : constant Boolean := 0 = Index (Line, 
"Lexer");
-                     Unref_Nonterm : constant Boolean := 0 = Index (Line, 
"Nonterm");
-                     Unref_Tokens  : constant Boolean := 0 = Index (Line, 
"Tokens");
-                     Unref_Recover : constant Boolean := 0 = Index (Line, 
"Recover_Active");
-                     Need_Comma    : Boolean          := False;
-                  begin
-                     Indent_Line ("function " & Name);
-                     Indent_Line (" (Lexer          : access constant 
WisiToken.Lexer.Instance'Class;");
-                     Indent_Line ("  Nonterm        : in out 
WisiToken.Recover_Token;");
-                     Indent_Line ("  Tokens         : in     
WisiToken.Recover_Token_Array;");
-                     Indent_Line ("  Recover_Active : in     Boolean)");
-                     Indent_Line (" return 
WisiToken.Semantic_Checks.Check_Status");
-                     Indent_Line ("is");
-
-                     Indent := Indent + 3;
-                     if Unref_Lexer or Unref_Nonterm or Unref_Tokens or 
Unref_Recover then
-                        Indent_Start ("pragma Unreferenced (");
-
-                        if Unref_Lexer then
-                           Put ("Lexer");
-                           Need_Comma := True;
-                        end if;
-                        if Unref_Nonterm then
-                           Put ((if Need_Comma then ", " else "") & "Nonterm");
-                           Need_Comma := True;
-                        end if;
-                        if Unref_Tokens then
-                           Put ((if Need_Comma then ", " else "") & "Tokens");
-                           Need_Comma := True;
-                        end if;
-                        if Unref_Recover then
-                           Put ((if Need_Comma then ", " else "") & 
"Recover_Active");
-                           Need_Comma := True;
-                        end if;
-                        Put_Line (");");
-                     end if;
-
-                     Put_Labels (RHS, Line);
-                     Indent := Indent - 3;
-
-                     Indent_Line ("begin");
-                     Indent := Indent + 3;
-                     Indent_Line (Line);
-                     Indent := Indent - 3;
-                     Indent_Line ("end " & Name & ";");
-                     New_Line;
-                  end;
-               end if;
-
-               RHS_Index := RHS_Index + 1;
-            end loop;
-         end;
-      end loop;
-
-      Put_Raw_Code (Ada_Comment, Input_Data.Raw_Code (Actions_Body_Post));
-
-      Put_Line ("end " & Package_Name & ";");
-      Close (Body_File);
-
-      Set_Output (Standard_Output);
-
-   end Create_Ada_Actions_Body;
-
-   procedure Create_Ada_Main_Body
-     (Actions_Package_Name : in String;
-      Main_Package_Name    : in String)
-   is
-      use WisiToken.Generate;
-
-      File_Name         : constant String := To_Lower (Main_Package_Name) & 
".adb";
-      re2c_Package_Name : constant String := -Common_Data.Lower_File_Name_Root 
& "_re2c_c";
-
-      Body_File : File_Type;
-   begin
-      Create (Body_File, Out_File, File_Name);
-      Set_Output (Body_File);
-      Indent := 1;
-
-      Put_File_Header (Ada_Comment, Use_Tuple => True, Tuple => Tuple);
-      Put_Raw_Code (Ada_Comment, Input_Data.Raw_Code (Copyright_License));
-      New_Line;
-
-      if (case Common_Data.Generate_Algorithm is
-          when LR_Generate_Algorithm => Input_Data.Action_Count > 0 or 
Input_Data.Check_Count > 0,
-          when Packrat_Generate_Algorithm | External => 
Input_Data.Action_Count > 0)
-      then
-         Put_Line ("with " & Actions_Package_Name & "; use " & 
Actions_Package_Name & ";");
-      end if;
-
-      case Common_Data.Lexer is
-      when None | Elisp_Lexer =>
-         null;
-
-      when re2c_Lexer =>
-         Put_Line ("with WisiToken.Lexer.re2c;");
-         Put_Line ("with " & re2c_Package_Name & ";");
-      end case;
-
-      case Common_Data.Generate_Algorithm is
-      when LR_Generate_Algorithm =>
-         null;
-
-      when Packrat_Gen =>
-         Put_Line ("with WisiToken.Parse.Packrat.Generated;");
-
-      when Packrat_Proc =>
-         Put_Line ("with WisiToken.Parse.Packrat.Procedural;");
-         Put_Line ("with WisiToken.Productions;");
-
-      when External =>
-         null;
-      end case;
-
-      Put_Line ("package body " & Main_Package_Name & " is");
-      Indent := Indent + 3;
-      New_Line;
-
-      case Common_Data.Lexer is
-      when None | Elisp_Lexer =>
-         null;
-
-      when re2c_Lexer =>
-         Indent_Line ("package Lexer is new WisiToken.Lexer.re2c");
-         Indent_Line ("  (" & re2c_Package_Name & ".New_Lexer,");
-         Indent_Line ("   " & re2c_Package_Name & ".Free_Lexer,");
-         Indent_Line ("   " & re2c_Package_Name & ".Reset_Lexer,");
-         Indent_Line ("   " & re2c_Package_Name & ".Next_Token);");
-         New_Line;
-      end case;
-
-      case Common_Data.Generate_Algorithm is
-      when LR_Generate_Algorithm =>
-         LR_Create_Create_Parser (Input_Data, Common_Data, Generate_Data);
-
-      when Packrat_Gen =>
-         WisiToken.BNF.Generate_Packrat (Packrat_Data, Generate_Data);
-
-         Packrat_Create_Create_Parser (Common_Data, Generate_Data, 
Packrat_Data);
-
-      when Packrat_Proc =>
-         Packrat_Create_Create_Parser (Common_Data, Generate_Data, 
Packrat_Data);
-
-      when External =>
-         External_Create_Create_Grammar (Generate_Data);
-      end case;
-
-      Put_Line ("end " & Main_Package_Name & ";");
-      Close (Body_File);
-      Set_Output (Standard_Output);
-   end Create_Ada_Main_Body;
-
-   procedure Create_Ada_Test_Main
-     (Actions_Package_Name : in String;
-      Main_Package_Name    : in String)
-   is
-      use WisiToken.Generate;
-
-      Generic_Package_Name : constant String :=
-        (case Common_Data.Generate_Algorithm is
-         when LR_Generate_Algorithm =>
-           (if Input_Data.Language_Params.Error_Recover then
-              (if Common_Data.Text_Rep
-               then "Gen_LR_Text_Rep_Parser_Run"
-               else "Gen_LR_Parser_Run")
-            else
-              (if Common_Data.Text_Rep
-               then "Gen_LR_Text_Rep_Parser_No_Recover_Run"
-               else "Gen_LR_Parser_No_Recover_Run")),
-
-         when Packrat_Generate_Algorithm => "Gen_Packrat_Parser_Run",
-         when External => raise SAL.Programmer_Error);
-
-      Unit_Name : constant String := File_Name_To_Ada (Output_File_Name_Root) &
-        "_" & Generate_Algorithm'Image (Common_Data.Generate_Algorithm) & 
"_Run";
-
-      Default_Language_Runtime_Package : constant String := 
"WisiToken.Parse.LR.McKenzie_Recover." & File_Name_To_Ada
-        (Output_File_Name_Root);
-
-      File_Name : constant String := To_Lower (Unit_Name) & ".ads";
-
-      File : File_Type;
-   begin
-      Create (File, Out_File, File_Name);
-      Set_Output (File);
-      Indent := 1;
-
-      Put_File_Header (Ada_Comment, Use_Tuple => True, Tuple => Tuple);
-      --  no Copyright_License; just a test file
-      New_Line;
-
-      Put_Line ("with " & Generic_Package_Name & ";");
-      Put_Line ("with " & Actions_Package_Name & ";");
-      Put_Line ("with " & Main_Package_Name & ";");
-      if Input_Data.Language_Params.Error_Recover and
-        Input_Data.Language_Params.Use_Language_Runtime
-      then
-         declare
-            Pkg : constant String :=
-              (if -Input_Data.Language_Params.Language_Runtime_Name = ""
-               then Default_Language_Runtime_Package
-               else -Input_Data.Language_Params.Language_Runtime_Name);
-         begin
-            --  For language-specific names in actions, checks.
-            Put_Line ("with " & Pkg & ";");
-            Put_Line ("use " & Pkg & ";");
-         end;
-      end if;
-
-      Put_Line ("procedure " & Unit_Name & " is new " & Generic_Package_Name);
-      Put_Line ("  (" & Actions_Package_Name & ".Descriptor,");
-      if Common_Data.Text_Rep then
-         Put_Line ("   """ & Output_File_Name_Root & "_" &
-                     To_Lower (Generate_Algorithm_Image (Tuple.Gen_Alg).all) &
-                     "_parse_table.txt"",");
-      end if;
-      if Input_Data.Language_Params.Error_Recover then
-         if Input_Data.Language_Params.Use_Language_Runtime then
-            Put_Line ("Fixes'Access, Matching_Begin_Tokens'Access, 
String_ID_Set'Access,");
-         else
-            Put_Line ("null, null, null,");
-         end if;
-      end if;
-      Put_Line (Main_Package_Name & ".Create_Parser);");
-      Close (File);
-      Set_Output (Standard_Output);
-   end Create_Ada_Test_Main;
-
-begin
-   case Common_Data.Lexer is
-   when None | re2c_Lexer =>
-      null;
-
-   when Elisp_Lexer =>
-      raise User_Error with WisiToken.Generate.Error_Message
-        (Input_Data.Grammar_Lexer.File_Name, 1, "Ada output language does not 
support " & Lexer_Image
-           (Common_Data.Lexer).all & " lexer");
-   end case;
-
-   case Tuple.Interface_Kind is
-   when None  =>
-      null;
-
-   when Module | Process =>
-      raise User_Error with WisiToken.Generate.Error_Message
-        (Input_Data.Grammar_Lexer.File_Name, 1, "Ada output language does not 
support setting Interface");
-   end case;
-
-   declare
-      Main_Package_Name    : constant String := File_Name_To_Ada 
(Output_File_Name_Root & Gen_Alg_Name) & "_Main";
-      Actions_Package_Name : constant String := File_Name_To_Ada 
(Output_File_Name_Root) & "_Actions";
-   begin
-      if Input_Data.Action_Count > 0 or Input_Data.Check_Count > 0 then
-         --  Some WisiToken tests have no actions or checks.
-         Create_Ada_Actions_Body
-           (Generate_Data.Action_Names, Generate_Data.Check_Names, 
Input_Data.Label_Count, Actions_Package_Name);
-      end if;
-
-      Create_Ada_Actions_Spec
-        (Output_File_Name_Root & "_actions.ads", Actions_Package_Name, 
Input_Data, Common_Data, Generate_Data);
-
-      if Tuple.Gen_Alg = External then
-         Create_External_Main_Spec (Main_Package_Name, Tuple, Input_Data);
-         Create_Ada_Main_Body (Actions_Package_Name, Main_Package_Name);
-      else
-         Create_Ada_Main_Body (Actions_Package_Name, Main_Package_Name);
-
-         Create_Ada_Main_Spec (To_Lower (Main_Package_Name) & ".ads", 
Main_Package_Name, Input_Data, Common_Data);
-
-         if Test_Main then
-            Create_Ada_Test_Main (Actions_Package_Name, Main_Package_Name);
-         end if;
-      end if;
-   end;
-
-exception
-when others =>
-   Set_Output (Standard_Output);
-   raise;
-end WisiToken.BNF.Output_Ada;
diff --git a/packages/wisi/wisitoken-bnf-output_ada_common.adb 
b/packages/wisi/wisitoken-bnf-output_ada_common.adb
deleted file mode 100644
index 3a594bb..0000000
--- a/packages/wisi/wisitoken-bnf-output_ada_common.adb
+++ /dev/null
@@ -1,1392 +0,0 @@
---  Abstract :
---
---  See spec.
---
---  Copyright (C) 2017 - 2020 Free Software Foundation, Inc.
---
---  This library is free software;  you can redistribute it and/or modify it
---  under terms of the  GNU General Public License  as published by the Free
---  Software  Foundation;  either version 3,  or (at your  option) any later
---  version. This library is distributed in the hope that it will be useful,
---  but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN-
---  TABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
---  As a special exception under Section 7 of GPL version 3, you are granted
---  additional permissions described in the GCC Runtime Library Exception,
---  version 3.1, as published by the Free Software Foundation.
-
-pragma License (GPL);
-
-with Ada.Strings.Fixed;
-with Ada.Text_IO; use Ada.Text_IO;
-with System.Multiprocessors;
-with WisiToken.BNF.Generate_Grammar;
-with WisiToken.BNF.Utils;
-with WisiToken.Generate; use WisiToken.Generate;
-with WisiToken.Parse.LR;
-with WisiToken.Productions;
-with WisiToken.Syntax_Trees;
-package body WisiToken.BNF.Output_Ada_Common is
-
-   --  Body subprograms, alphabetical
-
-   function Duplicate_Reduce (State : in Parse.LR.Parse_State) return Boolean
-   is
-      use Parse.LR;
-      Action_Node : Parse_Action_Node_Ptr;
-      First       : Boolean := True;
-      Action      : Reduce_Action_Rec;
-   begin
-      for Node of State.Action_List loop
-         Action_Node := Node.Actions;
-         if Action_Node.Next /= null then
-            --  conflict
-            return False;
-         elsif Action_Node.Item.Verb /= Reduce then
-            return False;
-         end if;
-
-         if First then
-            Action    := Action_Node.Item;
-            First     := False;
-         else
-            if not Equal (Action, Action_Node.Item) then
-               return False;
-            end if;
-         end if;
-      end loop;
-      return True;
-   end Duplicate_Reduce;
-
-   function Image (Item : in Boolean) return String
-     is (if Item then "True" else "False");
-
-   function Symbols_Image (State : in Parse.LR.Parse_State) return String
-   is
-      use all type Ada.Containers.Count_Type;
-      use Ada.Strings.Unbounded;
-
-      Result     : Unbounded_String;
-      Need_Comma : Boolean := False;
-   begin
-      if State.Action_List.Length = 1 then
-         return "(1 => " & Token_ID'Image (State.Action_List (1).Symbol) & ")";
-      else
-         Result := +"(";
-         for Node of State.Action_List loop
-            Result := Result &
-              (if Need_Comma then ", " else "") &
-              Trimmed_Image (Node.Symbol);
-            Need_Comma := True;
-         end loop;
-         Result := Result & ")";
-         return -Result;
-      end if;
-   end Symbols_Image;
-
-   ----------
-   --  Public subprograms in alphabetical order
-
-   procedure Create_Ada_Actions_Spec
-     (Output_File_Name :         in String;
-      Package_Name     :         in String;
-      Input_Data       :         in WisiToken_Grammar_Runtime.User_Data_Type;
-      Common_Data      :         in Output_Ada_Common.Common_Data;
-      Generate_Data    : aliased in WisiToken.BNF.Generate_Utils.Generate_Data)
-   is
-      use Generate_Utils;
-
-      Descriptor  : WisiToken.Descriptor renames Generate_Data.Descriptor.all;
-      Spec_File : File_Type;
-      Paren_Done  : Boolean      := False;
-      Cursor      : Token_Cursor := First (Generate_Data, Non_Grammar => True, 
Nonterminals => True);
-   begin
-      Create (Spec_File, Out_File, Output_File_Name);
-      Set_Output (Spec_File);
-      Indent := 1;
-
-      Put_File_Header
-        (Ada_Comment, Use_Tuple => True, Tuple =>
-           (Common_Data.Generate_Algorithm, Common_Data.Output_Language, 
Common_Data.Lexer, Common_Data.Interface_Kind,
-            Common_Data.Text_Rep));
-      Put_Raw_Code (Ada_Comment, Input_Data.Raw_Code (Copyright_License));
-      New_Line;
-
-      if not (Input_Data.Action_Count > 0 or Input_Data.Check_Count > 0) then
-         Put_Line ("with WisiToken;");
-      end if;
-      if Input_Data.Action_Count > 0 then
-         Put_Line ("with WisiToken.Syntax_Trees;");
-      end if;
-      if Input_Data.Check_Count > 0 then
-         Put_Line ("with WisiToken.Lexer;");
-         Put_Line ("with WisiToken.Semantic_Checks;");
-      end if;
-      Put_Raw_Code (Ada_Comment, Input_Data.Raw_Code (Actions_Spec_Context));
-      Put_Line ("package " & Package_Name & " is");
-      Indent := Indent + 3;
-      New_Line;
-
-      Put_Raw_Code (Ada_Comment, Input_Data.Raw_Code (Actions_Spec_Pre));
-
-      Indent_Line ("Descriptor : aliased WisiToken.Descriptor :=");
-      Indent_Line ("  (First_Terminal    =>" & WisiToken.Token_ID'Image 
(Descriptor.First_Terminal) & ",");
-      Indent := Indent + 3;
-      Indent_Line ("Last_Terminal     =>" & WisiToken.Token_ID'Image 
(Descriptor.Last_Terminal) & ",");
-      Indent_Line ("First_Nonterminal =>" & WisiToken.Token_ID'Image 
(Descriptor.First_Nonterminal) & ",");
-      Indent_Line ("Last_Nonterminal  =>" & WisiToken.Token_ID'Image 
(Descriptor.Last_Nonterminal) & ",");
-      Indent_Line ("EOI_ID            =>" & WisiToken.Token_ID'Image 
(Descriptor.EOI_ID) & ",");
-      Indent_Line ("Accept_ID         =>" & WisiToken.Token_ID'Image 
(Descriptor.Accept_ID) & ",");
-      Indent_Line ("Case_Insensitive  => " & Image 
(Input_Data.Language_Params.Case_Insensitive) & ",");
-      Indent_Line ("New_Line_ID       =>" & WisiToken.Token_ID'Image 
(Descriptor.New_Line_ID) & ",");
-      Indent_Line ("String_1_ID       =>" & WisiToken.Token_ID'Image 
(Descriptor.String_1_ID) & ",");
-      Indent_Line ("String_2_ID       =>" & WisiToken.Token_ID'Image 
(Descriptor.String_2_ID) & ",");
-      Indent_Line ("Image             =>");
-      Indent_Start ("  (");
-      Indent := Indent + 3;
-      loop
-         exit when Is_Done (Cursor);
-         if Paren_Done then
-            Indent_Start ("new String'(""" & (Name (Cursor)));
-         else
-            Put ("new String'(""" & (Name (Cursor)));
-            Paren_Done := True;
-         end if;
-         Next (Cursor, Nonterminals => True);
-         if Is_Done (Cursor) then
-            Put_Line (""")),");
-         else
-            Put_Line ("""),");
-         end if;
-      end loop;
-
-      Indent := Indent - 3;
-      Indent_Line ("Terminal_Image_Width =>" & Integer'Image 
(Descriptor.Terminal_Image_Width) & ",");
-      Indent_Line ("Image_Width          =>" & Integer'Image 
(Descriptor.Image_Width) & ",");
-      Indent_Line ("Last_Lookahead       =>" & WisiToken.Token_ID'Image 
(Descriptor.Last_Lookahead) & ");");
-      Indent := Indent - 3;
-      New_Line;
-
-      if Input_Data.Language_Params.Declare_Enums then
-         Paren_Done := False;
-
-         Cursor := First (Generate_Data, Non_Grammar => True, Nonterminals => 
True);
-         Indent_Line ("type Token_Enum_ID is");
-         Indent_Start ("  (");
-         Indent := Indent + 3;
-         loop
-            exit when Is_Done (Cursor);
-            if Paren_Done then
-               Indent_Start (To_Token_Ada_Name (Name (Cursor)));
-            else
-               Put (To_Token_Ada_Name (Name (Cursor)));
-               Paren_Done := True;
-            end if;
-            Next (Cursor, Nonterminals => True);
-            if Is_Done (Cursor) then
-               Put_Line (");");
-            else
-               Put_Line (",");
-            end if;
-         end loop;
-
-         Indent := Indent - 3;
-         New_Line;
-
-         Indent_Line ("type Token_Enum_ID_Array is array (Positive range <>) 
of Token_Enum_ID;");
-         Indent_Line ("use all type WisiToken.Token_ID;");
-         Indent_Line ("function ""+"" (Item : in Token_Enum_ID) return 
WisiToken.Token_ID");
-         Indent_Line ("  is (WisiToken.Token_ID'First + Token_Enum_ID'Pos 
(Item));");
-
-         Indent_Line ("function To_Token_Enum (Item : in WisiToken.Token_ID) 
return Token_Enum_ID");
-         Indent_Line ("  is (Token_Enum_ID'Val (Item - 
WisiToken.Token_ID'First));");
-         Indent_Line ("function ""-"" (Item : in WisiToken.Token_ID) return 
Token_Enum_ID renames To_Token_Enum;");
-         New_Line;
-
-      end if;
-
-      for Name_List of Generate_Data.Action_Names.all loop
-         if Name_List /= null then
-            for Name of Name_List.all loop
-               if Name /= null then
-                  Indent_Line ("procedure " & Name.all);
-                  Indent_Line (" (User_Data : in out 
WisiToken.Syntax_Trees.User_Data_Type'Class;");
-                  Indent_Line ("  Tree      : in out 
WisiToken.Syntax_Trees.Tree;");
-                  Indent_Line ("  Nonterm   : in     
WisiToken.Valid_Node_Index;");
-                  Indent_Line ("  Tokens    : in     
WisiToken.Valid_Node_Index_Array);");
-               end if;
-            end loop;
-         end if;
-      end loop;
-
-      for Name_List of Generate_Data.Check_Names.all loop
-         if Name_List /= null then
-            for Name of Name_List.all loop
-               if Name /= null then
-                  Indent_Line ("function " & Name.all);
-                  Indent_Line (" (Lexer          : access constant 
WisiToken.Lexer.Instance'Class;");
-                  Indent_Line ("  Nonterm        : in out 
WisiToken.Recover_Token;");
-                  Indent_Line ("  Tokens         : in     
WisiToken.Recover_Token_Array;");
-                  Indent_Line ("  Recover_Active : in     Boolean)");
-                  Indent_Line (" return 
WisiToken.Semantic_Checks.Check_Status;");
-               end if;
-            end loop;
-         end if;
-      end loop;
-
-      Put_Raw_Code (Ada_Comment, Input_Data.Raw_Code (Actions_Spec_Post));
-
-      Put_Line ("end " & Package_Name & ";");
-      Close (Spec_File);
-      Set_Output (Standard_Output);
-
-   end Create_Ada_Actions_Spec;
-
-   procedure Create_Ada_Main_Spec
-     (Output_File_Name  : in String;
-      Main_Package_Name : in String;
-      Input_Data        : in WisiToken_Grammar_Runtime.User_Data_Type;
-      Common_Data       : in Output_Ada_Common.Common_Data)
-   is
-      Lower_Package_Name : constant String := To_Lower (Main_Package_Name);
-
-      Spec_File : File_Type;
-
-      procedure LR_Process
-      is begin
-         Indent_Line ("procedure Create_Parser");
-         if Input_Data.Language_Params.Error_Recover then
-            Indent_Line ("  (Parser                         :    out 
WisiToken.Parse.LR.Parser.Parser;");
-            Indent_Line ("   Language_Fixes                 : in     
WisiToken.Parse.LR.Parser.Language_Fixes_Access;");
-            Indent_Line ("   Language_Matching_Begin_Tokens : in     " &
-                           
"WisiToken.Parse.LR.Parser.Language_Matching_Begin_Tokens_Access;");
-            Indent_Line ("   Language_String_ID_Set         : in     " &
-                           
"WisiToken.Parse.LR.Parser.Language_String_ID_Set_Access;");
-         else
-            Indent_Line ("  (Parser                       :    out 
WisiToken.Parse.LR.Parser_No_Recover.Parser;");
-            Indent_Line ("   --  no error recovery");
-         end if;
-         Indent_Line ("   Trace                        : not null access 
WisiToken.Trace'Class;");
-         Indent_Start ("   User_Data                    : in     
WisiToken.Syntax_Trees.User_Data_Access");
-
-         if Common_Data.Text_Rep then
-            Put_Line (";");
-            Indent_Line ("   Text_Rep_File_Name : in String);");
-         else
-            Put_Line (");");
-         end if;
-         New_Line;
-      end LR_Process;
-
-      procedure Packrat_Process
-      is begin
-         Indent_Line ("function Create_Parser");
-         Indent_Line ("  (Trace     : not null access WisiToken.Trace'Class;");
-         Indent_Line ("   User_Data : in     
WisiToken.Syntax_Trees.User_Data_Access)");
-         Indent_Line ("  return WisiToken.Parse.Base_Parser'Class;");
-         New_Line;
-      end Packrat_Process;
-
-   begin
-      if Common_Data.Generate_Algorithm = External then
-         raise SAL.Programmer_Error;
-      end if;
-
-      Create (Spec_File, Out_File, Output_File_Name);
-      Set_Output (Spec_File);
-      Indent := 1;
-
-      Put_File_Header
-        (Ada_Comment, Use_Tuple => True, Tuple =>
-           (Common_Data.Generate_Algorithm, Common_Data.Output_Language, 
Common_Data.Lexer, Common_Data.Interface_Kind,
-            Common_Data.Text_Rep));
-      Put_Raw_Code (Ada_Comment, Input_Data.Raw_Code (Copyright_License));
-      New_Line;
-
-      case Common_Data.Output_Language is
-      when Ada_Lang =>
-         Put_Line ("with WisiToken.Syntax_Trees;");
-
-      when Ada_Emacs_Lang =>
-         case Common_Data.Interface_Kind is
-         when Process =>
-            Put_Line ("with WisiToken.Syntax_Trees;");
-
-         when Module =>
-            Put_Line ("with Emacs_Module_Aux;");
-            Put_Line ("with emacs_module_h;");
-            Put_Line ("with Interfaces.C;");
-            Put_Line ("with WisiToken.Semantic_State;");
-         end case;
-      end case;
-
-      case Common_Data.Generate_Algorithm is
-      when LR_Generate_Algorithm =>
-         if Input_Data.Language_Params.Error_Recover then
-            Put_Line ("with WisiToken.Parse.LR.Parser;");
-         else
-            Put_Line ("with WisiToken.Parse.LR.Parser_No_Recover;");
-         end if;
-
-      when Packrat_Generate_Algorithm =>
-         Put_Line ("with WisiToken.Parse;");
-
-      when External =>
-         null;
-      end case;
-
-      Put_Line ("package " & Main_Package_Name & " is");
-      Indent := Indent + 3;
-      New_Line;
-
-      case Common_Data.Output_Language is
-      when Ada_Lang =>
-         case Common_Data.Generate_Algorithm is
-         when LR_Generate_Algorithm =>
-            LR_Process;
-         when Packrat_Generate_Algorithm =>
-            Packrat_Process;
-         when External =>
-            null;
-         end case;
-
-      when Ada_Emacs_Lang =>
-         case Common_Data.Interface_Kind is
-         when Process =>
-            case Common_Data.Generate_Algorithm is
-            when LR_Generate_Algorithm =>
-               LR_Process;
-            when Packrat_Generate_Algorithm =>
-               Packrat_Process;
-            when External =>
-               null;
-            end case;
-
-         when Module =>
-            Indent_Line ("function Parse (Env : 
Emacs_Module_Aux.Emacs_Env_Access) return emacs_module_h.emacs_value;");
-            Indent_Line ("pragma Export (C, Parse, """ & Lower_Package_Name & 
"_wisi_module_parse"");");
-            Indent_Line ("function Init (Env : 
Emacs_Module_Aux.Emacs_Env_Access) return Interfaces.C.int;");
-            Indent_Line ("pragma Export (C, Init, """ & Lower_Package_Name & 
"_wisi_module_parse_init"");");
-            New_Line;
-
-         end case;
-      end case;
-
-      Put_Line ("end " & Main_Package_Name & ";");
-      Close (Spec_File);
-      Set_Output (Standard_Output);
-   end Create_Ada_Main_Spec;
-
-   procedure Create_External_Main_Spec
-     (Main_Package_Name    : in String;
-      Tuple                : in Generate_Tuple;
-      Input_Data           : in WisiToken_Grammar_Runtime.User_Data_Type)
-   is
-      File_Name : constant String := To_Lower (Main_Package_Name) & ".ads";
-      Spec_File : File_Type;
-   begin
-      Create (Spec_File, Out_File, File_Name);
-      Set_Output (Spec_File);
-      Indent := 1;
-
-      Put_File_Header (Ada_Comment, Use_Tuple => True, Tuple => Tuple);
-      Put_Raw_Code (Ada_Comment, Input_Data.Raw_Code (Copyright_License));
-      New_Line;
-
-      Put_Line ("with WisiToken.Productions;");
-      Put_Line ("package " & Main_Package_Name & " is");
-      Indent := Indent + 3;
-      New_Line;
-
-      Indent_Line ("function Create_Grammar return 
WisiToken.Productions.Prod_Arrays.Vector;");
-
-      Indent := Indent - 3;
-      Put_Line ("end " & Main_Package_Name & ";");
-      Close (Spec_File);
-      Set_Output (Standard_Output);
-   end Create_External_Main_Spec;
-
-   procedure Create_LR_Parser_Core_1
-     (Common_Data   : in Output_Ada_Common.Common_Data;
-      Generate_Data : in WisiToken.BNF.Generate_Utils.Generate_Data)
-   is
-      use Ada.Strings.Unbounded;
-
-      subtype Nonterminal_ID is Token_ID range
-        Generate_Data.Grammar.First_Index .. Generate_Data.Grammar.Last_Index;
-
-      Table : WisiToken.Parse.LR.Parse_Table_Ptr renames 
Generate_Data.LR_Parse_Table;
-      Line  : Unbounded_String;
-
-      procedure Append (Item : in String)
-      is begin
-         Line := Line & Item;
-      end Append;
-
-      procedure Put (Label : in String; Item : in Token_ID_Array_Natural)
-      is begin
-         Indent_Line (Label & " =>");
-         Indent_Start ("  (");
-         Indent := Indent + 3;
-         Line := +"";
-         for I in Item'Range loop
-            Append (Trimmed_Image (Item (I)));
-
-            if I = Item'Last then
-               Append ("),");
-
-            else
-               Append (", ");
-            end if;
-         end loop;
-         Indent_Wrap (-Line);
-         Indent := Indent - 3;
-      end Put;
-
-   begin
-      Indent_Line ("McKenzie_Param : constant McKenzie_Param_Type :=");
-      Indent_Line ("  (First_Terminal    =>" & Token_ID'Image 
(Table.McKenzie_Param.First_Terminal) & ",");
-      Indent := Indent + 3;
-      Indent_Line ("Last_Terminal     =>" & Token_ID'Image 
(Table.McKenzie_Param.Last_Terminal) & ",");
-      Indent_Line ("First_Nonterminal =>" & Token_ID'Image 
(Table.McKenzie_Param.First_Nonterminal) & ",");
-      Indent_Line ("Last_Nonterminal  =>" & Token_ID'Image 
(Table.McKenzie_Param.Last_Nonterminal) & ",");
-      Put ("Insert", Table.McKenzie_Param.Insert);
-      Put ("Delete", Table.McKenzie_Param.Delete);
-      Put ("Push_Back", Table.McKenzie_Param.Push_Back);
-      Put ("Undo_Reduce", Table.McKenzie_Param.Undo_Reduce);
-      Indent_Line
-        ("Minimal_Complete_Cost_Delta => " & Integer'Image 
(Table.McKenzie_Param.Minimal_Complete_Cost_Delta) & ",");
-      Indent_Line ("Fast_Forward => " & Integer'Image 
(Table.McKenzie_Param.Fast_Forward) & ",");
-      Indent_Line ("Matching_Begin => " & Integer'Image 
(Table.McKenzie_Param.Matching_Begin) & ",");
-      Indent_Line ("Ignore_Check_Fail  =>" & Integer'Image 
(Table.McKenzie_Param.Ignore_Check_Fail) & ",");
-      Indent_Line ("Task_Count  =>" & System.Multiprocessors.CPU_Range'Image
-                     (Table.McKenzie_Param.Task_Count) & ",");
-      Indent_Line ("Check_Limit =>" & Token_Index'Image 
(Table.McKenzie_Param.Check_Limit) & ",");
-      Indent_Line ("Check_Delta_Limit =>" & Integer'Image 
(Table.McKenzie_Param.Check_Delta_Limit) & ",");
-      Indent_Line ("Enqueue_Limit =>" & Integer'Image 
(Table.McKenzie_Param.Enqueue_Limit) & ");");
-      Indent := Indent - 3;
-      New_Line;
-
-      if Common_Data.Text_Rep then
-         Indent_Line ("function Actions return 
WisiToken.Parse.LR.Semantic_Action_Array_Arrays.Vector");
-         Indent_Line ("is begin");
-         Indent := Indent + 3;
-         Indent_Line ("return Acts : 
WisiToken.Parse.LR.Semantic_Action_Array_Arrays.Vector do");
-         Indent := Indent + 3;
-         Indent_Line
-           ("Acts.Set_First_Last (" & Trimmed_Image 
(Generate_Data.Grammar.First_Index) & ", " &
-              Trimmed_Image (Generate_Data.Grammar.Last_Index) & ");");
-
-         for I in Nonterminal_ID loop
-            declare
-               P : Productions.Instance renames Generate_Data.Grammar (I);
-            begin
-               if Generate_Data.Action_Names (P.LHS) /= null or 
Generate_Data.Check_Names (P.LHS) /= null then
-                  Indent_Line
-                    ("Acts (" & Trimmed_Image (P.LHS) & ").Set_First_Last (0," 
&
-                       Integer'Image (P.RHSs.Last_Index) & ");");
-
-                  for J in P.RHSs.First_Index .. P.RHSs.Last_Index loop
-                     if (Generate_Data.Action_Names (P.LHS) /= null and then
-                           Generate_Data.Action_Names (P.LHS)(J) /= null)
-                       or
-                       (Generate_Data.Check_Names (P.LHS) /= null and then
-                          Generate_Data.Check_Names (P.LHS) /= null)
-                     then
-                        Indent_Wrap
-                          ("Acts (" & Trimmed_Image (P.LHS) & ")(" & 
Trimmed_Image (J) & ") := (" &
-                             (if Generate_Data.Action_Names (P.LHS) = null 
then "null"
-                              elsif Generate_Data.Action_Names (P.LHS)(J) = 
null then "null"
-                              else Generate_Data.Action_Names (P.LHS)(J).all & 
"'Access") & ", " &
-                             (if Generate_Data.Check_Names (P.LHS) = null then 
"null"
-                              elsif Generate_Data.Check_Names (P.LHS)(J) = 
null then "null"
-                              else Generate_Data.Check_Names (P.LHS)(J).all & 
"'Access") & ");");
-                     end if;
-                  end loop;
-               end if;
-            end;
-         end loop;
-         Indent := Indent - 3;
-         Indent_Line ("end return;");
-         Indent := Indent - 3;
-         Indent_Line ("end Actions;");
-         New_Line;
-      end if;
-   end Create_LR_Parser_Core_1;
-
-   procedure Create_LR_Parser_Table
-     (Input_Data    : in WisiToken_Grammar_Runtime.User_Data_Type;
-      Generate_Data : in WisiToken.BNF.Generate_Utils.Generate_Data)
-   is
-      use all type Ada.Containers.Count_Type;
-      use WisiToken.Parse.LR;
-      use Ada.Strings.Unbounded;
-
-      Table            : WisiToken.Parse.LR.Parse_Table_Ptr renames 
Generate_Data.LR_Parse_Table;
-      Lines_Per_Subr   : constant := 1000;
-      Subr_Count       : Integer  := 1;
-      Last_Subr_Closed : Boolean  := False;
-      Line             : Unbounded_String;
-
-      procedure Append (Item : in String)
-      is begin
-         Line := Line & Item;
-      end Append;
-   begin
-      --  Optimize source structure for GNAT compile time; one subroutine
-      --  with thousands of "Table.States (*) := ..." takes forever to
-      --  compile (apparently depending on available memory). But hundreds
-      --  of subroutines, containing the same lines in chunks of 1000,
-      --  compiles in acceptable time.
-
-      Indent_Line ("declare");
-      Indent := Indent + 3;
-
-      Indent_Line ("procedure Subr_" & Trimmed_Image (Subr_Count));
-      Indent_Line ("is begin");
-      Indent     := Indent + 3;
-      Line_Count := 0;
-
-      Declare_Subroutines :
-      for State_Index in Table.States'Range loop
-         Actions :
-         declare
-            use Ada.Containers;
-            Base_Indent : constant Ada.Text_IO.Count := Indent;
-         begin
-            Indent_Line
-              ("Table.States (" & Trimmed_Image (State_Index) & 
").Action_List.Set_Capacity (" &
-                 Trimmed_Image (Table.States (State_Index).Action_List.Length) 
& ");");
-
-            if Duplicate_Reduce (Table.States (State_Index)) then
-               if Table.States (State_Index).Action_List.Length > 0 then
-                  --  We only get here with Length = 0 when there's a bug in 
LALR_Generate.
-                  declare
-                     Node   : Action_Node renames Table.States 
(State_Index).Action_List (1);
-                     Action : constant Reduce_Action_Rec := Node.Actions.Item;
-                  begin
-                     Set_Col (Indent);
-                     Line := +"Add_Action (Table.States (" & Trimmed_Image 
(State_Index) & "), " &
-                       Symbols_Image (Table.States (State_Index)) & ", " &
-                       Image (Action.Production) & ", " &
-                       Count_Type'Image (Action.Token_Count) & ", ";
-
-                     Append
-                       ((if Generate_Data.Action_Names (Action.Production.LHS) 
= null then "null"
-                         elsif Generate_Data.Action_Names
-                           (Action.Production.LHS)(Action.Production.RHS) = 
null then "null"
-                         else Generate_Data.Action_Names
-                           (Action.Production.LHS)(Action.Production.RHS).all 
& "'Access"));
-                     Append (", ");
-                     Append
-                       ((if Generate_Data.Check_Names (Action.Production.LHS) 
= null then "null"
-                         elsif Generate_Data.Check_Names
-                           (Action.Production.LHS)(Action.Production.RHS) = 
null then "null"
-                         else Generate_Data.Check_Names
-                           (Action.Production.LHS)(Action.Production.RHS).all 
& "'Access"));
-
-                     Indent_Wrap (-Line & ");");
-                     Line_Count := Line_Count + 1;
-                     Indent     := Base_Indent;
-                  end;
-               end if;
-
-            else
-               for Node of Table.States (State_Index).Action_List loop
-                  Set_Col (Indent);
-                  declare
-                     Action_Node : Parse_Action_Node_Ptr := Node.Actions;
-                  begin
-                     case Action_Node.Item.Verb is
-                     when Shift =>
-                        Line := +"Add_Action (Table.States (" & Trimmed_Image 
(State_Index) & "), " &
-                          Trimmed_Image (Node.Symbol) & ", ";
-                        Append (Image (Action_Node.Item.Production) & ", ");
-                        Append (Trimmed_Image (Action_Node.Item.State));
-                        Append (");");
-
-                     when Reduce | Accept_It =>
-                        Line := +"Add_Action (Table.States (" & Trimmed_Image 
(State_Index) & "), " &
-                          Trimmed_Image (Node.Symbol);
-                        if Action_Node.Item.Verb = Reduce then
-                           Append (", Reduce");
-                        else
-                           Append (", Accept_It");
-                        end if;
-                        Append (", ");
-                        Append (Image (Action_Node.Item.Production) & ", ");
-                        Append (Count_Type'Image 
(Action_Node.Item.Token_Count) & ", ");
-                        Append
-                          ((if Generate_Data.Action_Names 
(Action_Node.Item.Production.LHS) = null then "null"
-                            elsif Generate_Data.Action_Names
-                              
(Action_Node.Item.Production.LHS)(Action_Node.Item.Production.RHS) = null
-                            then "null"
-                            else Generate_Data.Action_Names
-                              
(Action_Node.Item.Production.LHS)(Action_Node.Item.Production.RHS).all &
-                               "'Access"));
-                        Append (", ");
-                        Append
-                          ((if Generate_Data.Check_Names 
(Action_Node.Item.Production.LHS) = null then "null"
-                            elsif Generate_Data.Check_Names
-                              
(Action_Node.Item.Production.LHS)(Action_Node.Item.Production.RHS) = null
-                            then "null"
-                            else Generate_Data.Check_Names
-                              
(Action_Node.Item.Production.LHS)(Action_Node.Item.Production.RHS).all &
-                               "'Access"));
-                        Append (");");
-
-                     when Parse.LR.Error =>
-                        raise SAL.Programmer_Error;
-                     end case;
-                     Indent_Wrap (-Line);
-                     Line_Count := Line_Count + 1;
-
-                     loop
-                        Action_Node := Action_Node.Next;
-                        exit when Action_Node = null;
-                        --  There is a conflict; must be Shift/{Reduce|Accept} 
or Reduce/{Reduce|Accept}.
-                        --  The added parameters are the same in either case.
-                        case Action_Node.Item.Verb is
-                        when Reduce | Accept_It =>
-                           Line := +"Add_Conflict (Table.States (" & 
Trimmed_Image (State_Index) & "), " &
-                             Trimmed_Image (Node.Symbol) & ", ";
-                           Append (Image (Action_Node.Item.Production) & ", ");
-                           Append (Count_Type'Image 
(Action_Node.Item.Token_Count) & ", ");
-                           Append
-                             ((if Generate_Data.Action_Names 
(Action_Node.Item.Production.LHS) = null then "null"
-                               elsif Generate_Data.Action_Names
-                                 
(Action_Node.Item.Production.LHS)(Action_Node.Item.Production.RHS) = null
-                               then "null"
-                               else Generate_Data.Action_Names
-                                 
(Action_Node.Item.Production.LHS)(Action_Node.Item.Production.RHS).all &
-                                  "'Access"));
-                           Append (", ");
-                           Append
-                             ((if Generate_Data.Check_Names 
(Action_Node.Item.Production.LHS) = null then "null"
-                               elsif Generate_Data.Check_Names
-                                 
(Action_Node.Item.Production.LHS)(Action_Node.Item.Production.RHS) = null
-                               then "null"
-                               else Generate_Data.Check_Names
-                                 
(Action_Node.Item.Production.LHS)(Action_Node.Item.Production.RHS).all &
-                                  "'Access"));
-                           Indent_Wrap (-Line & ");");
-                           Line_Count := Line_Count + 1;
-
-                        when others =>
-                           raise SAL.Programmer_Error with "invalid conflict 
action verb: " &
-                             Parse.LR.Parse_Action_Verbs'Image 
(Action_Node.Item.Verb);
-                        end case;
-                     end loop;
-                  end;
-                  Indent := Base_Indent;
-               end loop;
-            end if;
-         end Actions;
-
-         if Table.States (State_Index).Goto_List.Length > 0 then
-            Indent_Line
-              ("Table.States (" & Trimmed_Image (State_Index) & 
").Goto_List.Set_Capacity (" &
-                 Trimmed_Image (Table.States (State_Index).Goto_List.Length) & 
");");
-         end if;
-         Gotos :
-         for Node of Table.States (State_Index).Goto_List loop
-            Set_Col (Indent);
-            Put ("Add_Goto (Table.States (" & Trimmed_Image (State_Index) & 
"), ");
-            Put_Line (Trimmed_Image (Node.Symbol) & ", " & Trimmed_Image 
(Node.State) & ");");
-            Line_Count := Line_Count + 1;
-         end loop Gotos;
-
-         if Input_Data.Language_Params.Error_Recover then
-            if Table.States (State_Index).Kernel.Length > 0 then
-               Indent_Wrap
-                 ("Table.States (" & Trimmed_Image (State_Index) & ").Kernel 
:= To_Vector (" &
-                    Image (Table.States (State_Index).Kernel, Strict => True) 
& ");");
-            end if;
-            if Table.States (State_Index).Minimal_Complete_Actions.Length > 0 
then
-               Indent_Wrap
-                 ("Table.States (" & Trimmed_Image (State_Index) & 
").Minimal_Complete_Actions := To_Vector (" &
-                    Strict_Image (Table.States 
(State_Index).Minimal_Complete_Actions, Strict => True) & ");");
-            end if;
-         end if;
-
-         if Line_Count > Lines_Per_Subr then
-            Line_Count := 0;
-            Indent := Indent - 3;
-            Indent_Line ("end Subr_" & Trimmed_Image (Subr_Count) & ";");
-
-            if State_Index < Table.States'Last then
-               Subr_Count := Subr_Count + 1;
-               Last_Subr_Closed := False;
-               Indent_Line ("procedure Subr_" & Trimmed_Image (Subr_Count));
-               Indent_Line ("is begin");
-               Indent := Indent + 3;
-            else
-               Last_Subr_Closed := True;
-            end if;
-         end if;
-
-      end loop Declare_Subroutines;
-
-      if not Last_Subr_Closed then
-         Indent := Indent - 3;
-         Indent_Line ("end Subr_" & Trimmed_Image (Subr_Count) & ";");
-      end if;
-
-      Indent := Indent - 3;
-      Indent_Line ("begin");
-      Indent := Indent + 3;
-
-      for Subr in 1 .. Subr_Count loop
-         Indent_Line ("Subr_" & Trimmed_Image (Subr) & ";");
-      end loop;
-      Indent_Line ("Table.Error_Action := new Parse_Action_Node'((Verb => 
Error, others => <>), null);");
-      Indent := Indent - 3;
-      Indent_Line ("end;");
-   end Create_LR_Parser_Table;
-
-   procedure LR_Create_Create_Parser
-     (Input_Data    :         in     WisiToken_Grammar_Runtime.User_Data_Type;
-      Common_Data   :         in out Output_Ada_Common.Common_Data;
-      Generate_Data : aliased in     
WisiToken.BNF.Generate_Utils.Generate_Data)
-   is
-      Table : WisiToken.Parse.LR.Parse_Table_Ptr renames 
Generate_Data.LR_Parse_Table;
-   begin
-      Indent_Line ("procedure Create_Parser");
-      case Common_Data.Interface_Kind is
-      when Process =>
-         if Input_Data.Language_Params.Error_Recover then
-            Indent_Line ("  (Parser                         :    out 
WisiToken.Parse.LR.Parser.Parser;");
-            Indent_Line ("   Language_Fixes                 : in     
WisiToken.Parse.LR.Parser.Language_Fixes_Access;");
-            Indent_Line ("   Language_Matching_Begin_Tokens : in     " &
-                           
"WisiToken.Parse.LR.Parser.Language_Matching_Begin_Tokens_Access;");
-            Indent_Line
-              ("   Language_String_ID_Set       : in     
WisiToken.Parse.LR.Parser.Language_String_ID_Set_Access;");
-         else
-            Indent_Line ("  (Parser                         :    out 
WisiToken.Parse.LR.Parser_No_Recover.Parser;");
-         end if;
-         Indent_Line ("   Trace                        : not null access 
WisiToken.Trace'Class;");
-         Indent_Start ("   User_Data                    : in     
WisiToken.Syntax_Trees.User_Data_Access");
-
-      when Module =>
-         Indent_Line ("  (Parser              :    out 
WisiToken.Parse.LR.Parser.Parser;");
-         Indent_Line ("   Env                 : in     Emacs_Env_Access;");
-         Indent_Start ("   Lexer_Elisp_Symbols : in     
Lexers.Elisp_Array_Emacs_Value");
-      end case;
-
-      if Common_Data.Text_Rep then
-         Put_Line (";");
-         Indent_Line ("   Text_Rep_File_Name : in String)");
-      else
-         Put_Line (")");
-      end if;
-
-      Indent_Line ("is");
-      Indent := Indent + 3;
-
-      Indent_Line ("use WisiToken.Parse.LR;");
-
-      if Common_Data.Text_Rep then
-         Create_LR_Parser_Core_1 (Common_Data, Generate_Data);
-         Indent_Line ("Table : constant Parse_Table_Ptr := Get_Text_Rep");
-         Indent_Line ("  (Text_Rep_File_Name, McKenzie_Param, Actions);");
-         Indent := Indent - 3;
-         Indent_Line ("begin");
-         Indent := Indent + 3;
-
-      else
-         if Input_Data.Language_Params.Error_Recover then
-            Create_LR_Parser_Core_1 (Common_Data, Generate_Data);
-         end if;
-
-         Indent_Line ("Table : constant Parse_Table_Ptr := new Parse_Table");
-         Indent_Line ("  (State_First       => 0,");
-         Indent := Indent + 3;
-         Indent_Line ("State_Last        =>" & State_Index'Image 
(Table.State_Last) & ",");
-         Indent_Line ("First_Terminal    =>" & Token_ID'Image 
(Table.First_Terminal) & ",");
-         Indent_Line ("Last_Terminal     =>" & Token_ID'Image 
(Table.Last_Terminal) & ",");
-         Indent_Line ("First_Nonterminal =>" & Token_ID'Image 
(Table.First_Nonterminal) & ",");
-         Indent_Line ("Last_Nonterminal  =>" & Token_ID'Image 
(Table.Last_Nonterminal) & ");");
-         Indent := Indent - 3;
-
-         Indent := Indent - 3;
-         Indent_Line ("begin");
-         Indent := Indent + 3;
-         if Input_Data.Language_Params.Error_Recover then
-            Indent_Line ("Table.McKenzie_Param := McKenzie_Param;");
-         end if;
-         Create_LR_Parser_Table (Input_Data, Generate_Data);
-         New_Line;
-      end if;
-
-      if Input_Data.Language_Params.Error_Recover then
-         Indent_Line ("WisiToken.Parse.LR.Parser.New_Parser");
-      else
-         Indent_Line ("WisiToken.Parse.LR.Parser_No_Recover.New_Parser");
-      end if;
-      Indent_Line ("  (Parser,");
-      case Common_Data.Interface_Kind is
-      when Process =>
-         Indent_Line ("   Trace,");
-         Indent_Line ("   Lexer.New_Lexer (Trace.Descriptor),");
-         Indent_Line ("   Table,");
-         if Input_Data.Language_Params.Error_Recover then
-            Indent_Line ("   Language_Fixes,");
-            Indent_Line ("   Language_Matching_Begin_Tokens,");
-            Indent_Line ("   Language_String_ID_Set,");
-         end if;
-         Indent_Line ("   User_Data,");
-         Indent_Line ("   Max_Parallel         => 15,");
-         Indent_Line ("   Terminate_Same_State => True);");
-
-      when Module =>
-         Indent_Line ("   Lexer.New_Lexer (Env, Lexer_Elisp_Symbols),");
-         Indent_Line ("   Table, Max_Parallel => 15, Terminate_Same_State => 
True);");
-
-      end case;
-      Indent := Indent - 3;
-      Indent_Line ("end Create_Parser;");
-   end LR_Create_Create_Parser;
-
-   procedure Packrat_Create_Create_Parser
-     (Common_Data   :         in out Output_Ada_Common.Common_Data;
-      Generate_Data : aliased in     
WisiToken.BNF.Generate_Utils.Generate_Data;
-      Packrat_Data  :         in     WisiToken.Generate.Packrat.Data)
-   is
-      use Ada.Strings.Unbounded;
-
-      Text     : Unbounded_String;
-      Need_Bar : Boolean := True;
-   begin
-      Indent_Line ("function Create_Parser");
-      Indent_Line ("  (Trace     : not null acc