]> code.delx.au - gnu-emacs/blobdiff - lisp/progmodes/ada-mode.el
Merge from emacs--devo--0
[gnu-emacs] / lisp / progmodes / ada-mode.el
index 68afd8ee649565e73c7c93e5dbb660b4e1f95022..aa3aea0d71bb87d0048a5dcfc2f981d8570c651e 100644 (file)
@@ -1,20 +1,19 @@
 ;;; ada-mode.el --- major-mode for editing Ada sources
 
-;; Copyright (C) 1994, 95, 97, 98, 99, 2000, 2001, 2002, 03, 2004
-;;  Free Software Foundation, Inc.
+;; Copyright (C) 1994, 1995, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
+;;               2005, 2006, 2007  Free Software Foundation, Inc.
 
 ;; Author: Rolf Ebert      <ebert@inf.enst.fr>
 ;;      Markus Heritsch <Markus.Heritsch@studbox.uni-stuttgart.de>
 ;;      Emmanuel Briot  <briot@gnat.com>
-;; Maintainer: Emmanuel Briot <briot@gnat.com>
-;; Ada Core Technologies's version:   Revision: 1.188
+;; Maintainer: Stephen Leake <stephen_leake@member.fsf.org>
 ;; Keywords: languages ada
 
 ;; 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 2, or (at your option)
+;; the Free Software Foundation; either version 3, or (at your option)
 ;; any later version.
 
 ;; GNU Emacs is distributed in the hope that it will be useful,
 
 ;; You should have received a copy of the GNU General Public License
 ;; along with GNU Emacs; see the file COPYING.  If not, write to the
-;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-;; Boston, MA 02111-1307, USA.
+;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
 
 ;;; Commentary:
-;;; This mode is a major mode for editing Ada83 and Ada95 source code.
-;;; This is a major rewrite of the file packaged with Emacs-20.  The
-;;; ada-mode is composed of four lisp files, ada-mode.el, ada-xref.el,
-;;; ada-prj.el and ada-stmt.el.  Only this file (ada-mode.el) is
-;;; completely independent from the GNU Ada compiler Gnat, distributed
-;;; by Ada Core Technologies.  All the other files rely heavily on
-;;; features provided only by Gnat.
+;;; This mode is a major mode for editing Ada code.  This is a major
+;;; rewrite of the file packaged with Emacs-20.  The Ada mode is
+;;; composed of four Lisp files: ada-mode.el, ada-xref.el, ada-prj.el
+;;; and ada-stmt.el.  Only this file (ada-mode.el) is completely
+;;; independent from the GNU Ada compiler GNAT, distributed by Ada
+;;; Core Technologies.  All the other files rely heavily on features
+;;; provided only by GNAT.
 ;;;
 ;;; Note: this mode will not work with Emacs 19. If you are on a VMS
 ;;; system, where the latest version of Emacs is 19.28, you will need
 ;;; (yet) been recoded in this new mode.  Perhaps you prefer sticking
 ;;; to his version.
 ;;;
-;;; A complete rewrite for Emacs-20 / Gnat-3.11 has been done by Ada Core
-;;; Technologies. Please send bugs to  briot@gnat.com
+;;; A complete rewrite for Emacs-20 / GNAT-3.11 has been done by Ada Core
+;;; Technologies.
 
 ;;; Credits:
 ;;;   Many thanks to John McCabe <john@assen.demon.co.uk> for sending so
 ;;;     many patches included in this package.
 ;;;   Christian Egli <Christian.Egli@hcsd.hac.com>:
 ;;;     ada-imenu-generic-expression
-;;;   Many thanks also to the following persons that have contributed one day
+;;;   Many thanks also to the following persons that have contributed
 ;;;   to the ada-mode
 ;;;     Philippe Waroquiers (PW) <philippe@cfmu.eurocontrol.be> in particular,
 ;;;     woodruff@stc.llnl.gov (John Woodruff)
 ;;;   `abbrev-mode': Provides the capability to define abbreviations, which
 ;;;      are automatically expanded when you type them. See the Emacs manual.
 
-(eval-when-compile
-  (require 'ispell nil t)
-  (require 'find-file nil t)
-  (require 'align nil t)
-  (require 'which-func nil t)
-  (require 'compile nil t))
+(require 'find-file nil t)
+(require 'align nil t)
+(require 'which-func nil t)
+(require 'compile nil t)
+
+(defvar compile-auto-highlight)
+(defvar ispell-check-comments)
+(defvar skeleton-further-elements)
 
-;; this function is needed at compile time
 (eval-and-compile
   (defun ada-check-emacs-version (major minor &optional is-xemacs)
     "Return t if Emacs's version is greater or equal to MAJOR.MINOR.
 If IS-XEMACS is non-nil, check for XEmacs instead of Emacs."
     (let ((xemacs-running (or (string-match "Lucid"  emacs-version)
-                              (string-match "XEmacs" emacs-version))))
+                             (string-match "XEmacs" emacs-version))))
       (and (or (and is-xemacs xemacs-running)
-               (not (or is-xemacs xemacs-running)))
-           (or (> emacs-major-version major)
-               (and (= emacs-major-version major)
-                    (>= emacs-minor-version minor)))))))
+              (not (or is-xemacs xemacs-running)))
+          (or (> emacs-major-version major)
+              (and (= emacs-major-version major)
+                   (>= emacs-minor-version minor)))))))
 
-
-;;  This call should not be made in the release that is done for the
-;;  official Emacs, since it does nothing useful for the latest version
-;;(if (not (ada-check-emacs-version 21 1))
-;;    (require 'ada-support))
+(defun ada-mode-version ()
+  "Return Ada mode version."
+  (interactive)
+  (let ((version-string "3.7"))
+    (if (interactive-p)
+       (message version-string)
+      version-string)))
 
 (defvar ada-mode-hook nil
   "*List of functions to call when Ada mode is invoked.
@@ -159,7 +161,8 @@ fully loaded.
 This is a good place to add Ada environment specific bindings.")
 
 (defgroup ada nil
-  "Major mode for editing Ada source in Emacs."
+  "Major mode for editing and compiling Ada source in Emacs."
+  :link '(custom-group-link :tag "Font Lock Faces group" font-lock-faces)
   :group 'languages)
 
 (defcustom ada-auto-case t
@@ -174,7 +177,7 @@ and `ada-case-attribute'."
 An example is :
   declare
      A,
-     >>>>>B : Integer;  --  from ada-broken-decl-indent"
+     >>>>>B : Integer;"
   :type 'integer :group 'ada)
 
 (defcustom ada-broken-indent 2
@@ -182,7 +185,7 @@ An example is :
 
 An example is :
    My_Var : My_Type := (Field1 =>
-                        >>>>>>>>>Value);  -- from ada-broken-indent"
+                       >>>>>>>>>Value);"
   :type 'integer :group 'ada)
 
 (defcustom ada-continuation-indent ada-broken-indent
@@ -190,7 +193,7 @@ An example is :
 
 An example is :
    Func (Param1,
-         >>>>>Param2);"
+        >>>>>Param2);"
   :type 'integer :group 'ada)
 
 (defcustom ada-case-attribute 'ada-capitalize-word
@@ -198,10 +201,10 @@ An example is :
 It may be `downcase-word', `upcase-word', `ada-loose-case-word',
 `ada-capitalize-word' or `ada-no-auto-case'."
   :type '(choice (const downcase-word)
-                 (const upcase-word)
-                 (const ada-capitalize-word)
-                 (const ada-loose-case-word)
-                 (const ada-no-auto-case))
+                (const upcase-word)
+                (const ada-capitalize-word)
+                (const ada-loose-case-word)
+                (const ada-no-auto-case))
   :group 'ada)
 
 (defcustom ada-case-exception-file
@@ -214,8 +217,8 @@ These files should contain one word per line, that gives the casing
 to be used for that word in Ada files.  If the line starts with the
 character *, then the exception will be used for substrings 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.  Each line can be terminated by
-a comment."
+at the end of the word or at a _ character.  Each line can be terminated
+by a comment."
   :type '(repeat (file))
   :group 'ada)
 
@@ -224,10 +227,10 @@ a comment."
 It may be `downcase-word', `upcase-word', `ada-loose-case-word' or
 `ada-capitalize-word'."
   :type '(choice (const downcase-word)
-                 (const upcase-word)
-                 (const ada-capitalize-word)
-                 (const ada-loose-case-word)
-                 (const ada-no-auto-case))
+                (const upcase-word)
+                (const ada-capitalize-word)
+                (const ada-loose-case-word)
+                (const ada-no-auto-case))
   :group 'ada)
 
 (defcustom ada-case-identifier 'ada-loose-case-word
@@ -235,10 +238,10 @@ It may be `downcase-word', `upcase-word', `ada-loose-case-word' or
 It may be `downcase-word', `upcase-word', `ada-loose-case-word' or
 `ada-capitalize-word'."
   :type '(choice (const downcase-word)
-                 (const upcase-word)
-                 (const ada-capitalize-word)
-                 (const ada-loose-case-word)
-                 (const ada-no-auto-case))
+                (const upcase-word)
+                (const ada-capitalize-word)
+                (const ada-loose-case-word)
+                (const ada-no-auto-case))
   :group 'ada)
 
 (defcustom ada-clean-buffer-before-saving t
@@ -251,7 +254,7 @@ It may be `downcase-word', `upcase-word', `ada-loose-case-word' or
 An example is :
 procedure Foo is
 begin
->>>>>>>>>>null;  --  from ada-indent"
+>>>>>>>>>>null;"
   :type 'integer  :group 'ada)
 
 (defcustom ada-indent-after-return t
@@ -265,7 +268,7 @@ Note that indentation is calculated only if `ada-indent-comment-as-code' is t.
 
 For instance:
     A := 1;   --  A multi-line comment
-              --  aligned if ada-indent-align-comments is t"
+             --  aligned if ada-indent-align-comments is t"
   :type 'boolean :group 'ada)
 
 (defcustom ada-indent-comment-as-code t
@@ -304,7 +307,7 @@ type A is
 
 An example is:
    type A is
-   >>>>>>>>>>>record    --  from ada-indent-record-rel-type"
+   >>>>>>>>>>>record"
   :type 'integer :group 'ada)
 
 (defcustom ada-indent-renames ada-broken-indent
@@ -314,8 +317,8 @@ the open parenthesis (if there is no parenthesis, `ada-broken-indent' is used).
 
 An example is:
    function A (B : Integer)
-       return C;      --  from ada-indent-return
-   >>>renames Foo;    --  from ada-indent-renames"
+       return C;
+   >>>renames Foo;"
   :type 'integer :group 'ada)
 
 (defcustom ada-indent-return 0
@@ -325,7 +328,7 @@ the open parenthesis (if there is no parenthesis, `ada-broken-indent' is used).
 
 An example is:
    function A (B : Integer)
-   >>>>>return C;       --  from ada-indent-return"
+   >>>>>return C;"
   :type 'integer :group 'ada)
 
 (defcustom ada-indent-to-open-paren t
@@ -349,18 +352,17 @@ Used by `ada-fill-comment-paragraph-postfix'."
 An example is:
 procedure Foo is
 begin
->>>>>>>>>>>>Label:  --  from ada-label-indent
+>>>>Label:
 
 This is also used for <<..>> labels"
   :type 'integer :group 'ada)
 
 (defcustom ada-language-version 'ada95
-  "*Do we program in `ada83' or `ada95'?"
-  :type '(choice (const ada83) (const ada95)) :group 'ada)
+  "*Ada language version; one of `ada83', `ada95', `ada2005'."
+  :type '(choice (const ada83) (const ada95) (const ada2005)) :group 'ada)
 
 (defcustom ada-move-to-declaration nil
-  "*Non-nil means `ada-move-to-start' moves point to the subprogram declaration,
-not to 'begin'."
+  "*Non-nil means `ada-move-to-start' moves to the subprogram declaration, not to 'begin'."
   :type 'boolean :group 'ada)
 
 (defcustom ada-popup-key '[down-mouse-3]
@@ -374,13 +376,12 @@ If nil, no contextual menu is available."
          (split-string (or (getenv "ADA_INCLUDE_PATH") "") ":")
          '("/usr/adainclude" "/usr/local/adainclude"
            "/opt/gnu/adainclude"))
-  "*List of directories to search for Ada files.
+  "*Default list of directories to search for Ada files.
 See the description for the `ff-search-directories' variable.  This variable
-is the initial value of this variable, and is copied and modified in
-`ada-search-directories-internal'."
+is the initial value of `ada-search-directories-internal'."
   :type '(repeat (choice :tag "Directory"
-                         (const :tag "default" nil)
-                         (directory :format "%v")))
+                        (const :tag "default" nil)
+                        (directory :format "%v")))
   :group 'ada)
 
 (defvar ada-search-directories-internal ada-search-directories
@@ -394,7 +395,7 @@ and the standard runtime location, and the value of the user-defined
 
 An example is:
    if A = B
-   >>>>>>>>>>>then   --  from ada-stmt-end-indent"
+   >>>>then"
   :type 'integer :group 'ada)
 
 (defcustom ada-tab-policy 'indent-auto
@@ -402,10 +403,10 @@ An example is:
 Must be one of :
 `indent-rigidly' : always adds `ada-indent' blanks at the beginning of the line.
 `indent-auto'    : use indentation functions in this file.
-`always-tab'     : do indent-relative."
+`always-tab'     : do `indent-relative'."
   :type '(choice (const indent-auto)
-                 (const indent-rigidly)
-                 (const always-tab))
+                (const indent-rigidly)
+                (const always-tab))
   :group 'ada)
 
 (defcustom ada-use-indent ada-broken-indent
@@ -413,7 +414,7 @@ Must be one of :
 
 An example is:
    use Ada.Text_IO,
-   >>>>>Ada.Numerics;    --  from ada-use-indent"
+   >>>>Ada.Numerics;"
   :type 'integer :group 'ada)
 
 (defcustom ada-when-indent 3
@@ -421,7 +422,7 @@ An example is:
 
 An example is:
    case A is
-   >>>>>>>>when B =>     --  from ada-when-indent"
+   >>>>when B =>"
   :type 'integer :group 'ada)
 
 (defcustom ada-with-indent ada-broken-indent
@@ -429,18 +430,18 @@ An example is:
 
 An example is:
    with Ada.Text_IO,
-   >>>>>Ada.Numerics;    --  from ada-with-indent"
+   >>>>Ada.Numerics;"
   :type 'integer :group 'ada)
 
 (defcustom ada-which-compiler 'gnat
   "*Name of the compiler to use.
-This will determine what features are made available through the ada-mode.
-The possible choices are :
-`gnat': Use Ada Core Technologies' Gnat compiler.  Add some cross-referencing
-    features
-`generic': Use a generic compiler"
+This will determine what features are made available through the Ada mode.
+The possible choices are:
+`gnat': Use Ada Core Technologies' GNAT compiler.  Add some cross-referencing
+    features.
+`generic': Use a generic compiler."
   :type '(choice (const gnat)
-                 (const generic))
+                (const generic))
   :group 'ada)
 
 
@@ -456,7 +457,7 @@ The extensions should include a `.' if needed.")
 The extensions should include a `.' if needed.")
 
 (defvar ada-mode-menu (make-sparse-keymap "Ada")
-  "Menu for ada-mode.")
+  "Menu for Ada mode.")
 
 (defvar ada-mode-map (make-sparse-keymap)
   "Local keymap used for Ada mode.")
@@ -471,6 +472,7 @@ The extensions should include a `.' if needed.")
   "Syntax table for Ada, where `_' is a word constituent.")
 
 (eval-when-compile
+  ;; These values are used in eval-when-compile expressions.
   (defconst ada-83-string-keywords
     '("abort" "abs" "accept" "access" "all" "and" "array" "at" "begin"
       "body" "case" "constant" "declare" "delay" "delta" "digits" "do"
@@ -480,8 +482,18 @@ The extensions should include a `.' if needed.")
       "procedure" "raise" "range" "record" "rem" "renames" "return"
       "reverse" "select" "separate" "subtype" "task" "terminate" "then"
       "type" "use" "when" "while" "with" "xor")
-    "List of Ada keywords.
-This variable is used to define `ada-83-keywords' and `ada-95-keywords'"))
+    "List of Ada 83 keywords.
+Used to define `ada-*-keywords'.")
+
+  (defconst ada-95-string-keywords
+    '("abstract" "aliased" "protected" "requeue" "tagged" "until")
+    "List of keywords new in Ada 95.
+Used to define `ada-*-keywords'.")
+
+  (defconst ada-2005-string-keywords
+    '("interface" "overriding" "synchronized")
+    "List of keywords new in Ada 2005.
+Used to define `ada-*-keywords.'"))
 
 (defvar ada-ret-binding nil
   "Variable to save key binding of RET when casing is activated.")
@@ -507,7 +519,7 @@ See `ff-other-file-alist'.")
       ("[^=]\\(\\s-+\\)=[^=]" 1 t)
       ("\\(\\s-*\\)use\\s-" 1)
       ("\\(\\s-*\\)--" 1))
-    "Ada support for align.el <= 2.2
+    "Ada support for align.el <= 2.2.
 This variable provides regular expressions on which to align different lines.
 See `align-mode-alist' for more information.")
 
@@ -528,28 +540,29 @@ See `align-mode-alist' for more information.")
      (valid   . (lambda() (not (ada-in-comment-p))))
      (modes   . '(ada-mode)))
     )
-  "Ada support for align.el >= 2.8
+  "Ada support for align.el >= 2.8.
 This variable defines several rules to use to align different lines.")
 
 (defconst ada-align-region-separate
-  (concat
-   "^\\s-*\\($\\|\\("
-   "begin\\|"
-   "declare\\|"
-   "else\\|"
-   "end\\|"
-   "exception\\|"
-   "for\\|"
-   "function\\|"
-   "generic\\|"
-   "if\\|"
-   "is\\|"
-   "procedure\\|"
-   "record\\|"
-   "return\\|"
-   "type\\|"
-   "when"
-   "\\)\\>\\)")
+  (eval-when-compile
+    (concat
+     "^\\s-*\\($\\|\\("
+     "begin\\|"
+     "declare\\|"
+     "else\\|"
+     "end\\|"
+     "exception\\|"
+     "for\\|"
+     "function\\|"
+     "generic\\|"
+     "if\\|"
+     "is\\|"
+     "procedure\\|"
+     "record\\|"
+     "return\\|"
+     "type\\|"
+     "when"
+     "\\)\\>\\)"))
   "See the variable `align-region-separate' for more information.")
 
 ;;; ---- Below are the regexp used in this package for parsing
@@ -557,29 +570,38 @@ This variable defines several rules to use to align different lines.")
 (defconst ada-83-keywords
   (eval-when-compile
     (concat "\\<" (regexp-opt ada-83-string-keywords t) "\\>"))
-  "Regular expression for looking at Ada83 keywords.")
+  "Regular expression matching Ada83 keywords.")
 
 (defconst ada-95-keywords
   (eval-when-compile
     (concat "\\<" (regexp-opt
-                   (append
-                    '("abstract" "aliased" "protected" "requeue"
-                      "tagged" "until")
-                    ada-83-string-keywords) t) "\\>"))
-  "Regular expression for looking at Ada95 keywords.")
+                  (append
+                   ada-95-string-keywords
+                   ada-83-string-keywords) t) "\\>"))
+  "Regular expression matching Ada95 keywords.")
+
+(defconst ada-2005-keywords
+  (eval-when-compile
+    (concat "\\<" (regexp-opt
+                  (append
+                   ada-2005-string-keywords
+                   ada-83-string-keywords
+                   ada-95-string-keywords) t) "\\>"))
+  "Regular expression matching Ada2005 keywords.")
 
-(defvar ada-keywords ada-95-keywords
-  "Regular expression for looking at Ada keywords.")
+(defvar ada-keywords ada-2005-keywords
+  "Regular expression matching Ada keywords.")
+;; FIXME: make this customizable
 
 (defconst ada-ident-re
   "\\(\\sw\\|[_.]\\)+"
   "Regexp matching Ada (qualified) identifiers.")
 
-;;  "with" needs to be included in the regexp, so that we can insert new lines
-;;  after the declaration of the parameter for a generic.
+;;  "with" needs to be included in the regexp, to match generic subprogram parameters
+;;  Similarly, we put '[not] overriding' on the same line with 'procedure' etc.
 (defvar ada-procedure-start-regexp
   (concat
-   "^[ \t]*\\(with[ \t]+\\)?\\(procedure\\|function\\|task\\)[ \t\n]+"
+   "^[ \t]*\\(with[ \t]+\\)?\\(\\(not[ \t]+\\)?overriding[ \t]+\\)?\\(procedure\\|function\\|task\\)[ \t\n]+"
 
    ;;  subprogram name: operator ("[+/=*]")
    "\\("
@@ -589,11 +611,21 @@ This variable defines several rules to use to align different lines.")
    "\\|"
    "\\(\\(\\sw\\|[_.]\\)+\\)"
    "\\)")
-  "Regexp used to find Ada procedures/functions.")
+  "Regexp matching Ada subprogram start.
+The actual start is at (match-beginning 4). The name is in (match-string 5).")
+
+(defconst ada-name-regexp
+  "\\([a-zA-Z][a-zA-Z0-9_.']*[a-zA-Z0-9]\\)"
+  "Regexp matching a fully qualified name (including attribute).")
+
+(defconst ada-package-start-regexp
+  (concat "^[ \t]*\\(private[ \t]+\\)?\\(package\\)[ \t\n]+\\(body[ \t]*\\)?" ada-name-regexp)
+  "Regexp matching start of package.
+The package name is in (match-string 4).")
 
-(defvar ada-package-start-regexp
-  "^[ \t]*\\(package\\)"
-  "Regexp used to find Ada packages.")
+(defconst ada-compile-goto-error-file-linenr-re
+  "\\([-_.a-zA-Z0-9]+\\):\\([0-9]+\\)\\(:\\([0-9]+\\)\\)?"
+  "Regexp matching filename:linenr[:column].")
 
 
 ;;; ---- regexps for indentation functions
@@ -601,42 +633,42 @@ This variable defines several rules to use to align different lines.")
 (defvar ada-block-start-re
   (eval-when-compile
     (concat "\\<\\(" (regexp-opt '("begin" "declare" "else"
-                                   "exception" "generic" "loop" "or"
-                                   "private" "select" ))
-            "\\|\\(\\(limited\\|abstract\\|tagged\\)[ \t\n]+\\)*record\\)\\>"))
+                                  "exception" "generic" "loop" "or"
+                                  "private" "select" ))
+           "\\|\\(\\(limited\\|abstract\\|tagged\\)[ \t\n]+\\)*record\\)\\>"))
   "Regexp for keywords starting Ada blocks.")
 
 (defvar ada-end-stmt-re
   (eval-when-compile
     (concat "\\("
-            ";"                                        "\\|"
-            "=>[ \t]*$"                                "\\|"
-            "^[ \t]*separate[ \t]*(\\(\\sw\\|[_.]\\)+)"  "\\|"
-            "\\<" (regexp-opt '("begin" "declare" "is" "do" "else" "generic"
-                                "loop" "private" "record" "select"
-                                "then abort" "then") t) "\\>"  "\\|"
-            "^[ \t]*" (regexp-opt '("function" "package" "procedure")
-                                  t) "\\>\\(\\sw\\|[ \t_.]\\)+\\<is\\>"        "\\|"
-            "^[ \t]*exception\\>"
-            "\\)")                      )
+           ";"                                        "\\|"
+           "=>[ \t]*$"                                "\\|"
+           "^[ \t]*separate[ \t]*(\\(\\sw\\|[_.]\\)+)"  "\\|"
+           "\\<" (regexp-opt '("begin" "declare" "is" "do" "else" "generic"
+                               "loop" "private" "record" "select"
+                               "then abort" "then") t) "\\>"  "\\|"
+           "^[ \t]*" (regexp-opt '("function" "package" "procedure")
+                                 t) "\\>\\(\\sw\\|[ \t_.]\\)+\\<is\\>"        "\\|"
+           "^[ \t]*exception\\>"
+           "\\)")                      )
   "Regexp of possible ends for a non-broken statement.
 A new statement starts after these.")
 
 (defvar ada-matching-start-re
   (eval-when-compile
     (concat "\\<"
-            (regexp-opt
-             '("end" "loop" "select" "begin" "case" "do"
-               "if" "task" "package" "record" "protected") t)
-            "\\>"))
+           (regexp-opt
+            '("end" "loop" "select" "begin" "case" "do" "declare"
+              "if" "task" "package" "procedure" "function" "record" "protected") t)
+           "\\>"))
   "Regexp used in `ada-goto-matching-start'.")
 
 (defvar ada-matching-decl-start-re
   (eval-when-compile
     (concat "\\<"
-            (regexp-opt
-             '("is" "separate" "end" "declare" "if" "new" "begin" "generic" "when") t)
-            "\\>"))
+           (regexp-opt
+            '("is" "separate" "end" "declare" "if" "new" "begin" "generic" "when") t)
+           "\\>"))
   "Regexp used in `ada-goto-matching-decl-start'.")
 
 (defvar ada-loop-start-re
@@ -646,7 +678,7 @@ A new statement starts after these.")
 (defvar ada-subprog-start-re
   (eval-when-compile
     (concat "\\<" (regexp-opt '("accept" "entry" "function" "package" "procedure"
-                                "protected" "task") t) "\\>"))
+                               "protected" "task") t) "\\>"))
   "Regexp for the start of a subprogram.")
 
 (defvar ada-named-block-re
@@ -702,13 +734,13 @@ displaying the menu if point was on an identifier."
   (list
    (list nil ada-imenu-subprogram-menu-re 2)
    (list "*Specs*"
-         (concat
-          "^[ \t]*\\(procedure\\|function\\)[ \t\n]+\\(\\(\\sw\\|_\\)+\\)"
-          "\\("
-          "\\(" ada-imenu-comment-re "[ \t\n]+\\|[ \t\n]*([^)]+)"
+        (concat
+         "^[ \t]*\\(procedure\\|function\\)[ \t\n]+\\(\\(\\sw\\|_\\)+\\)"
+         "\\("
+         "\\(" ada-imenu-comment-re "[ \t\n]+\\|[ \t\n]*([^)]+)"
          ada-imenu-comment-re "\\)";; parameter list or simple space
-          "\\([ \t\n]*return[ \t\n]+\\(\\sw\\|[_.]\\)+[ \t\n]*\\)?"
-          "\\)?;") 2)
+         "\\([ \t\n]*return[ \t\n]+\\(\\sw\\|[_.]\\)+[ \t\n]*\\)?"
+         "\\)?;") 2)
    '("*Tasks*" "^[ \t]*task[ \t]+\\(type[ \t]+\\)?\\(\\(body[ \t]+\\)?\\(\\sw\\|_\\)+\\)" 2)
    '("*Type Defs*" "^[ \t]*\\(sub\\)?type[ \t]+\\(\\(\\sw\\|_\\)+\\)" 2)
    '("*Protected*"
@@ -724,7 +756,7 @@ each type of entity that can be found in an Ada file.")
 ;;------------------------------------------------------------
 
 (defun ada-compile-mouse-goto-error ()
-  "Mouse interface for ada-compile-goto-error."
+  "Mouse interface for `ada-compile-goto-error'."
   (interactive)
   (mouse-set-point last-input-event)
   (ada-compile-goto-error (point))
@@ -734,49 +766,52 @@ each type of entity that can be found in an Ada file.")
   "Replace `compile-goto-error' from compile.el.
 If POS is on a file and line location, go to this position.  It adds
 to compile.el the capacity to go to a reference in an error message.
-For instance, on this line:
+For instance, on these lines:
   foo.adb:61:11:  [...] in call to size declared at foo.ads:11
-both file locations can be clicked on and jumped to."
+  foo.adb:61:11:  [...] in call to local declared at line 20
+the 4 file locations can be clicked on and jumped to."
   (interactive "d")
   (goto-char pos)
 
   (skip-chars-backward "-a-zA-Z0-9_:./\\")
   (cond
    ;;  special case: looking at a filename:line not at the beginning of a line
+   ;;  or a simple line reference "at line ..."
    ((and (not (bolp))
-         (looking-at
-          "\\([-_.a-zA-Z0-9]+\\):\\([0-9]+\\)\\(:\\([0-9]+\\)\\)?"))
-    (let ((line (match-string 2))
-          file
-          (error-pos (point-marker))
-          source)
+        (or (looking-at ada-compile-goto-error-file-linenr-re)
+            (and
+             (save-excursion
+               (beginning-of-line)
+               (looking-at ada-compile-goto-error-file-linenr-re))
+             (save-excursion
+               (if (looking-at "\\([0-9]+\\)") (backward-word 1))
+               (looking-at "line \\([0-9]+\\)"))))
+            )
+    (let ((line (if (match-beginning 2) (match-string 2) (match-string 1)))
+         (file (if (match-beginning 2) (match-string 1)
+                 (save-excursion (beginning-of-line)
+                                 (looking-at ada-compile-goto-error-file-linenr-re)
+                                 (match-string 1))))
+         (error-pos (point-marker))
+         source)
+
+      ;; set source marker
       (save-excursion
-        (save-restriction
-          (widen)
-          ;;  Use funcall so as to prevent byte-compiler warnings
-          ;;  `ada-find-file' is not defined if ada-xref wasn't loaded. But
-          ;;  if we can find it, we should use it instead of
-          ;;  `compilation-find-file', since the latter doesn't know anything
-          ;;  about source path.
-
-          (if (functionp 'ada-find-file)
-              (setq file (funcall (symbol-function 'ada-find-file)
-                                  (match-string 1)))
-            (setq file (funcall (symbol-function 'compilation-find-file)
-                                (point-marker) (match-string 1)
-                                "./")))
-          (set-buffer file)
-
-          (if (stringp line)
-              (goto-line (string-to-number line)))
-          (setq source (point-marker))))
-      (funcall (symbol-function 'compilation-goto-locus)
-               (cons source error-pos))
+        (compilation-find-file (point-marker) (match-string 1) "./")
+        (set-buffer file)
+
+        (if (stringp line)
+            (goto-line (string-to-number line)))
+
+        (setq source (point-marker)))
+
+      (compilation-goto-locus error-pos source nil)
+
       ))
 
    ;; otherwise, default behavior
    (t
-    (funcall (symbol-function 'compile-goto-error)))
+    (compile-goto-error))
    )
   (recenter))
 
@@ -794,13 +829,12 @@ both file locations can be clicked on and jumped to."
 ;; Thus their syntax property is changed automatically, and we can still use
 ;; the standard Emacs functions for sexp (see `ada-in-string-p')
 ;;
-;; On Emacs, this is done through the `syntax-table' text property. The
-;; modification is done automatically each time the user as typed a new
-;; character. This is already done in `font-lock-mode' (in
-;; `font-lock-syntactic-keywords', so we take advantage of the existing
-;; mechanism. If font-lock-mode is not activated, we do it by hand in
-;; `ada-after-change-function', thanks to `ada-deactivate-properties' and
-;; `ada-initialize-properties'.
+;; On Emacs, this is done through the `syntax-table' text property.  The
+;; corresponding action is applied automatically each time the buffer
+;; changes.  If `font-lock-mode' is enabled (the default) the action is
+;; set up by `font-lock-syntactic-keywords'.  Otherwise, we do it
+;; manually in `ada-after-change-function'.  The proper method is
+;; installed by `ada-handle-syntax-table-properties'.
 ;;
 ;; on XEmacs, the `syntax-table' property does not exist and we have to use a
 ;; slow advice to `parse-partial-sexp' to do the same thing.
@@ -817,7 +851,6 @@ The standard table declares `_' as a symbol constituent, the second one
 declares it as a word constituent."
   (interactive)
   (setq ada-mode-syntax-table (make-syntax-table))
-  (set-syntax-table  ada-mode-syntax-table)
 
   ;; define string brackets (`%' is alternative string bracket, but
   ;; almost never used as such and throws font-lock and indentation
@@ -875,105 +908,116 @@ declares it as a word constituent."
     (defadvice parse-partial-sexp (around parse-partial-sexp-protect-constants)
       "Handles special character constants and gnatprep statements."
       (let (change)
-        (if (< to from)
-            (let ((tmp from))
-              (setq from to  to tmp)))
-        (save-excursion
-          (goto-char from)
-          (while (re-search-forward "'\\([(\")#]\\)'" to t)
-            (setq change (cons (list (match-beginning 1)
-                                     1
-                                     (match-string 1))
-                               change))
-            (replace-match "'A'"))
-          (goto-char from)
-          (while (re-search-forward "\\(#[0-9a-fA-F]*#\\)" to t)
-            (setq change (cons (list (match-beginning 1)
-                                     (length (match-string 1))
-                                     (match-string 1))
-                               change))
-            (replace-match (make-string (length (match-string 1)) ?@))))
-        ad-do-it
-        (save-excursion
-          (while change
-            (goto-char (caar change))
-            (delete-char (cadar change))
-            (insert (caddar change))
-            (setq change (cdr change)))))))
-
-(defun ada-deactivate-properties ()
-  "Deactivate ada-mode's properties handling.
-This would be a duplicate of font-lock if both are used at the same time."
-  (remove-hook 'after-change-functions 'ada-after-change-function t))
-
-(defun ada-initialize-properties ()
-  "Initialize some special text properties in the whole buffer.
-In particular, character constants are said to be strings, #...# are treated
-as numbers instead of gnatprep comments."
-  (save-excursion
-    (save-restriction
-      (widen)
-      (goto-char (point-min))
-      (while (re-search-forward "'.'" nil t)
-        (add-text-properties (match-beginning 0) (match-end 0)
-                             '(syntax-table ("'" . ?\"))))
-      (goto-char (point-min))
-      (while (re-search-forward "^[ \t]*#" nil t)
-        (add-text-properties (match-beginning 0) (match-end 0)
-                             '(syntax-table (11 . 10))))
-      (set-buffer-modified-p nil)
-
-      ;;  Setting this only if font-lock is not set won't work
-      ;;  if the user activates or deactivates font-lock-mode,
-      ;;  but will make things faster most of the time
-      (add-hook 'after-change-functions 'ada-after-change-function nil t)
-      )))
+       (if (< to from)
+           (let ((tmp from))
+             (setq from to  to tmp)))
+       (save-excursion
+         (goto-char from)
+         (while (re-search-forward "'\\([(\")#]\\)'" to t)
+           (setq change (cons (list (match-beginning 1)
+                                    1
+                                    (match-string 1))
+                              change))
+           (replace-match "'A'"))
+         (goto-char from)
+         (while (re-search-forward "\\(#[0-9a-fA-F]*#\\)" to t)
+           (setq change (cons (list (match-beginning 1)
+                                    (length (match-string 1))
+                                    (match-string 1))
+                              change))
+           (replace-match (make-string (length (match-string 1)) ?@))))
+       ad-do-it
+       (save-excursion
+         (while change
+           (goto-char (caar change))
+           (delete-char (cadar change))
+           (insert (caddar change))
+           (setq change (cdr change)))))))
+
+(defun ada-set-syntax-table-properties ()
+  "Assign `syntax-table' properties in accessible part of buffer.
+In particular, character constants are said to be strings, #...#
+are treated as numbers instead of gnatprep comments."
+  (let ((modified (buffer-modified-p))
+       (buffer-undo-list t)
+       (inhibit-read-only t)
+       (inhibit-point-motion-hooks t)
+       (inhibit-modification-hooks t))
+    (remove-text-properties (point-min) (point-max) '(syntax-table nil))
+    (goto-char (point-min))
+    (while (re-search-forward
+           ;; The following regexp was adapted from
+           ;; `ada-font-lock-syntactic-keywords'.
+           "^[ \t]*\\(#\\(?:if\\|else\\|elsif\\|end\\)\\)\\|[^a-zA-Z0-9)]\\('\\)[^'\n]\\('\\)"
+           nil t)
+      (if (match-beginning 1)
+         (put-text-property
+              (match-beginning 1) (match-end 1) 'syntax-table '(11 . ?\n))
+       (put-text-property
+            (match-beginning 2) (match-end 2) 'syntax-table '(7 . ?'))
+       (put-text-property
+            (match-beginning 3) (match-end 3) 'syntax-table '(7 . ?'))))
+    (unless modified
+      (restore-buffer-modified-p nil))))
 
 (defun ada-after-change-function (beg end old-len)
   "Called when the region between BEG and END was changed in the buffer.
 OLD-LEN indicates what the length of the replaced text was."
-  (let ((inhibit-point-motion-hooks t)
-        (eol (point)))
+  (save-excursion
+    (save-restriction
+      (let ((from (progn (goto-char beg) (line-beginning-position)))
+           (to (progn (goto-char end) (line-end-position))))
+       (narrow-to-region from to)
+       (save-match-data
+         (ada-set-syntax-table-properties))))))
+
+(defun ada-initialize-syntax-table-properties ()
+  "Assign `syntax-table' properties in current buffer."
     (save-excursion
-      (save-match-data
-        (beginning-of-line)
-        (remove-text-properties (point) eol '(syntax-table nil))
-        (while (re-search-forward "'.'" eol t)
-          (add-text-properties (match-beginning 0) (match-end 0)
-                               '(syntax-table ("'" . ?\"))))
-        (beginning-of-line)
-        (if (looking-at "^[ \t]*#")
-            (add-text-properties (match-beginning 0) (match-end 0)
-                                 '(syntax-table (11 . 10))))))))
+      (save-restriction
+       (widen)
+       (save-match-data
+         (ada-set-syntax-table-properties))))
+    (add-hook 'after-change-functions 'ada-after-change-function nil t))
+
+(defun ada-handle-syntax-table-properties ()
+  "Handle `syntax-table' properties."
+  (if font-lock-mode
+      ;; `font-lock-mode' will take care of `syntax-table' properties.
+      (remove-hook 'after-change-functions 'ada-after-change-function t)
+    ;; Take care of `syntax-table' properties manually.
+    (ada-initialize-syntax-table-properties)))
 
 ;;------------------------------------------------------------------
 ;;  Testing the grammatical context
 ;;------------------------------------------------------------------
 
 (defsubst ada-in-comment-p (&optional parse-result)
-  "Return t if inside a comment."
+  "Return t if inside a comment.
+If PARSE-RESULT is non-nil, use it instead of calling `parse-partial-sexp'."
   (nth 4 (or parse-result
-             (parse-partial-sexp
-              (line-beginning-position) (point)))))
+            (parse-partial-sexp
+             (line-beginning-position) (point)))))
 
 (defsubst ada-in-string-p (&optional parse-result)
   "Return t if point is inside a string.
-If parse-result is non-nil, use is instead of calling `parse-partial-sexp'."
+If PARSE-RESULT is non-nil, use it instead of calling `parse-partial-sexp'."
   (nth 3 (or parse-result
-             (parse-partial-sexp
-              (line-beginning-position) (point)))))
+            (parse-partial-sexp
+             (line-beginning-position) (point)))))
 
 (defsubst ada-in-string-or-comment-p (&optional parse-result)
-  "Return t if inside a comment or string."
+  "Return t if inside a comment or string.
+If PARSE-RESULT is non-nil, use it instead of calling `parse-partial-sexp'."
   (setq parse-result (or parse-result
-                         (parse-partial-sexp
-                          (line-beginning-position) (point))))
+                        (parse-partial-sexp
+                         (line-beginning-position) (point))))
   (or (ada-in-string-p parse-result) (ada-in-comment-p parse-result)))
 
 
 ;;------------------------------------------------------------------
 ;; Contextual menus
-;; The Ada-mode comes with contextual menus, bound by default to the right
+;; The Ada mode comes with contextual menus, bound by default to the right
 ;; mouse button.
 ;; Add items to this menu by modifying `ada-contextual-menu'. Note that the
 ;; variable `ada-contextual-menu-on-identifier' is set automatically to t
@@ -986,7 +1030,7 @@ It forces Emacs to change the cursor position."
   (interactive)
   (funcall function)
   (setq ada-contextual-menu-last-point
-        (list (point) (current-buffer))))
+       (list (point) (current-buffer))))
 
 (defun ada-popup-menu (position)
   "Pops up a contextual menu, depending on where the user clicked.
@@ -1001,23 +1045,23 @@ point is where the mouse button was clicked."
   ;;  transient-mark-mode.
   (let ((deactivate-mark nil))
     (setq ada-contextual-menu-last-point
-         (list (point) (current-buffer)))
+        (list (point) (current-buffer)))
     (mouse-set-point last-input-event)
 
     (setq ada-contextual-menu-on-identifier
-          (and (char-after)
-               (or (= (char-syntax (char-after)) ?w)
-                   (= (char-after) ?_))
-               (not (ada-in-string-or-comment-p))
-               (save-excursion (skip-syntax-forward "w")
-                               (not (ada-after-keyword-p)))
-               ))
+         (and (char-after)
+              (or (= (char-syntax (char-after)) ?w)
+                  (= (char-after) ?_))
+              (not (ada-in-string-or-comment-p))
+              (save-excursion (skip-syntax-forward "w")
+                              (not (ada-after-keyword-p)))
+              ))
     (if (fboundp 'popup-menu)
        (funcall (symbol-function 'popup-menu) ada-contextual-menu)
       (let (choice)
        (setq choice (x-popup-menu position ada-contextual-menu))
-       (if choice
-           (funcall (lookup-key ada-contextual-menu (vector (car choice)))))))
+       (if choice
+           (funcall (lookup-key ada-contextual-menu (vector (car choice)))))))
 
     (set-buffer (cadr ada-contextual-menu-last-point))
     (goto-char (car ada-contextual-menu-last-point))
@@ -1036,15 +1080,15 @@ extensions.
 SPEC and BODY are two regular expressions that must match against
 the file name."
   (let* ((reg (concat (regexp-quote body) "$"))
-         (tmp (assoc reg ada-other-file-alist)))
+        (tmp (assoc reg ada-other-file-alist)))
     (if tmp
-        (setcdr tmp (list (cons spec (cadr tmp))))
+       (setcdr tmp (list (cons spec (cadr tmp))))
       (add-to-list 'ada-other-file-alist (list reg (list spec)))))
 
   (let* ((reg (concat (regexp-quote spec) "$"))
-         (tmp (assoc reg ada-other-file-alist)))
+        (tmp (assoc reg ada-other-file-alist)))
     (if tmp
-        (setcdr tmp (list (cons body (cadr tmp))))
+       (setcdr tmp (list (cons body (cadr tmp))))
       (add-to-list 'ada-other-file-alist (list reg (list body)))))
 
   (add-to-list 'auto-mode-alist
@@ -1059,10 +1103,10 @@ the file name."
   ;; speedbar)
   (if (fboundp 'speedbar-add-supported-extension)
       (progn
-        (funcall (symbol-function 'speedbar-add-supported-extension)
-                 spec)
-        (funcall (symbol-function 'speedbar-add-supported-extension)
-                 body)))
+       (funcall (symbol-function 'speedbar-add-supported-extension)
+                spec)
+       (funcall (symbol-function 'speedbar-add-supported-extension)
+                body)))
   )
 
 
@@ -1101,18 +1145,20 @@ If you use imenu.el:
 
 If you use find-file.el:
  Switch to other file (Body <-> Spec)                 '\\[ff-find-other-file]'
-                                                   or '\\[ff-mouse-find-other-file]
+                                                  or '\\[ff-mouse-find-other-file]
  Switch to other file in other window                 '\\[ada-ff-other-window]'
-                                                   or '\\[ff-mouse-find-other-file-other-window]
+                                                  or '\\[ff-mouse-find-other-file-other-window]
  If you use this function in a spec and no body is available, it gets created with body stubs.
 
 If you use ada-xref.el:
  Goto declaration:          '\\[ada-point-and-xref]' on the identifier
-                         or '\\[ada-goto-declaration]' with point on the identifier
+                        or '\\[ada-goto-declaration]' with point on the identifier
  Complete identifier:       '\\[ada-complete-identifier]'."
 
   (interactive)
   (kill-all-local-variables)
+  
+  (set-syntax-table ada-mode-syntax-table)
 
   (set (make-local-variable 'require-final-newline) mode-require-final-newline)
 
@@ -1135,7 +1181,7 @@ If you use ada-xref.el:
   ;; aligned under the latest parameter, not under the declaration start).
   (set (make-local-variable 'comment-line-break-function)
        (lambda (&optional soft) (let ((fill-prefix nil))
-                                  (indent-new-comment-line soft))))
+                                 (indent-new-comment-line soft))))
 
   (set (make-local-variable 'indent-line-function)
        'ada-indent-current-function)
@@ -1148,9 +1194,9 @@ If you use ada-xref.el:
   (unless (featurep 'xemacs)
     (progn
       (if (ada-check-emacs-version 20 3)
-          (progn
-            (set (make-local-variable 'parse-sexp-ignore-comments) t)
-            (set (make-local-variable 'comment-padding) 0)))
+         (progn
+           (set (make-local-variable 'parse-sexp-ignore-comments) t)
+           (set (make-local-variable 'comment-padding) 0)))
       (set (make-local-variable 'parse-sexp-lookup-properties) t)
       ))
 
@@ -1167,7 +1213,7 @@ If you use ada-xref.el:
   ;;  Support for compile.el
   ;;  We just substitute our own functions to go to the error.
   (add-hook 'compilation-mode-hook
-            (lambda()
+           (lambda()
              (set (make-local-variable 'compile-auto-highlight) 40)
              ;; FIXME: This has global impact!  -stef
              (define-key compilation-minor-mode-map [mouse-2]
@@ -1184,15 +1230,15 @@ If you use ada-xref.el:
   (if (featurep 'xemacs)
       ;;  XEmacs
       (put 'ada-mode 'font-lock-defaults
-           '(ada-font-lock-keywords
-             nil t ((?\_ . "w") (?# . ".")) beginning-of-line))
+          '(ada-font-lock-keywords
+            nil t ((?\_ . "w") (?# . ".")) beginning-of-line))
     ;;  Emacs
     (set (make-local-variable 'font-lock-defaults)
-         '(ada-font-lock-keywords
-           nil t
-           ((?\_ . "w") (?# . "."))
-           beginning-of-line
-           (font-lock-syntactic-keywords . ada-font-lock-syntactic-keywords)))
+        '(ada-font-lock-keywords
+          nil t
+          ((?\_ . "w") (?# . "."))
+          beginning-of-line
+          (font-lock-syntactic-keywords . ada-font-lock-syntactic-keywords)))
     )
 
   ;; Set up support for find-file.el.
@@ -1201,63 +1247,39 @@ If you use ada-xref.el:
   (set (make-local-variable 'ff-search-directories)
        'ada-search-directories-internal)
   (setq ff-post-load-hook    'ada-set-point-accordingly
-        ff-file-created-hook 'ada-make-body)
+       ff-file-created-hook 'ada-make-body)
   (add-hook 'ff-pre-load-hook 'ada-which-function-are-we-in)
 
-  ;; Some special constructs for find-file.el
-  ;; We do not need to add the construction for 'with', which is in the
-  ;; standard find-file.el
   (make-local-variable 'ff-special-constructs)
-
-  ;; Go to the parent package :
-  (add-to-list 'ff-special-constructs
-               (cons (eval-when-compile
-                       (concat "^\\(private[ \t]\\)?[ \t]*package[ \t]+"
-                               "\\(body[ \t]+\\)?"
-                               "\\(\\(\\sw\\|[_.]\\)+\\)\\.\\(\\sw\\|_\\)+[ \t\n]+is"))
-                     (lambda ()
-                      (if (fboundp 'ff-get-file)
-                          (if (boundp 'fname)
-                              (set 'fname (ff-get-file
-                                           ada-search-directories-internal
-                                           (ada-make-filename-from-adaname
-                                            (match-string 3))
-                                           ada-spec-suffixes)))))))
-  ;; Another special construct for find-file.el : when in a separate clause,
-  ;; go to the correct package.
-  (add-to-list 'ff-special-constructs
-               (cons "^separate[ \t\n]*(\\(\\(\\sw\\|[_.]\\)+\\))"
-                     (lambda ()
-                      (if (fboundp 'ff-get-file)
-                          (if (boundp 'fname)
-                              (setq fname (ff-get-file
-                                           ada-search-directories-internal
-                                           (ada-make-filename-from-adaname
-                                            (match-string 1))
-                                           ada-spec-suffixes)))))))
-
-  ;; Another special construct, that redefines the one in find-file.el. The
-  ;; old one can handle only one possible type of extension for Ada files
-  ;;  remove from the list the standard "with..." that is put by find-file.el,
-  ;;  since it uses the old ada-spec-suffix variable
-  ;; This one needs to replace the standard one defined in find-file.el (with
-  ;;  Emacs <= 20.4), since that one uses the old variable ada-spec-suffix
-  (let ((old-construct
-         (assoc "^with[ \t]+\\([a-zA-Z0-9_\\.]+\\)" ff-special-constructs))
-        (new-cdr
-         (lambda ()
-          (if (fboundp 'ff-get-file)
-              (if (boundp 'fname)
-                  (set 'fname (ff-get-file
-                               ada-search-directories-internal
-                               (ada-make-filename-from-adaname
-                                (match-string 1))
-                               ada-spec-suffixes)))))))
-    (if old-construct
-        (setcdr old-construct new-cdr)
-      (add-to-list 'ff-special-constructs
-                   (cons "^with[ \t]+\\([a-zA-Z0-9_\\.]+\\)"
-                         new-cdr))))
+  (mapc (lambda (pair) (add-to-list 'ff-special-constructs pair))
+        (list
+         ;; Top level child package declaration; go to the parent package.
+         (cons (eval-when-compile
+                 (concat "^\\(private[ \t]\\)?[ \t]*package[ \t]+"
+                         "\\(body[ \t]+\\)?"
+                         "\\(\\(\\sw\\|[_.]\\)+\\)\\.\\(\\sw\\|_\\)+[ \t\n]+is"))
+               (lambda ()
+                 (ff-get-file
+                  ada-search-directories-internal
+                  (ada-make-filename-from-adaname (match-string 3))
+                  ada-spec-suffixes)))
+
+         ;; A "separate" clause.
+         (cons "^separate[ \t\n]*(\\(\\(\\sw\\|[_.]\\)+\\))"
+               (lambda ()
+                 (ff-get-file
+                  ada-search-directories-internal
+                  (ada-make-filename-from-adaname (match-string 1))
+                  ada-spec-suffixes)))
+
+         ;; A "with" clause.
+         (cons "^with[ \t]+\\([a-zA-Z0-9_\\.]+\\)"
+               (lambda ()
+                 (ff-get-file
+                  ada-search-directories-internal
+                  (ada-make-filename-from-adaname (match-string 1))
+                  ada-spec-suffixes)))
+         ))
 
   ;;  Support for outline-minor-mode
   (set (make-local-variable 'outline-regexp)
@@ -1270,59 +1292,49 @@ If you use ada-xref.el:
   ;;  Support for ispell : Check only comments
   (set (make-local-variable 'ispell-check-comments) 'exclusive)
 
-  ;;  Support for align.el <= 2.2, if present
-  ;;  align.el is distributed with Emacs 21, but not with earlier versions.
-  (if (boundp 'align-mode-alist)
-      (add-to-list 'align-mode-alist '(ada-mode . ada-align-list)))
-
-  ;;  Support for align.el >= 2.8, if present
-  (if (boundp 'align-dq-string-modes)
-      (progn
-       (add-to-list 'align-dq-string-modes 'ada-mode)
-       (add-to-list 'align-open-comment-modes 'ada-mode)
-       (set (make-variable-buffer-local 'align-region-separate)
-            ada-align-region-separate)
-
-       ;; Exclude comments alone on line from alignment.
-       (add-to-list 'align-exclude-rules-list
-                    '(ada-solo-comment
-                      (regexp  . "^\\(\\s-*\\)--")
-                      (modes   . '(ada-mode))))
-       (add-to-list 'align-exclude-rules-list
-                    '(ada-solo-use
-                      (regexp  . "^\\(\\s-*\\)\\<use\\>")
-                      (modes   . '(ada-mode))))
-
-       (setq ada-align-modes nil)
-
-       (add-to-list 'ada-align-modes
-                    '(ada-declaration-assign
-                      (regexp  . "[^:]\\(\\s-*\\):[^:]")
-                      (valid   . (lambda() (not (ada-in-comment-p))))
-                      (repeat . t)
-                      (modes   . '(ada-mode))))
-       (add-to-list 'ada-align-modes
-                    '(ada-associate
-                      (regexp  . "[^=]\\(\\s-*\\)=>")
-                      (valid   . (lambda() (not (ada-in-comment-p))))
-                      (modes   . '(ada-mode))))
-       (add-to-list 'ada-align-modes
-                    '(ada-comment
-                      (regexp  . "\\(\\s-*\\)--")
-                      (modes   . '(ada-mode))))
-       (add-to-list 'ada-align-modes
-                    '(ada-use
-                      (regexp  . "\\(\\s-*\\)\\<use\\s-")
-                      (valid   . (lambda() (not (ada-in-comment-p))))
-                      (modes   . '(ada-mode))))
-       (add-to-list 'ada-align-modes
-                    '(ada-at
-                      (regexp . "\\(\\s-+\\)at\\>")
-                      (modes . '(ada-mode))))
-
-
-       (setq align-mode-rules-list ada-align-modes)
-       ))
+  ;;  Support for align
+  (add-to-list 'align-dq-string-modes 'ada-mode)
+  (add-to-list 'align-open-comment-modes 'ada-mode)
+  (set (make-local-variable 'align-region-separate) ada-align-region-separate)
+
+  ;; Exclude comments alone on line from alignment.
+  (add-to-list 'align-exclude-rules-list
+               '(ada-solo-comment
+                 (regexp  . "^\\(\\s-*\\)--")
+                 (modes   . '(ada-mode))))
+  (add-to-list 'align-exclude-rules-list
+               '(ada-solo-use
+                 (regexp  . "^\\(\\s-*\\)\\<use\\>")
+                 (modes   . '(ada-mode))))
+
+  (setq ada-align-modes nil)
+
+  (add-to-list 'ada-align-modes
+               '(ada-declaration-assign
+                 (regexp  . "[^:]\\(\\s-*\\):[^:]")
+                 (valid   . (lambda() (not (ada-in-comment-p))))
+                 (repeat . t)
+                 (modes   . '(ada-mode))))
+  (add-to-list 'ada-align-modes
+               '(ada-associate
+                 (regexp  . "[^=]\\(\\s-*\\)=>")
+                 (valid   . (lambda() (not (ada-in-comment-p))))
+                 (modes   . '(ada-mode))))
+  (add-to-list 'ada-align-modes
+               '(ada-comment
+                 (regexp  . "\\(\\s-*\\)--")
+                 (modes   . '(ada-mode))))
+  (add-to-list 'ada-align-modes
+               '(ada-use
+                 (regexp  . "\\(\\s-*\\)\\<use\\s-")
+                 (valid   . (lambda() (not (ada-in-comment-p))))
+                 (modes   . '(ada-mode))))
+  (add-to-list 'ada-align-modes
+               '(ada-at
+                 (regexp . "\\(\\s-+\\)at\\>")
+                 (modes . '(ada-mode))))
+
+  (setq align-mode-rules-list ada-align-modes)
 
   ;;  Set up the contextual menu
   (if ada-popup-key
@@ -1333,17 +1345,11 @@ If you use ada-xref.el:
   (setq local-abbrev-table ada-mode-abbrev-table)
 
   ;;  Support for which-function mode
-  ;; which-function-mode does not work with nested subprograms, since it is
-  ;; based only on the regexps generated by imenu, and thus can only detect the
-  ;; beginning of subprograms, not the end.
-  ;; Fix is: redefine a new function ada-which-function, and call it when the
-  ;; major-mode is ada-mode.
-
   (make-local-variable 'which-func-functions)
   (setq which-func-functions '(ada-which-function))
 
   ;;  Support for indent-new-comment-line (Especially for XEmacs)
-  (setq comment-multi-line nil)
+  (set (make-local-variable 'comment-multi-line) nil)
 
   (setq major-mode 'ada-mode
        mode-name "Ada")
@@ -1356,11 +1362,11 @@ If you use ada-xref.el:
 
   (if ada-clean-buffer-before-saving
       (progn
-        ;; remove all spaces at the end of lines in the whole buffer.
+       ;; remove all spaces at the end of lines in the whole buffer.
        (add-hook 'local-write-file-hooks 'delete-trailing-whitespace)
-        ;; convert all tabs to the correct number of spaces.
-        (add-hook 'local-write-file-hooks
-                  (lambda () (untabify (point-min) (point-max))))))
+       ;; convert all tabs to the correct number of spaces.
+       (add-hook 'local-write-file-hooks
+                 (lambda () (untabify (point-min) (point-max))))))
 
   (set (make-local-variable 'skeleton-further-elements)
        '((< '(backward-delete-char-untabify
@@ -1380,18 +1386,19 @@ If you use ada-xref.el:
   ;;  font-lock-mode
 
   (unless (featurep 'xemacs)
-    (progn
-      (ada-initialize-properties)
-      (add-hook 'font-lock-mode-hook 'ada-deactivate-properties nil t)))
+    (ada-initialize-syntax-table-properties)
+    (add-hook 'font-lock-mode-hook 'ada-handle-syntax-table-properties nil t))
 
   ;; the following has to be done after running the ada-mode-hook
   ;; because users might want to set the values of these variable
-  ;; inside the hook (MH)
+  ;; inside the hook
 
   (cond ((eq ada-language-version 'ada83)
-         (setq ada-keywords ada-83-keywords))
-        ((eq ada-language-version 'ada95)
-         (setq ada-keywords ada-95-keywords)))
+        (setq ada-keywords ada-83-keywords))
+       ((eq ada-language-version 'ada95)
+        (setq ada-keywords ada-95-keywords))
+       ((eq ada-language-version 'ada2005)
+        (setq ada-keywords ada-2005-keywords)))
 
   (if ada-auto-case
       (ada-activate-keys-for-case)))
@@ -1415,7 +1422,7 @@ If you use ada-xref.el:
 \f
 ;;-----------------------------------------------------------------
 ;;                      auto-casing
-;; Since Ada is case-insensitive, the Ada-mode provides an extensive set of
+;; Since Ada is case-insensitive, the Ada mode provides an extensive set of
 ;; functions to auto-case identifiers, keywords, ...
 ;; The basic rules for autocasing are defined through the variables
 ;; `ada-case-attribute', `ada-case-keyword' and `ada-case-identifier'. These
@@ -1428,18 +1435,16 @@ If you use ada-xref.el:
 ;;-----------------------------------------------------------------
 
 (defun ada-save-exceptions-to-file (file-name)
-  "Save the exception lists `ada-case-exception' and
-`ada-case-exception-substring' to the file FILE-NAME."
-
-  ;;  Save the list in the file
+  "Save the casing exception lists to the file FILE-NAME.
+Casing exception lists are `ada-case-exception' and `ada-case-exception-substring'."
   (find-file (expand-file-name file-name))
   (erase-buffer)
   (mapcar (lambda (x) (insert (car x) "\n"))
          (sort (copy-sequence ada-case-exception)
                (lambda(a b) (string< (car a) (car b)))))
   (mapcar (lambda (x) (insert "*" (car x) "\n"))
-            (sort (copy-sequence ada-case-exception-substring)
-                  (lambda(a b) (string< (car a) (car b)))))
+           (sort (copy-sequence ada-case-exception-substring)
+                 (lambda(a b) (string< (car a) (car b)))))
   (save-buffer)
   (kill-buffer nil)
   )
@@ -1451,23 +1456,23 @@ The new words is added to the first file in `ada-case-exception-file'.
 The standard casing rules will no longer apply to this word."
   (interactive)
   (let ((previous-syntax-table (syntax-table))
-        file-name
-        )
+       file-name
+       )
 
     (cond ((stringp ada-case-exception-file)
-           (setq file-name ada-case-exception-file))
-          ((listp ada-case-exception-file)
-           (setq file-name (car ada-case-exception-file)))
-          (t
-           (error (concat "No exception file specified. "
+          (setq file-name ada-case-exception-file))
+         ((listp ada-case-exception-file)
+          (setq file-name (car ada-case-exception-file)))
+         (t
+          (error (concat "No exception file specified.  "
                          "See variable ada-case-exception-file"))))
 
     (set-syntax-table ada-mode-symbol-syntax-table)
     (unless word
       (save-excursion
-        (skip-syntax-backward "w")
-        (setq word (buffer-substring-no-properties
-                    (point) (save-excursion (forward-word 1) (point))))))
+       (skip-syntax-backward "w")
+       (setq word (buffer-substring-no-properties
+                   (point) (save-excursion (forward-word 1) (point))))))
     (set-syntax-table previous-syntax-table)
 
     ;;  Reread the exceptions file, in case it was modified by some other,
@@ -1476,8 +1481,8 @@ The standard casing rules will no longer apply to this word."
     ;;  If the word is already in the list, even with a different casing
     ;;  we simply want to replace it.
     (if (and (not (equal ada-case-exception '()))
-             (assoc-string word ada-case-exception t))
-        (setcar (assoc-string word ada-case-exception t) word)
+            (assoc-string word ada-case-exception t))
+       (setcar (assoc-string word ada-case-exception t) word)
       (add-to-list 'ada-case-exception (cons word t))
       )
 
@@ -1498,7 +1503,7 @@ word itself has a special casing."
               ((listp ada-case-exception-file)
                (car ada-case-exception-file))
               (t
-               (error (concat "No exception file specified. "
+               (error (concat "No exception file specified.  "
                               "See variable ada-case-exception-file"))))))
 
     ;;  Find the substring to define as an exception. Order is: the parameter,
@@ -1529,30 +1534,30 @@ word itself has a special casing."
     ;;  If the word is already in the list, even with a different casing
     ;;  we simply want to replace it.
     (if (and (not (equal ada-case-exception-substring '()))
-             (assoc-string word ada-case-exception-substring t))
-        (setcar (assoc-string word ada-case-exception-substring t) word)
+            (assoc-string word ada-case-exception-substring t))
+       (setcar (assoc-string word ada-case-exception-substring t) word)
       (add-to-list 'ada-case-exception-substring (cons word t))
       )
 
     (ada-save-exceptions-to-file file-name)
 
-    (message (concat "Defining " word " as a casing exception"))))
+    (message "%s" (concat "Defining " word " as a casing exception"))))
 
 (defun ada-case-read-exceptions-from-file (file-name)
   "Read the content of the casing exception file FILE-NAME."
   (if (file-readable-p (expand-file-name file-name))
       (let ((buffer (current-buffer)))
-        (find-file (expand-file-name file-name))
-        (set-syntax-table ada-mode-symbol-syntax-table)
-        (widen)
-        (goto-char (point-min))
-        (while (not (eobp))
-
-          ;; If the item is already in the list, even with an other casing,
-          ;; do not add it again. This way, the user can easily decide which
-          ;; priority should be applied to each casing exception
-          (let ((word (buffer-substring-no-properties
-                       (point) (save-excursion (forward-word 1) (point)))))
+       (find-file (expand-file-name file-name))
+       (set-syntax-table ada-mode-symbol-syntax-table)
+       (widen)
+       (goto-char (point-min))
+       (while (not (eobp))
+
+         ;; If the item is already in the list, even with an other casing,
+         ;; do not add it again. This way, the user can easily decide which
+         ;; priority should be applied to each casing exception
+         (let ((word (buffer-substring-no-properties
+                      (point) (save-excursion (forward-word 1) (point)))))
 
            ;;  Handling a substring ?
            (if (char-equal (string-to-char word) ?*)
@@ -1563,9 +1568,9 @@ word itself has a special casing."
              (unless (assoc-string word ada-case-exception t)
                (add-to-list 'ada-case-exception (cons word t)))))
 
-          (forward-line 1))
-        (kill-buffer nil)
-        (set-buffer buffer)))
+         (forward-line 1))
+       (kill-buffer nil)
+       (set-buffer buffer)))
   )
 
 (defun ada-case-read-exceptions ()
@@ -1577,11 +1582,11 @@ word itself has a special casing."
        ada-case-exception-substring '())
 
   (cond ((stringp ada-case-exception-file)
-         (ada-case-read-exceptions-from-file ada-case-exception-file))
+        (ada-case-read-exceptions-from-file ada-case-exception-file))
 
-        ((listp ada-case-exception-file)
-         (mapcar 'ada-case-read-exceptions-from-file
-                 ada-case-exception-file))))
+       ((listp ada-case-exception-file)
+        (mapcar 'ada-case-read-exceptions-from-file
+                ada-case-exception-file))))
 
 (defun ada-adjust-case-substring ()
   "Adjust case of substrings in the previous word."
@@ -1613,30 +1618,30 @@ word itself has a special casing."
 
 (defun ada-adjust-case-identifier ()
   "Adjust case of the previous identifier.
-The auto-casing is done according to the value of `ada-case-identifier' and
-the exceptions defined in `ada-case-exception-file'."
+The auto-casing is done according to the value of `ada-case-identifier'
+and the exceptions defined in `ada-case-exception-file'."
   (interactive)
   (if (or (equal ada-case-exception '())
-          (equal (char-after) ?_))
+         (equal (char-after) ?_))
       (progn
        (funcall ada-case-identifier -1)
        (ada-adjust-case-substring))
 
     (progn
       (let ((end   (point))
-            (start (save-excursion (skip-syntax-backward "w")
-                                   (point)))
-            match)
-        ;;  If we have an exception, replace the word by the correct casing
-        (if (setq match (assoc-string (buffer-substring start end)
+           (start (save-excursion (skip-syntax-backward "w")
+                                  (point)))
+           match)
+       ;;  If we have an exception, replace the word by the correct casing
+       (if (setq match (assoc-string (buffer-substring start end)
                                      ada-case-exception t))
 
-            (progn
-              (delete-region start end)
-              (insert (car match)))
+           (progn
+             (delete-region start end)
+             (insert (car match)))
 
-          ;;  Else simply re-case the word
-          (funcall ada-case-identifier -1)
+         ;;  Else simply re-case the word
+         (funcall ada-case-identifier -1)
          (ada-adjust-case-substring))))))
 
 (defun ada-after-keyword-p ()
@@ -1644,9 +1649,9 @@ the exceptions defined in `ada-case-exception-file'."
   (save-excursion
     (forward-word -1)
     (and (not (and (char-before)
-                   (or (= (char-before) ?_)
-                       (= (char-before) ?'))));; unless we have a _ or '
-         (looking-at (concat ada-keywords "[^_]")))))
+                  (or (= (char-before) ?_)
+                      (= (char-before) ?'))));; unless we have a _ or '
+        (looking-at (concat ada-keywords "[^_]")))))
 
 (defun ada-adjust-case (&optional force-identifier)
   "Adjust the case of the word before the character just typed.
@@ -1685,7 +1690,7 @@ ARG is the prefix the user entered with \\[universal-argument]."
 
   (if ada-auto-case
       (let ((lastk last-command-char)
-            (previous-syntax-table (syntax-table)))
+           (previous-syntax-table (syntax-table)))
 
        (unwind-protect
            (progn
@@ -1705,7 +1710,7 @@ ARG is the prefix the user entered with \\[universal-argument]."
                       (funcall ada-ret-binding))))
                    ((eq lastk ?\C-i) (ada-tab))
                    ;; Else just insert the character
-              ((self-insert-command (prefix-numeric-value arg))))
+             ((self-insert-command (prefix-numeric-value arg))))
              ;; if there is a keyword in front of the underscore
              ;; then it should be part of an identifier (MH)
              (if (eq lastk ?_)
@@ -1714,7 +1719,7 @@ ARG is the prefix the user entered with \\[universal-argument]."
              )
          ;; Restore the syntax table
          (set-syntax-table previous-syntax-table))
-        )
+       )
 
     ;; Else, no auto-casing
     (cond
@@ -1738,11 +1743,11 @@ ARG is the prefix the user entered with \\[universal-argument]."
 
   ;; Call case modifying function after certain keys.
   (mapcar (function (lambda(key) (define-key
-                                   ada-mode-map
-                                   (char-to-string key)
-                                   'ada-adjust-case-interactive)))
-          '( ?` ?_ ?# ?% ?& ?* ?( ?) ?- ?= ?+
-                ?| ?\; ?: ?' ?\" ?< ?, ?. ?> ?/ ?\n 32 ?\r )))
+                                  ada-mode-map
+                                  (char-to-string key)
+                                  'ada-adjust-case-interactive)))
+         '( ?` ?_ ?# ?% ?& ?* ?( ?) ?- ?= ?+
+               ?| ?\; ?: ?' ?\" ?< ?, ?. ?> ?/ ?\n 32 ?\r )))
 
 (defun ada-loose-case-word (&optional arg)
   "Upcase first letter and letters following `_' in the following word.
@@ -1751,19 +1756,19 @@ ARG is ignored, and is there for compatibility with `capitalize-word' only."
   (interactive)
   (save-excursion
     (let ((end   (save-excursion (skip-syntax-forward  "w") (point)))
-          (first t))
+         (first t))
       (skip-syntax-backward "w")
       (while (and (or first (search-forward "_" end t))
-                  (< (point) end))
-        (and first
-             (setq first nil))
-        (insert-char (upcase (following-char)) 1)
-        (delete-char 1)))))
+                 (< (point) end))
+       (and first
+            (setq first nil))
+       (insert-char (upcase (following-char)) 1)
+       (delete-char 1)))))
 
 (defun ada-no-auto-case (&optional arg)
-  "Do nothing.
-This function can be used for the auto-casing variables in the ada-mode, to
-adapt to unusal auto-casing schemes. Since it does nothing, you can for
+  "Do nothing.  ARG is ignored.
+This function can be used for the auto-casing variables in Ada mode, to
+adapt to unusal auto-casing schemes.  Since it does nothing, you can for
 instance use it for `ada-case-identifier' if you don't want any special
 auto-casing for identifiers, whereas keywords have to be lower-cased.
 See also `ada-auto-case' to disable auto casing altogether."
@@ -1774,7 +1779,7 @@ See also `ada-auto-case' to disable auto casing altogether."
 ARG is ignored, and is there for compatibility with `capitalize-word' only."
   (interactive)
   (let ((end   (save-excursion (skip-syntax-forward  "w") (point)))
-        (begin (save-excursion (skip-syntax-backward "w") (point))))
+       (begin (save-excursion (skip-syntax-backward "w") (point))))
     (modify-syntax-entry ?_ "_")
     (capitalize-region begin end)
     (modify-syntax-entry ?_ "w")))
@@ -1784,49 +1789,49 @@ ARG is ignored, and is there for compatibility with `capitalize-word' only."
 Attention: This function might take very long for big regions!"
   (interactive "*r")
   (let ((begin nil)
-        (end nil)
-        (keywordp nil)
-        (attribp nil)
-        (previous-syntax-table (syntax-table)))
+       (end nil)
+       (keywordp nil)
+       (attribp nil)
+       (previous-syntax-table (syntax-table)))
     (message "Adjusting case ...")
     (unwind-protect
-        (save-excursion
-          (set-syntax-table ada-mode-symbol-syntax-table)
-          (goto-char to)
-          ;;
-          ;; loop: look for all identifiers, keywords, and attributes
-          ;;
-          (while (re-search-backward "\\<\\(\\sw+\\)\\>" from t)
-            (setq end (match-end 1))
-            (setq attribp
-                 (and (> (point) from)
-                      (save-excursion
-                        (forward-char -1)
-                        (setq attribp (looking-at "'.[^']")))))
-            (or
-             ;; do nothing if it is a string or comment
-             (ada-in-string-or-comment-p)
-             (progn
-               ;;
-               ;; get the identifier or keyword or attribute
-               ;;
-               (setq begin (point))
-               (setq keywordp (looking-at ada-keywords))
-               (goto-char end)
-               ;;
-               ;; casing according to user-option
-               ;;
-               (if attribp
-                   (funcall ada-case-attribute -1)
-                 (if keywordp
-                     (funcall ada-case-keyword -1)
-                   (ada-adjust-case-identifier)))
-               (goto-char begin))))
-          (message "Adjusting case ... Done"))
+       (save-excursion
+         (set-syntax-table ada-mode-symbol-syntax-table)
+         (goto-char to)
+         ;;
+         ;; loop: look for all identifiers, keywords, and attributes
+         ;;
+         (while (re-search-backward "\\<\\(\\sw+\\)\\>" from t)
+           (setq end (match-end 1))
+           (setq attribp
+                (and (> (point) from)
+                     (save-excursion
+                       (forward-char -1)
+                       (setq attribp (looking-at "'.[^']")))))
+           (or
+            ;; do nothing if it is a string or comment
+            (ada-in-string-or-comment-p)
+            (progn
+              ;;
+              ;; get the identifier or keyword or attribute
+              ;;
+              (setq begin (point))
+              (setq keywordp (looking-at ada-keywords))
+              (goto-char end)
+              ;;
+              ;; casing according to user-option
+              ;;
+              (if attribp
+                  (funcall ada-case-attribute -1)
+                (if keywordp
+                    (funcall ada-case-keyword -1)
+                  (ada-adjust-case-identifier)))
+              (goto-char begin))))
+         (message "Adjusting case ... Done"))
       (set-syntax-table previous-syntax-table))))
 
 (defun ada-adjust-case-buffer ()
-  "Adjusts the case of all words in the whole buffer.
+  "Adjust the case of all words in the whole buffer.
 ATTENTION: This function might take very long for big buffers!"
   (interactive "*")
   (ada-adjust-case-region (point-min) (point-max)))
@@ -1852,44 +1857,44 @@ ATTENTION: This function might take very long for big buffers!"
   "Reformat the parameter list point is in."
   (interactive)
   (let ((begin nil)
-        (end nil)
-        (delend nil)
-        (paramlist nil)
-        (previous-syntax-table (syntax-table)))
+       (end nil)
+       (delend nil)
+       (paramlist nil)
+       (previous-syntax-table (syntax-table)))
     (unwind-protect
-        (progn
-          (set-syntax-table ada-mode-symbol-syntax-table)
-
-          ;; check if really inside parameter list
-          (or (ada-in-paramlist-p)
-              (error "Not in parameter list"))
+       (progn
+         (set-syntax-table ada-mode-symbol-syntax-table)
 
-          ;; find start of current parameter-list
-          (ada-search-ignore-string-comment
-           (concat ada-subprog-start-re "\\|\\<body\\>" ) t nil)
-          (down-list 1)
-          (backward-char 1)
-          (setq begin (point))
+         ;; check if really inside parameter list
+         (or (ada-in-paramlist-p)
+             (error "Not in parameter list"))
 
-          ;; find end of parameter-list
-          (forward-sexp 1)
-          (setq delend (point))
-          (delete-char -1)
-          (insert "\n")
+         ;; find start of current parameter-list
+         (ada-search-ignore-string-comment
+          (concat ada-subprog-start-re "\\|\\<body\\>" ) t nil)
+         (down-list 1)
+         (backward-char 1)
+         (setq begin (point))
+
+         ;; find end of parameter-list
+         (forward-sexp 1)
+         (setq delend (point))
+         (delete-char -1)
+         (insert "\n")
 
-          ;; find end of last parameter-declaration
-          (forward-comment -1000)
-          (setq end (point))
+         ;; find end of last parameter-declaration
+         (forward-comment -1000)
+         (setq end (point))
 
-          ;; build a list of all elements of the parameter-list
-          (setq paramlist (ada-scan-paramlist (1+ begin) end))
+         ;; build a list of all elements of the parameter-list
+         (setq paramlist (ada-scan-paramlist (1+ begin) end))
 
-          ;; delete the original parameter-list
-          (delete-region begin  delend)
+         ;; delete the original parameter-list
+         (delete-region begin  delend)
 
-          ;; insert the new parameter-list
-          (goto-char begin)
-          (ada-insert-paramlist paramlist))
+         ;; insert the new parameter-list
+         (goto-char begin)
+         (ada-insert-paramlist paramlist))
 
       ;; restore syntax-table
       (set-syntax-table previous-syntax-table)
@@ -1899,12 +1904,12 @@ ATTENTION: This function might take very long for big buffers!"
   "Scan the parameter list found in between BEGIN and END.
 Return the equivalent internal parameter list."
   (let ((paramlist (list))
-        (param (list))
-        (notend t)
-        (apos nil)
-        (epos nil)
-        (semipos nil)
-        (match-cons nil))
+       (param (list))
+       (notend t)
+       (apos nil)
+       (epos nil)
+       (semipos nil)
+       (match-cons nil))
 
     (goto-char begin)
 
@@ -1917,11 +1922,11 @@ Return the equivalent internal parameter list."
 
       ;; find last character of parameter-declaration
       (if (setq match-cons
-               (ada-search-ignore-string-comment "[ \t\n]*;" nil end t))
-          (progn
-            (setq epos (car match-cons))
-            (setq semipos (cdr match-cons)))
-        (setq epos end))
+              (ada-search-ignore-string-comment "[ \t\n]*;" nil end t))
+         (progn
+           (setq epos (car match-cons))
+           (setq semipos (cdr match-cons)))
+       (setq epos end))
 
       ;; read name(s) of parameter(s)
       (goto-char apos)
@@ -1933,76 +1938,76 @@ Return the equivalent internal parameter list."
       ;; look for 'in'
       (setq apos (point))
       (setq param
-           (append param
-                   (list
-                    (consp
-                     (ada-search-ignore-string-comment
-                      "in" nil epos t 'word-search-forward)))))
+          (append param
+                  (list
+                   (consp
+                    (ada-search-ignore-string-comment
+                     "in" nil epos t 'word-search-forward)))))
 
       ;; look for 'out'
       (goto-char apos)
       (setq param
-           (append param
-                   (list
-                    (consp
-                     (ada-search-ignore-string-comment
-                      "out" nil epos t 'word-search-forward)))))
+          (append param
+                  (list
+                   (consp
+                    (ada-search-ignore-string-comment
+                     "out" nil epos t 'word-search-forward)))))
 
       ;; look for 'access'
       (goto-char apos)
       (setq param
-           (append param
-                   (list
-                    (consp
-                     (ada-search-ignore-string-comment
-                      "access" nil epos t 'word-search-forward)))))
+          (append param
+                  (list
+                   (consp
+                    (ada-search-ignore-string-comment
+                     "access" nil epos t 'word-search-forward)))))
 
       ;; skip 'in'/'out'/'access'
       (goto-char apos)
       (ada-goto-next-non-ws)
       (while (looking-at "\\<\\(in\\|out\\|access\\)\\>")
-        (forward-word 1)
-        (ada-goto-next-non-ws))
+       (forward-word 1)
+       (ada-goto-next-non-ws))
 
       ;; read type of parameter
       ;; We accept spaces in the name, since some software like Rose
       ;; generates something like: "A : B 'Class"
       (looking-at "\\<\\(\\sw\\|[_.' \t]\\)+\\>")
       (setq param
-           (append param
-                   (list (match-string 0))))
+          (append param
+                  (list (match-string 0))))
 
       ;; read default-expression, if there is one
       (goto-char (setq apos (match-end 0)))
       (setq param
-           (append param
-                   (list
-                    (if (setq match-cons
-                             (ada-search-ignore-string-comment
-                              ":=" nil epos t 'search-forward))
-                        (buffer-substring (car match-cons) epos)
-                      nil))))
+          (append param
+                  (list
+                   (if (setq match-cons
+                            (ada-search-ignore-string-comment
+                             ":=" nil epos t 'search-forward))
+                       (buffer-substring (car match-cons) epos)
+                     nil))))
 
       ;; add this parameter-declaration to the list
       (setq paramlist (append paramlist (list param)))
 
       ;; check if it was the last parameter
       (if (eq epos end)
-          (setq notend nil)
-        (goto-char semipos))
+         (setq notend nil)
+       (goto-char semipos))
       )
     (reverse paramlist)))
 
 (defun ada-insert-paramlist (paramlist)
   "Insert a formatted PARAMLIST in the buffer."
   (let ((i (length paramlist))
-        (parlen 0)
-        (typlen 0)
-        (inp nil)
-        (outp nil)
-        (accessp nil)
-        (column nil)
-        (firstcol nil))
+       (parlen 0)
+       (typlen 0)
+       (inp nil)
+       (outp nil)
+       (accessp nil)
+       (column nil)
+       (firstcol nil))
 
     ;; loop until last parameter
     (while (not (zerop i))
@@ -2026,23 +2031,23 @@ Return the equivalent internal parameter list."
 
     ;; does paramlist already start on a separate line ?
     (if (save-excursion
-          (re-search-backward "^.\\|[^ \t]" nil t)
-          (looking-at "^."))
-        ;; yes => re-indent it
-        (progn
-          (ada-indent-current)
-          (save-excursion
-            (if (looking-at "\\(is\\|return\\)")
-                (replace-match " \\1"))))
+         (re-search-backward "^.\\|[^ \t]" nil t)
+         (looking-at "^."))
+       ;; yes => re-indent it
+       (progn
+         (ada-indent-current)
+         (save-excursion
+           (if (looking-at "\\(is\\|return\\)")
+               (replace-match " \\1"))))
 
       ;; no => insert it where we are after removing any whitespace
       (fixup-whitespace)
       (save-excursion
-        (cond
-         ((looking-at "[ \t]*\\(\n\\|;\\)")
-          (replace-match "\\1"))
-         ((looking-at "[ \t]*\\(is\\|return\\)")
-          (replace-match " \\1"))))
+       (cond
+        ((looking-at "[ \t]*\\(\n\\|;\\)")
+         (replace-match "\\1"))
+        ((looking-at "[ \t]*\\(is\\|return\\)")
+         (replace-match " \\1"))))
       (insert " "))
 
     (insert "(")
@@ -2064,42 +2069,42 @@ Return the equivalent internal parameter list."
 
       ;; insert 'in' or space
       (if (nth 1 (nth i paramlist))
-          (insert "in ")
-        (if (and
-             (or inp
-                 accessp)
-             (not (nth 3 (nth i paramlist))))
-            (insert "   ")))
+         (insert "in ")
+       (if (and
+            (or inp
+                accessp)
+            (not (nth 3 (nth i paramlist))))
+           (insert "   ")))
 
       ;; insert 'out' or space
       (if (nth 2 (nth i paramlist))
-          (insert "out ")
-        (if (and
-             (or outp
-                 accessp)
-             (not (nth 3 (nth i paramlist))))
-            (insert "    ")))
+         (insert "out ")
+       (if (and
+            (or outp
+                accessp)
+            (not (nth 3 (nth i paramlist))))
+           (insert "    ")))
 
       ;; insert 'access'
       (if (nth 3 (nth i paramlist))
-          (insert "access "))
+         (insert "access "))
 
       (setq column (current-column))
 
       ;; insert type-name and, if necessary, space and default-expression
       (insert (nth 4 (nth i paramlist)))
       (if (nth 5 (nth i paramlist))
-          (progn
-            (indent-to (+ column typlen 1))
-            (insert (nth 5 (nth i paramlist)))))
+         (progn
+           (indent-to (+ column typlen 1))
+           (insert (nth 5 (nth i paramlist)))))
 
       ;; check if it was the last parameter
       (if (zerop i)
-          (insert ")")
-        ;; no => insert ';' and newline and indent
-        (insert ";")
-        (newline)
-        (indent-to firstcol))
+         (insert ")")
+       ;; no => insert ';' and newline and indent
+       (insert ";")
+       (newline)
+       (indent-to firstcol))
       )
 
     ;; if anything follows, except semicolon, newline, is or return
@@ -2118,7 +2123,7 @@ Return the equivalent internal parameter list."
 ;;       that are evaluated)
 ;;  Thus the total indentation for a line is the column number of the reference
 ;;  position plus whatever value the evaluation of the second element provides.
-;;  This mechanism is used so that the ada-mode can "explain" how the
+;;  This mechanism is used so that the Ada mode can "explain" how the
 ;;  indentation was calculated, by showing which variables were used.
 ;;
 ;;  The indentation itself is done in only one pass: first we try to guess in
@@ -2143,22 +2148,22 @@ Return the equivalent internal parameter list."
   (interactive "*r")
   (goto-char beg)
   (let ((block-done 0)
-        (lines-remaining (count-lines beg end))
-        (msg (format "%%4d out of %4d lines remaining ..."
-                     (count-lines beg end)))
-        (endmark (copy-marker end)))
+       (lines-remaining (count-lines beg end))
+       (msg (format "%%4d out of %4d lines remaining ..."
+                    (count-lines beg end)))
+       (endmark (copy-marker end)))
     ;; catch errors while indenting
     (while (< (point) endmark)
       (if (> block-done 39)
-          (progn
+         (progn
            (setq lines-remaining (- lines-remaining block-done)
                  block-done     0)
            (message msg lines-remaining)))
       (if (= (char-after) ?\n) nil
-        (ada-indent-current))
+       (ada-indent-current))
       (forward-line 1)
       (setq block-done      (1+ block-done)))
-    (message "indenting ... done")))
+    (message "Indenting ... done")))
 
 (defun ada-indent-newline-indent ()
   "Indent the current line, insert a newline and then indent the new line."
@@ -2169,8 +2174,7 @@ Return the equivalent internal parameter list."
 
 (defun ada-indent-newline-indent-conditional ()
   "Insert a newline and indent it.
-The original line is indented first if `ada-indent-after-return' is non-nil.
-This function is intended to be bound to the C-m and C-j keys."
+The original line is indented first if `ada-indent-after-return' is non-nil."
   (interactive "*")
   (if ada-indent-after-return (ada-indent-current))
   (newline)
@@ -2188,17 +2192,17 @@ This function is intended to be bound to the C-m and C-j keys."
 
       (if (equal (cdr cur-indent) '(0))
          (message (concat "same indentation as line " (number-to-string line)))
-       (message (mapconcat (lambda(x)
-                             (cond
-                              ((symbolp x)
-                               (symbol-name x))
-                              ((numberp x)
-                               (number-to-string x))
-                              ((listp x)
-                               (concat "- " (symbol-name (cadr x))))
-                              ))
-                           (cdr cur-indent)
-                           " + "))))
+       (message "%s" (mapconcat (lambda(x)
+                                  (cond
+                                   ((symbolp x)
+                                    (symbol-name x))
+                                   ((numberp x)
+                                    (number-to-string x))
+                                   ((listp x)
+                                    (concat "- " (symbol-name (cadr x))))
+                                   ))
+                                (cdr cur-indent)
+                                " + "))))
     (save-excursion
       (goto-char (car cur-indent))
       (sit-for 1))))
@@ -2211,7 +2215,7 @@ command like:
 
   (while command-line-args-left
     (let ((source (car command-line-args-left)))
-      (message (concat "formating " source))
+      (message "Formating %s" source)
       (find-file source)
       (ada-indent-region (point-min) (point-max))
       (ada-adjust-case-buffer)
@@ -2231,65 +2235,65 @@ Return the calculation that was done, including the reference point and the
 offset."
   (interactive)
   (let ((previous-syntax-table (syntax-table))
-        (orgpoint (point-marker))
-        cur-indent tmp-indent
-        prev-indent)
+       (orgpoint (point-marker))
+       cur-indent tmp-indent
+       prev-indent)
 
     (unwind-protect
-        (progn
-          (set-syntax-table ada-mode-symbol-syntax-table)
+       (progn
+         (set-syntax-table ada-mode-symbol-syntax-table)
 
-          ;;  This need to be done here so that the advice is not always
-          ;;  activated (this might interact badly with other modes)
-          (if (featurep 'xemacs)
-              (ad-activate 'parse-partial-sexp t))
+         ;;  This need to be done here so that the advice is not always
+         ;;  activated (this might interact badly with other modes)
+         (if (featurep 'xemacs)
+             (ad-activate 'parse-partial-sexp t))
 
-          (save-excursion
-            (setq cur-indent
+         (save-excursion
+           (setq cur-indent
 
-                 ;; Not First line in the buffer ?
-                 (if (save-excursion (zerop (forward-line -1)))
-                     (progn
-                       (back-to-indentation)
-                       (ada-get-current-indent))
+                ;; Not First line in the buffer ?
+                (if (save-excursion (zerop (forward-line -1)))
+                    (progn
+                      (back-to-indentation)
+                      (ada-get-current-indent))
 
-                   ;; first line in the buffer
-                   (list (point-min) 0))))
+                  ;; first line in the buffer
+                  (list (point-min) 0))))
 
-          ;; Evaluate the list to get the column to indent to
-          ;; prev-indent contains the column to indent to
+         ;; Evaluate the list to get the column to indent to
+         ;; prev-indent contains the column to indent to
          (if cur-indent
              (setq prev-indent (save-excursion (goto-char (car cur-indent))
                                                (current-column))
                    tmp-indent (cdr cur-indent))
            (setq prev-indent 0  tmp-indent '()))
 
-          (while (not (null tmp-indent))
-            (cond
-             ((numberp (car tmp-indent))
-              (setq prev-indent (+ prev-indent (car tmp-indent))))
-             (t
-              (setq prev-indent (+ prev-indent (eval (car tmp-indent)))))
-             )
-            (setq tmp-indent (cdr tmp-indent)))
-
-          ;; only re-indent if indentation is different then the current
-          (if (= (save-excursion (back-to-indentation) (current-column)) prev-indent)
-              nil
-            (beginning-of-line)
-            (delete-horizontal-space)
-            (indent-to prev-indent))
-          ;;
-          ;; restore position of point
-          ;;
-          (goto-char orgpoint)
-          (if (< (current-column) (current-indentation))
-              (back-to-indentation)))
+         (while (not (null tmp-indent))
+           (cond
+            ((numberp (car tmp-indent))
+             (setq prev-indent (+ prev-indent (car tmp-indent))))
+            (t
+             (setq prev-indent (+ prev-indent (eval (car tmp-indent)))))
+            )
+           (setq tmp-indent (cdr tmp-indent)))
+
+         ;; only re-indent if indentation is different then the current
+         (if (= (save-excursion (back-to-indentation) (current-column)) prev-indent)
+             nil
+           (beginning-of-line)
+           (delete-horizontal-space)
+           (indent-to prev-indent))
+         ;;
+         ;; restore position of point
+         ;;
+         (goto-char orgpoint)
+         (if (< (current-column) (current-indentation))
+             (back-to-indentation)))
 
       ;; restore syntax-table
       (set-syntax-table previous-syntax-table)
       (if (featurep 'xemacs)
-          (ad-deactivate 'parse-partial-sexp))
+         (ad-deactivate 'parse-partial-sexp))
       )
 
     cur-indent
@@ -2298,14 +2302,14 @@ offset."
 (defun ada-get-current-indent ()
   "Return the indentation to use for the current line."
   (let (column
-        pos
-        match-cons
+       pos
+       match-cons
        result
-        (orgpoint (save-excursion
-                    (beginning-of-line)
-                    (forward-comment -10000)
-                    (forward-line 1)
-                    (point))))
+       (orgpoint (save-excursion
+                   (beginning-of-line)
+                   (forward-comment -10000)
+                   (forward-line 1)
+                   (point))))
 
     (setq result
     (cond
@@ -2430,8 +2434,8 @@ offset."
        ;; else
 
        ((looking-at "else\\>")
-       (if (save-excursion  (ada-goto-previous-word)
-                            (looking-at "\\<or\\>"))
+       (if (save-excursion (ada-goto-previous-word)
+                           (looking-at "\\<or\\>"))
            (ada-indent-on-previous-lines nil orgpoint orgpoint)
          (save-excursion
            (ada-goto-matching-start 1 nil t)
@@ -2481,16 +2485,16 @@ offset."
           (looking-at "loop\\>"))
       (setq pos (point))
       (save-excursion
-        (goto-char (match-end 0))
-        (ada-goto-stmt-start)
-        (if (looking-at "\\<\\(loop\\|if\\)\\>")
-            (ada-indent-on-previous-lines nil orgpoint orgpoint)
-          (unless (looking-at ada-loop-start-re)
-            (ada-search-ignore-string-comment ada-loop-start-re
-                                              nil pos))
-          (if (looking-at "\\<loop\\>")
-              (ada-indent-on-previous-lines nil orgpoint orgpoint)
-            (list (progn (back-to-indentation) (point)) 'ada-stmt-end-indent)))))
+       (goto-char (match-end 0))
+       (ada-goto-stmt-start)
+       (if (looking-at "\\<\\(loop\\|if\\)\\>")
+           (ada-indent-on-previous-lines nil orgpoint orgpoint)
+         (unless (looking-at ada-loop-start-re)
+           (ada-search-ignore-string-comment ada-loop-start-re
+                                             nil pos))
+         (if (looking-at "\\<loop\\>")
+             (ada-indent-on-previous-lines nil orgpoint orgpoint)
+           (list (progn (back-to-indentation) (point)) 'ada-stmt-end-indent)))))
 
      ;;----------------------------
      ;;    starting with l (limited) or r (record)
@@ -2517,9 +2521,9 @@ offset."
      ((and (= (downcase (char-after)) ?b)
           (looking-at "begin\\>"))
       (save-excursion
-        (if (ada-goto-matching-decl-start t)
-            (list (progn (back-to-indentation) (point)) 0)
-          (ada-indent-on-previous-lines nil orgpoint orgpoint))))
+       (if (ada-goto-matching-decl-start t)
+           (list (progn (back-to-indentation) (point)) 0)
+         (ada-indent-on-previous-lines nil orgpoint orgpoint))))
 
      ;;---------------------------
      ;;   starting with i (is)
@@ -2529,16 +2533,16 @@ offset."
           (looking-at "is\\>"))
 
       (if (and ada-indent-is-separate
-               (save-excursion
-                 (goto-char (match-end 0))
-                 (ada-goto-next-non-ws (save-excursion (end-of-line)
-                                                       (point)))
-                 (looking-at "\\<abstract\\>\\|\\<separate\\>")))
-          (save-excursion
-            (ada-goto-stmt-start)
-            (list (progn (back-to-indentation) (point)) 'ada-indent))
-        (save-excursion
-          (ada-goto-stmt-start)
+              (save-excursion
+                (goto-char (match-end 0))
+                (ada-goto-next-non-ws (save-excursion (end-of-line)
+                                                      (point)))
+                (looking-at "\\<abstract\\>\\|\\<separate\\>")))
+         (save-excursion
+           (ada-goto-stmt-start)
+           (list (progn (back-to-indentation) (point)) 'ada-indent))
+       (save-excursion
+         (ada-goto-stmt-start)
          (if (looking-at "\\<package\\|procedure\\|function\\>")
              (list (progn (back-to-indentation) (point)) 0)
            (list (progn (back-to-indentation) (point)) 'ada-indent)))))
@@ -2619,8 +2623,8 @@ offset."
      ((and (= (downcase (char-after)) ?d)
           (looking-at "do\\>"))
       (save-excursion
-        (ada-goto-stmt-start)
-        (list (progn (back-to-indentation) (point)) 'ada-stmt-end-indent)))
+       (ada-goto-stmt-start)
+       (list (progn (back-to-indentation) (point)) 'ada-stmt-end-indent)))
 
      ;;--------------------------------
      ;;   starting with '-'  (comment)
@@ -2652,7 +2656,7 @@ offset."
            (ada-indent-on-previous-lines nil orgpoint orgpoint)))
 
        ;; Else same indentation as the previous line
-        (list (save-excursion (back-to-indentation) (point)) 0)))
+       (list (save-excursion (back-to-indentation) (point)) 0)))
 
      ;;--------------------------------
      ;;   starting with '#'  (preprocessor line)
@@ -2660,7 +2664,7 @@ offset."
 
      ((and (= (char-after) ?#)
           (equal ada-which-compiler 'gnat)
-           (looking-at "#[ \t]*\\(if\\|els\\(e\\|if\\)\\|end[ \t]*if\\)"))
+          (looking-at "#[ \t]*\\(if\\|els\\(e\\|if\\)\\|end[ \t]*if\\)"))
       (list (save-excursion (beginning-of-line) (point)) 0))
 
      ;;--------------------------------
@@ -2669,9 +2673,9 @@ offset."
 
      ((and (not (eobp)) (= (char-after) ?\)))
       (save-excursion
-        (forward-char 1)
-        (backward-sexp 1)
-        (list (point) 0)))
+       (forward-char 1)
+       (backward-sexp 1)
+       (list (point) 0)))
 
      ;;---------------------------------
      ;; new/abstract/separate
@@ -2709,9 +2713,9 @@ offset."
 
      ((looking-at "\\(\\sw\\|_\\)+[ \t\n]*:[^=]")
       (if (ada-in-decl-p)
-          (ada-indent-on-previous-lines nil orgpoint orgpoint)
-        (append (ada-indent-on-previous-lines nil orgpoint orgpoint)
-                '(ada-label-indent))))
+         (ada-indent-on-previous-lines nil orgpoint orgpoint)
+       (append (ada-indent-on-previous-lines nil orgpoint orgpoint)
+               '(ada-label-indent))))
 
      ))
 
@@ -2731,60 +2735,60 @@ if INITIAL-POS is non-nil, moves point to INITIAL-POS before calculation."
 
     ;; Is inside a parameter-list ?
     (if (ada-in-paramlist-p)
-        (ada-get-indent-paramlist)
+       (ada-get-indent-paramlist)
 
       ;; move to beginning of current statement
       (unless nomove
-        (ada-goto-stmt-start))
+       (ada-goto-stmt-start))
 
       ;; no beginning found => don't change indentation
       (if (and (eq oldpoint (point))
-               (not nomove))
-          (ada-get-indent-nochange)
-
-        (cond
-         ;;
-         ((and
-           ada-indent-to-open-paren
-           (ada-in-open-paren-p))
-          (ada-get-indent-open-paren))
-         ;;
-         ((looking-at "end\\>")
-          (ada-get-indent-end orgpoint))
-         ;;
-         ((looking-at ada-loop-start-re)
-          (ada-get-indent-loop orgpoint))
-         ;;
-         ((looking-at ada-subprog-start-re)
-          (ada-get-indent-subprog orgpoint))
-         ;;
-         ((looking-at ada-block-start-re)
-          (ada-get-indent-block-start orgpoint))
-         ;;
-         ((looking-at "\\(sub\\)?type\\>")
-          (ada-get-indent-type orgpoint))
-         ;;
-         ;; "then" has to be included in the case of "select...then abort"
-         ;; statements, since (goto-stmt-start) at the beginning of
-         ;; the current function would leave the cursor on that position
-         ((looking-at "\\(\\(els\\)?if\\>\\)\\|then abort\\\>")
-          (ada-get-indent-if orgpoint))
-         ;;
-         ((looking-at "case\\>")
-          (ada-get-indent-case orgpoint))
-         ;;
-         ((looking-at "when\\>")
-          (ada-get-indent-when orgpoint))
-         ;;
-         ((looking-at "\\(\\sw\\|_\\)+[ \t\n]*:[^=]")
-          (ada-get-indent-label orgpoint))
-         ;;
-         ((looking-at "separate\\>")
-          (ada-get-indent-nochange))
+              (not nomove))
+         (ada-get-indent-nochange)
+
+       (cond
+        ;;
+        ((and
+          ada-indent-to-open-paren
+          (ada-in-open-paren-p))
+         (ada-get-indent-open-paren))
+        ;;
+        ((looking-at "end\\>")
+         (ada-get-indent-end orgpoint))
+        ;;
+        ((looking-at ada-loop-start-re)
+         (ada-get-indent-loop orgpoint))
+        ;;
+        ((looking-at ada-subprog-start-re)
+         (ada-get-indent-subprog orgpoint))
+        ;;
+        ((looking-at ada-block-start-re)
+         (ada-get-indent-block-start orgpoint))
+        ;;
+        ((looking-at "\\(sub\\)?type\\>")
+         (ada-get-indent-type orgpoint))
+        ;;
+        ;; "then" has to be included in the case of "select...then abort"
+        ;; statements, since (goto-stmt-start) at the beginning of
+        ;; the current function would leave the cursor on that position
+        ((looking-at "\\(\\(els\\)?if\\>\\)\\|then abort\\\>")
+         (ada-get-indent-if orgpoint))
+        ;;
+        ((looking-at "case\\>")
+         (ada-get-indent-case orgpoint))
+        ;;
+        ((looking-at "when\\>")
+         (ada-get-indent-when orgpoint))
+        ;;
+        ((looking-at "\\(\\sw\\|_\\)+[ \t\n]*:[^=]")
+         (ada-get-indent-label orgpoint))
+        ;;
+        ((looking-at "separate\\>")
+         (ada-get-indent-nochange))
 
         ;; A label
         ((looking-at "<<")
-          (list (+ (save-excursion (back-to-indentation) (point))
+         (list (+ (save-excursion (back-to-indentation) (point))
                   (- ada-label-indent))))
 
         ;;
@@ -2797,8 +2801,8 @@ if INITIAL-POS is non-nil, moves point to INITIAL-POS before calculation."
                              'ada-with-indent
                            'ada-use-indent))))
         ;;
-         (t
-          (ada-get-indent-noindent orgpoint)))))
+        (t
+         (ada-get-indent-noindent orgpoint)))))
     ))
 
 (defun ada-get-indent-open-paren ()
@@ -2844,146 +2848,146 @@ if INITIAL-POS is non-nil, moves point to INITIAL-POS before calculation."
   "Calculate the indentation when point is just before an end statement.
 ORGPOINT is the limit position used in the calculation."
   (let ((defun-name nil)
-        (indent nil))
+       (indent nil))
 
     ;; is the line already terminated by ';' ?
     (if (save-excursion
-          (ada-search-ignore-string-comment ";" nil orgpoint nil
-                                            'search-forward))
-
-        ;; yes, look what's following 'end'
-        (progn
-          (forward-word 1)
-          (ada-goto-next-non-ws)
-          (cond
-           ((looking-at "\\<\\(loop\\|select\\|if\\|case\\)\\>")
-            (save-excursion (ada-check-matching-start (match-string 0)))
-            (list (save-excursion (back-to-indentation) (point)) 0))
-
-           ;;
-           ;; loop/select/if/case/record/select
-           ;;
-           ((looking-at "\\<record\\>")
-            (save-excursion
-              (ada-check-matching-start (match-string 0))
-              ;;  we are now looking at the matching "record" statement
-              (forward-word 1)
-              (ada-goto-stmt-start)
-              ;;  now on the matching type declaration, or use clause
-              (unless (looking-at "\\(for\\|type\\)\\>")
-                (ada-search-ignore-string-comment "\\<type\\>" t))
-              (list (progn (back-to-indentation) (point)) 0)))
-           ;;
-           ;; a named block end
-           ;;
-           ((looking-at ada-ident-re)
-            (setq defun-name (match-string 0))
-            (save-excursion
-              (ada-goto-matching-start 0)
-              (ada-check-defun-name defun-name))
-            (list (progn (back-to-indentation) (point)) 0))
-           ;;
-           ;; a block-end without name
-           ;;
-           ((= (char-after) ?\;)
-            (save-excursion
-              (ada-goto-matching-start 0)
-              (if (looking-at "\\<begin\\>")
-                  (progn
-                    (setq indent (list (point) 0))
-                    (if (ada-goto-matching-decl-start t)
-                        (list (progn (back-to-indentation) (point)) 0)
-                      indent))
+         (ada-search-ignore-string-comment ";" nil orgpoint nil
+                                           'search-forward))
+
+       ;; yes, look what's following 'end'
+       (progn
+         (forward-word 1)
+         (ada-goto-next-non-ws)
+         (cond
+          ((looking-at "\\<\\(loop\\|select\\|if\\|case\\)\\>")
+           (save-excursion (ada-check-matching-start (match-string 0)))
+           (list (save-excursion (back-to-indentation) (point)) 0))
+
+          ;;
+          ;; loop/select/if/case/record/select
+          ;;
+          ((looking-at "\\<record\\>")
+           (save-excursion
+             (ada-check-matching-start (match-string 0))
+             ;;  we are now looking at the matching "record" statement
+             (forward-word 1)
+             (ada-goto-stmt-start)
+             ;;  now on the matching type declaration, or use clause
+             (unless (looking-at "\\(for\\|type\\)\\>")
+               (ada-search-ignore-string-comment "\\<type\\>" t))
+             (list (progn (back-to-indentation) (point)) 0)))
+          ;;
+          ;; a named block end
+          ;;
+          ((looking-at ada-ident-re)
+           (setq defun-name (match-string 0))
+           (save-excursion
+             (ada-goto-matching-start 0)
+             (ada-check-defun-name defun-name))
+           (list (progn (back-to-indentation) (point)) 0))
+          ;;
+          ;; a block-end without name
+          ;;
+          ((= (char-after) ?\;)
+           (save-excursion
+             (ada-goto-matching-start 0)
+             (if (looking-at "\\<begin\\>")
+                 (progn
+                   (setq indent (list (point) 0))
+                   (if (ada-goto-matching-decl-start t)
+                       (list (progn (back-to-indentation) (point)) 0)
+                     indent))
                (list (progn (back-to-indentation) (point)) 0)
                )))
-           ;;
-           ;; anything else - should maybe signal an error ?
-           ;;
-           (t
-            (list (save-excursion (back-to-indentation) (point))
-                  'ada-broken-indent))))
+          ;;
+          ;; anything else - should maybe signal an error ?
+          ;;
+          (t
+           (list (save-excursion (back-to-indentation) (point))
+                 'ada-broken-indent))))
 
       (list (save-excursion (back-to-indentation) (point))
-            'ada-broken-indent))))
+           'ada-broken-indent))))
 
 (defun ada-get-indent-case (orgpoint)
   "Calculate the indentation when point is just before a case statement.
 ORGPOINT is the limit position used in the calculation."
   (let ((match-cons nil)
-        (opos (point)))
+       (opos (point)))
     (cond
      ;;
      ;; case..is..when..=>
      ;;
      ((save-excursion
-        (setq match-cons (and
-                          ;; the `=>' must be after the keyword `is'.
-                          (ada-search-ignore-string-comment
-                           "is" nil orgpoint nil 'word-search-forward)
-                          (ada-search-ignore-string-comment
-                           "[ \t\n]+=>" nil orgpoint))))
+       (setq match-cons (and
+                         ;; the `=>' must be after the keyword `is'.
+                         (ada-search-ignore-string-comment
+                          "is" nil orgpoint nil 'word-search-forward)
+                         (ada-search-ignore-string-comment
+                          "[ \t\n]+=>" nil orgpoint))))
       (save-excursion
-        (goto-char (car match-cons))
-        (unless (ada-search-ignore-string-comment "when" t opos)
-          (error "Missing 'when' between 'case' and '=>'"))
-        (list (save-excursion (back-to-indentation) (point)) 'ada-indent)))
+       (goto-char (car match-cons))
+       (unless (ada-search-ignore-string-comment "when" t opos)
+         (error "Missing 'when' between 'case' and '=>'"))
+       (list (save-excursion (back-to-indentation) (point)) 'ada-indent)))
      ;;
      ;; case..is..when
      ;;
      ((save-excursion
-        (setq match-cons (ada-search-ignore-string-comment
-                          "when" nil orgpoint nil 'word-search-forward)))
+       (setq match-cons (ada-search-ignore-string-comment
+                         "when" nil orgpoint nil 'word-search-forward)))
       (goto-char (cdr match-cons))
       (list (save-excursion (back-to-indentation) (point)) 'ada-broken-indent))
      ;;
      ;; case..is
      ;;
      ((save-excursion
-        (setq match-cons (ada-search-ignore-string-comment
-                          "is" nil orgpoint nil 'word-search-forward)))
+       (setq match-cons (ada-search-ignore-string-comment
+                         "is" nil orgpoint nil 'word-search-forward)))
       (list (save-excursion (back-to-indentation) (point)) 'ada-when-indent))
      ;;
      ;; incomplete case
      ;;
      (t
       (list (save-excursion (back-to-indentation) (point))
-            'ada-broken-indent)))))
+           'ada-broken-indent)))))
 
 (defun ada-get-indent-when (orgpoint)
   "Calculate the indentation when point is just before a when statement.
 ORGPOINT is the limit position used in the calculation."
   (let ((cur-indent (save-excursion (back-to-indentation) (point))))
     (if (ada-search-ignore-string-comment "[ \t\n]*=>" nil orgpoint)
-        (list cur-indent 'ada-indent)
+       (list cur-indent 'ada-indent)
       (list cur-indent 'ada-broken-indent))))
 
 (defun ada-get-indent-if (orgpoint)
   "Calculate the indentation when point is just before an if statement.
 ORGPOINT is the limit position used in the calculation."
   (let ((cur-indent (save-excursion (back-to-indentation) (point)))
-        (match-cons nil))
+       (match-cons nil))
     ;;
     ;; Move to the correct then (ignore all "and then")
     ;;
     (while (and (setq match-cons (ada-search-ignore-string-comment
-                                  "\\<\\(then\\|and[ \t]*then\\)\\>"
-                                  nil orgpoint))
-                (= (downcase (char-after (car match-cons))) ?a)))
+                                 "\\<\\(then\\|and[ \t]*then\\)\\>"
+                                 nil orgpoint))
+               (= (downcase (char-after (car match-cons))) ?a)))
     ;; If "then" was found (we are looking at it)
     (if match-cons
-        (progn
-          ;;
-          ;; 'then' first in separate line ?
-          ;; => indent according to 'then',
-          ;; => else indent according to 'if'
-          ;;
-          (if (save-excursion
-                (back-to-indentation)
-                (looking-at "\\<then\\>"))
-              (setq cur-indent (save-excursion (back-to-indentation) (point))))
-          ;; skip 'then'
-          (forward-word 1)
-          (list cur-indent 'ada-indent))
+       (progn
+         ;;
+         ;; 'then' first in separate line ?
+         ;; => indent according to 'then',
+         ;; => else indent according to 'if'
+         ;;
+         (if (save-excursion
+               (back-to-indentation)
+               (looking-at "\\<then\\>"))
+             (setq cur-indent (save-excursion (back-to-indentation) (point))))
+         ;; skip 'then'
+         (forward-word 1)
+         (list cur-indent 'ada-indent))
 
       (list cur-indent 'ada-broken-indent))))
 
@@ -2993,11 +2997,11 @@ ORGPOINT is the limit position used in the calculation."
   (let ((pos nil))
     (cond
      ((save-excursion
-        (forward-word 1)
-        (setq pos (ada-goto-next-non-ws orgpoint)))
+       (forward-word 1)
+       (setq pos (ada-goto-next-non-ws orgpoint)))
       (goto-char pos)
       (save-excursion
-        (ada-indent-on-previous-lines t orgpoint)))
+       (ada-indent-on-previous-lines t orgpoint)))
 
      ;;  Special case for record types, for instance for:
      ;;     type A is (B : Integer;
@@ -3024,27 +3028,27 @@ ORGPOINT is the limit position used in the calculation."
   "Calculate the indentation when point is just before a subprogram.
 ORGPOINT is the limit position used in the calculation."
   (let ((match-cons nil)
-        (cur-indent (save-excursion (back-to-indentation) (point)))
-        (foundis nil))
+       (cur-indent (save-excursion (back-to-indentation) (point)))
+       (foundis nil))
     ;;
     ;; is there an 'is' in front of point ?
     ;;
     (if (save-excursion
-          (setq match-cons
-               (ada-search-ignore-string-comment
-                "\\<\\(is\\|do\\)\\>" nil orgpoint)))
-        ;;
-        ;; yes, then skip to its end
-        ;;
-        (progn
-          (setq foundis t)
-          (goto-char (cdr match-cons)))
+         (setq match-cons
+              (ada-search-ignore-string-comment
+               "\\<\\(is\\|do\\)\\>" nil orgpoint)))
+       ;;
+       ;; yes, then skip to its end
+       ;;
+       (progn
+         (setq foundis t)
+         (goto-char (cdr match-cons)))
       ;;
       ;; no, then goto next non-ws, if there is one in front of point
       ;;
       (progn
-        (unless (ada-goto-next-non-ws orgpoint)
-          (goto-char orgpoint))))
+       (unless (ada-goto-next-non-ws orgpoint)
+         (goto-char orgpoint))))
 
     (cond
      ;;
@@ -3053,8 +3057,8 @@ ORGPOINT is the limit position used in the calculation."
      ((and
        foundis
        (save-excursion
-         (not (ada-search-ignore-string-comment
-               "[^ \t\n]" nil orgpoint t))))
+        (not (ada-search-ignore-string-comment
+              "[^ \t\n]" nil orgpoint t))))
       (list cur-indent 'ada-indent))
      ;;
      ;; is abstract/separate/new ...
@@ -3062,10 +3066,10 @@ ORGPOINT is the limit position used in the calculation."
      ((and
        foundis
        (save-excursion
-         (setq match-cons
-              (ada-search-ignore-string-comment
-               "\\<\\(separate\\|new\\|abstract\\)\\>"
-               nil orgpoint))))
+        (setq match-cons
+             (ada-search-ignore-string-comment
+              "\\<\\(separate\\|new\\|abstract\\)\\>"
+              nil orgpoint))))
       (goto-char (car match-cons))
       (ada-search-ignore-string-comment ada-subprog-start-re t)
       (ada-get-indent-noindent orgpoint))
@@ -3081,7 +3085,7 @@ ORGPOINT is the limit position used in the calculation."
      ;; no 'is' but ';'
      ;;
      ((save-excursion
-        (ada-search-ignore-string-comment ";" nil orgpoint nil 'search-forward))
+       (ada-search-ignore-string-comment ";" nil orgpoint nil 'search-forward))
       (list cur-indent 0))
      ;;
      ;; no 'is' or ';'
@@ -3102,74 +3106,74 @@ ORGPOINT is the limit position used in the calculation."
        ;;  subprogram declaration (in that case, we are at this point inside
        ;;  the parameter declaration list)
        ((ada-in-paramlist-p)
-        (ada-previous-procedure)
-        (list (save-excursion (back-to-indentation) (point)) 0))
+       (ada-previous-procedure)
+       (list (save-excursion (back-to-indentation) (point)) 0))
 
        ;;  This one is called when indenting the second line of a multi-line
        ;;  declaration section, in a declare block or a record declaration
        ((looking-at "[ \t]*\\(\\sw\\|_\\)*[ \t]*,[ \t]*$")
-        (list (save-excursion (back-to-indentation) (point))
-              'ada-broken-decl-indent))
+       (list (save-excursion (back-to-indentation) (point))
+             'ada-broken-decl-indent))
 
        ;;  This one is called in every over case when indenting a line at the
        ;;  top level
        (t
-        (if (looking-at ada-named-block-re)
-            (setq label (- ada-label-indent))
-
-          (let (p)
-
-            ;;  "with private" or "null record" cases
-            (if (or (save-excursion
-                      (and (ada-search-ignore-string-comment "\\<private\\>" nil orgpoint)
-                           (setq p (point))
-                           (save-excursion (forward-char -7);; skip back "private"
-                                           (ada-goto-previous-word)
-                                           (looking-at "with"))))
-                    (save-excursion
-                      (and (ada-search-ignore-string-comment "\\<record\\>" nil orgpoint)
-                           (setq p (point))
-                           (save-excursion (forward-char -6);; skip back "record"
-                                           (ada-goto-previous-word)
-                                           (looking-at "null")))))
-                (progn
-                  (goto-char p)
-                  (re-search-backward "\\<\\(type\\|subtype\\)\\>" nil t)
-                  (list (save-excursion (back-to-indentation) (point)) 0)))))
-        (if (save-excursion
-              (ada-search-ignore-string-comment ";" nil orgpoint nil
-                                                'search-forward))
-            (list (+ (save-excursion (back-to-indentation) (point)) label) 0)
-          (list (+ (save-excursion (back-to-indentation) (point)) label)
-                'ada-broken-indent)))))))
+       (if (looking-at ada-named-block-re)
+           (setq label (- ada-label-indent))
+
+         (let (p)
+
+           ;;  "with private" or "null record" cases
+           (if (or (save-excursion
+                     (and (ada-search-ignore-string-comment "\\<private\\>" nil orgpoint)
+                          (setq p (point))
+                          (save-excursion (forward-char -7);; skip back "private"
+                                          (ada-goto-previous-word)
+                                          (looking-at "with"))))
+                   (save-excursion
+                     (and (ada-search-ignore-string-comment "\\<record\\>" nil orgpoint)
+                          (setq p (point))
+                          (save-excursion (forward-char -6);; skip back "record"
+                                          (ada-goto-previous-word)
+                                          (looking-at "null")))))
+               (progn
+                 (goto-char p)
+                 (re-search-backward "\\<\\(type\\|subtype\\)\\>" nil t)
+                 (list (save-excursion (back-to-indentation) (point)) 0)))))
+       (if (save-excursion
+             (ada-search-ignore-string-comment ";" nil orgpoint nil
+                                               'search-forward))
+           (list (+ (save-excursion (back-to-indentation) (point)) label) 0)
+         (list (+ (save-excursion (back-to-indentation) (point)) label)
+               'ada-broken-indent)))))))
 
 (defun ada-get-indent-label (orgpoint)
   "Calculate the indentation when before a label or variable declaration.
 ORGPOINT is the limit position used in the calculation."
   (let ((match-cons nil)
-        (cur-indent (save-excursion (back-to-indentation) (point))))
+       (cur-indent (save-excursion (back-to-indentation) (point))))
     (ada-search-ignore-string-comment ":" nil)
     (cond
      ;; loop label
      ((save-excursion
-        (setq match-cons (ada-search-ignore-string-comment
-                          ada-loop-start-re nil orgpoint)))
+       (setq match-cons (ada-search-ignore-string-comment
+                         ada-loop-start-re nil orgpoint)))
       (goto-char (car match-cons))
       (ada-get-indent-loop orgpoint))
 
      ;; declare label
      ((save-excursion
-        (setq match-cons (ada-search-ignore-string-comment
-                          "\\<declare\\|begin\\>" nil orgpoint)))
+       (setq match-cons (ada-search-ignore-string-comment
+                         "\\<declare\\|begin\\>" nil orgpoint)))
       (goto-char (car match-cons))
       (list (save-excursion (back-to-indentation) (point)) 'ada-indent))
 
      ;; variable declaration
      ((ada-in-decl-p)
       (if (save-excursion
-            (ada-search-ignore-string-comment ";" nil orgpoint))
-          (list cur-indent 0)
-        (list cur-indent 'ada-broken-indent)))
+           (ada-search-ignore-string-comment ";" nil orgpoint))
+         (list cur-indent 0)
+       (list cur-indent 'ada-broken-indent)))
 
      ;; nothing follows colon
      (t
@@ -3179,14 +3183,14 @@ ORGPOINT is the limit position used in the calculation."
   "Calculate the indentation when just before a loop or a for ... use.
 ORGPOINT is the limit position used in the calculation."
   (let ((match-cons nil)
-        (pos (point))
+       (pos (point))
 
-        ;; If looking at a named block, skip the label
-        (label (save-excursion
-                 (beginning-of-line)
-                 (if (looking-at ada-named-block-re)
-                     (- ada-label-indent)
-                   0))))
+       ;; If looking at a named block, skip the label
+       (label (save-excursion
+                (beginning-of-line)
+                (if (looking-at ada-named-block-re)
+                    (- ada-label-indent)
+                  0))))
 
     (cond
 
@@ -3194,8 +3198,8 @@ ORGPOINT is the limit position used in the calculation."
      ;; statement complete
      ;;
      ((save-excursion
-        (ada-search-ignore-string-comment ";" nil orgpoint nil
-                                          'search-forward))
+       (ada-search-ignore-string-comment ";" nil orgpoint nil
+                                         'search-forward))
       (list (+ (save-excursion (back-to-indentation) (point)) label) 0))
      ;;
      ;; simple loop
@@ -3203,8 +3207,8 @@ ORGPOINT is the limit position used in the calculation."
      ((looking-at "loop\\>")
       (setq pos (ada-get-indent-block-start orgpoint))
       (if (equal label 0)
-          pos
-        (list (+ (car pos) label) (cdr pos))))
+         pos
+       (list (+ (car pos) label) (cdr pos))))
 
      ;;
      ;; 'for'- loop (or also a for ... use statement)
@@ -3215,21 +3219,21 @@ ORGPOINT is the limit position used in the calculation."
        ;; for ... use
        ;;
        ((save-excursion
-          (and
-           (goto-char (match-end 0))
-           (ada-goto-next-non-ws orgpoint)
-           (forward-word 1)
-           (if (= (char-after) ?') (forward-word 1) t)
-           (ada-goto-next-non-ws orgpoint)
-           (looking-at "\\<use\\>")
-           ;;
-           ;; check if there is a 'record' before point
-           ;;
-           (progn
-             (setq match-cons (ada-search-ignore-string-comment
-                               "record" nil orgpoint nil 'word-search-forward))
-             t)))
-        (if match-cons
+         (and
+          (goto-char (match-end 0))
+          (ada-goto-next-non-ws orgpoint)
+          (forward-word 1)
+          (if (= (char-after) ?') (forward-word 1) t)
+          (ada-goto-next-non-ws orgpoint)
+          (looking-at "\\<use\\>")
+          ;;
+          ;; check if there is a 'record' before point
+          ;;
+          (progn
+            (setq match-cons (ada-search-ignore-string-comment
+                              "record" nil orgpoint nil 'word-search-forward))
+            t)))
+       (if match-cons
            (progn
              (goto-char (car match-cons))
              (list (save-excursion (back-to-indentation) (point)) 'ada-indent))
@@ -3240,25 +3244,25 @@ ORGPOINT is the limit position used in the calculation."
        ;; for..loop
        ;;
        ((save-excursion
-          (setq match-cons (ada-search-ignore-string-comment
-                            "loop" nil orgpoint nil 'word-search-forward)))
-        (goto-char (car match-cons))
-        ;;
-        ;; indent according to 'loop', if it's first in the line;
-        ;; otherwise to 'for'
-        ;;
-        (unless (save-excursion
-                  (back-to-indentation)
-                  (looking-at "\\<loop\\>"))
-          (goto-char pos))
-        (list (+ (save-excursion (back-to-indentation) (point)) label)
-              'ada-indent))
+         (setq match-cons (ada-search-ignore-string-comment
+                           "loop" nil orgpoint nil 'word-search-forward)))
+       (goto-char (car match-cons))
+       ;;
+       ;; indent according to 'loop', if it's first in the line;
+       ;; otherwise to 'for'
+       ;;
+       (unless (save-excursion
+                 (back-to-indentation)
+                 (looking-at "\\<loop\\>"))
+         (goto-char pos))
+       (list (+ (save-excursion (back-to-indentation) (point)) label)
+             'ada-indent))
        ;;
        ;; for-statement is broken
        ;;
        (t
-        (list (+ (save-excursion (back-to-indentation) (point)) label)
-              'ada-broken-indent))))
+       (list (+ (save-excursion (back-to-indentation) (point)) label)
+             'ada-broken-indent))))
 
      ;;
      ;; 'while'-loop
@@ -3268,24 +3272,24 @@ ORGPOINT is the limit position used in the calculation."
       ;; while..loop ?
       ;;
       (if (save-excursion
-            (setq match-cons (ada-search-ignore-string-comment
-                              "loop" nil orgpoint nil 'word-search-forward)))
-
-          (progn
-            (goto-char (car match-cons))
-            ;;
-            ;; indent according to 'loop', if it's first in the line;
-            ;; otherwise to 'while'.
-            ;;
-            (unless (save-excursion
-                      (back-to-indentation)
-                      (looking-at "\\<loop\\>"))
-              (goto-char pos))
-            (list (+ (save-excursion (back-to-indentation) (point)) label)
-                  'ada-indent))
-
-        (list (+ (save-excursion (back-to-indentation) (point)) label)
-              'ada-broken-indent))))))
+           (setq match-cons (ada-search-ignore-string-comment
+                             "loop" nil orgpoint nil 'word-search-forward)))
+
+         (progn
+           (goto-char (car match-cons))
+           ;;
+           ;; indent according to 'loop', if it's first in the line;
+           ;; otherwise to 'while'.
+           ;;
+           (unless (save-excursion
+                     (back-to-indentation)
+                     (looking-at "\\<loop\\>"))
+             (goto-char pos))
+           (list (+ (save-excursion (back-to-indentation) (point)) label)
+                 'ada-indent))
+
+       (list (+ (save-excursion (back-to-indentation) (point)) label)
+             'ada-broken-indent))))))
 
 (defun ada-get-indent-type (orgpoint)
   "Calculate the indentation when before a type statement.
@@ -3296,46 +3300,46 @@ ORGPOINT is the limit position used in the calculation."
      ;; complete record declaration
      ;;
      ((save-excursion
-        (and
-         (setq match-dat (ada-search-ignore-string-comment
-                          "end" nil orgpoint nil 'word-search-forward))
-         (ada-goto-next-non-ws)
-         (looking-at "\\<record\\>")
-         (forward-word 1)
-         (ada-goto-next-non-ws)
-         (= (char-after) ?\;)))
+       (and
+        (setq match-dat (ada-search-ignore-string-comment
+                         "end" nil orgpoint nil 'word-search-forward))
+        (ada-goto-next-non-ws)
+        (looking-at "\\<record\\>")
+        (forward-word 1)
+        (ada-goto-next-non-ws)
+        (= (char-after) ?\;)))
       (goto-char (car match-dat))
       (list (save-excursion (back-to-indentation) (point)) 0))
      ;;
      ;; record type
      ;;
      ((save-excursion
-        (setq match-dat (ada-search-ignore-string-comment
-                         "record" nil orgpoint nil 'word-search-forward)))
+       (setq match-dat (ada-search-ignore-string-comment
+                        "record" nil orgpoint nil 'word-search-forward)))
       (goto-char (car match-dat))
       (list (save-excursion (back-to-indentation) (point)) 'ada-indent))
      ;;
      ;; complete type declaration
      ;;
      ((save-excursion
-        (ada-search-ignore-string-comment ";" nil orgpoint nil
-                                          'search-forward))
+       (ada-search-ignore-string-comment ";" nil orgpoint nil
+                                         'search-forward))
       (list (save-excursion (back-to-indentation) (point)) 0))
      ;;
      ;; "type ... is", but not "type ... is ...", which is broken
      ;;
      ((save-excursion
-        (and
-         (ada-search-ignore-string-comment "is" nil orgpoint nil
-                                           'word-search-forward)
-         (not (ada-goto-next-non-ws orgpoint))))
+       (and
+        (ada-search-ignore-string-comment "is" nil orgpoint nil
+                                          'word-search-forward)
+        (not (ada-goto-next-non-ws orgpoint))))
       (list (save-excursion (back-to-indentation) (point)) 'ada-broken-indent))
      ;;
      ;; broken statement
      ;;
      (t
       (list (save-excursion (back-to-indentation) (point))
-            'ada-broken-indent)))))
+           'ada-broken-indent)))))
 
 \f
 ;; -----------------------------------------------------------
@@ -3348,7 +3352,7 @@ Return the new position of point.
 As a special case, if we are looking at a closing parenthesis, skip to the
 open parenthesis."
   (let ((match-dat nil)
-        (orgpoint (point)))
+       (orgpoint (point)))
 
     (setq match-dat (ada-search-prev-end-stmt))
     (if match-dat
@@ -3393,14 +3397,14 @@ open parenthesis."
 Return a cons cell whose car is the beginning and whose cdr
 is the end of the match."
   (let ((match-dat nil)
-        (found nil))
+       (found nil))
 
     ;; search until found or beginning-of-buffer
     (while
-        (and
-         (not found)
-         (setq match-dat (ada-search-ignore-string-comment
-                          ada-end-stmt-re t)))
+       (and
+        (not found)
+        (setq match-dat (ada-search-ignore-string-comment
+                         ada-end-stmt-re t)))
 
       (goto-char (car match-dat))
       (unless (ada-in-open-paren-p)
@@ -3415,27 +3419,32 @@ is the end of the match."
 
         ((looking-at "is")
          (setq found
-               (and (save-excursion (ada-goto-previous-word)
+               (and (save-excursion (ada-goto-previous-word)
                                     (ada-goto-previous-word)
                                     (not (looking-at "subtype")))
 
-                   (save-excursion (goto-char (cdr match-dat))
-                                   (ada-goto-next-non-ws)
-                                   ;;  words that can go after an 'is'
-                                   (not (looking-at
-                                    (eval-when-compile
-                                      (concat "\\<"
-                                              (regexp-opt
-                                               '("separate" "access" "array"
-                                                 "abstract" "new") t)
-                                              "\\>\\|("))))))))
+                   (save-excursion (goto-char (cdr match-dat))
+                                   (ada-goto-next-non-ws)
+                                   ;;  words that can go after an 'is'
+                                   (not (looking-at
+                                    (eval-when-compile
+                                      (concat "\\<"
+                                              (regexp-opt
+                                               '("separate" "access" "array"
+                                                 "private" "abstract" "new") t)
+                                              "\\>\\|("))))))))
+
+        ((looking-at "private")
+         (save-excursion
+           (backward-word 1)
+           (setq found (not (looking-at "is")))))
 
         (t
          (setq found t))
-        )))
+       )))
 
     (if found
-        match-dat
+       match-dat
       nil)))
 
 
@@ -3446,11 +3455,11 @@ Do not call this function from within a string."
   (unless limit
     (setq limit (point-max)))
   (while (and (<= (point) limit)
-              (progn (forward-comment 10000)
-                     (if (and (not (eobp))
-                              (save-excursion (forward-char 1)
-                                              (ada-in-string-p)))
-                         (progn (forward-sexp 1) t)))))
+             (progn (forward-comment 10000)
+                    (if (and (not (eobp))
+                             (save-excursion (forward-char 1)
+                                             (ada-in-string-p)))
+                        (progn (forward-sexp 1) t)))))
   (if (< (point) limit)
       (point)
     nil)
@@ -3471,22 +3480,22 @@ Stop the search at LIMIT."
 If BACKWARD is non-nil, jump to the beginning of the previous word.
 Return the new position of point or nil if not found."
   (let ((match-cons nil)
-        (orgpoint (point))
-        (old-syntax (char-to-string (char-syntax ?_))))
+       (orgpoint (point))
+       (old-syntax (char-to-string (char-syntax ?_))))
     (modify-syntax-entry ?_ "w")
     (unless backward
       (skip-syntax-forward "w"))
     (if (setq match-cons
-             (if backward
-                 (ada-search-ignore-string-comment "\\w" t nil t)
-               (ada-search-ignore-string-comment "\\w" nil nil t)))
-        ;;
-        ;; move to the beginning of the word found
-        ;;
-        (progn
-          (goto-char (car match-cons))
-          (skip-syntax-backward "w")
-          (point))
+            (if backward
+                (ada-search-ignore-string-comment "\\w" t nil t)
+              (ada-search-ignore-string-comment "\\w" nil nil t)))
+       ;;
+       ;; move to the beginning of the word found
+       ;;
+       (progn
+         (goto-char (car match-cons))
+         (skip-syntax-backward "w")
+         (point))
       ;;
       ;; if not found, restore old position of point
       ;;
@@ -3511,8 +3520,8 @@ Moves point to the beginning of the declaration."
 
   ;; named block without a `declare'
   (if (save-excursion
-        (ada-goto-previous-word)
-        (looking-at (concat "\\<" defun-name "\\> *:")))
+       (ada-goto-previous-word)
+       (looking-at (concat "\\<" defun-name "\\> *:")))
       t                                 ; do nothing
     ;;
     ;; 'accept' or 'package' ?
@@ -3524,30 +3533,30 @@ Moves point to the beginning of the declaration."
     ;;
     (save-excursion
       ;;
-      ;; a named 'declare'-block ?
+      ;; a named 'declare'-block ? => jump to the label
       ;;
       (if (looking-at "\\<declare\\>")
-          (ada-goto-stmt-start)
-        ;;
-        ;; no, => 'procedure'/'function'/'task'/'protected'
-        ;;
-        (progn
-          (forward-word 2)
-          (backward-word 1)
-          ;;
-          ;; skip 'body' 'type'
-          ;;
-          (if (looking-at "\\<\\(body\\|type\\)\\>")
-              (forward-word 1))
-          (forward-sexp 1)
-          (backward-sexp 1)))
+         (backward-word 1)
+       ;;
+       ;; no, => 'procedure'/'function'/'task'/'protected'
+       ;;
+       (progn
+         (forward-word 2)
+         (backward-word 1)
+         ;;
+         ;; skip 'body' 'type'
+         ;;
+         (if (looking-at "\\<\\(body\\|type\\)\\>")
+             (forward-word 1))
+         (forward-sexp 1)
+         (backward-sexp 1)))
       ;;
       ;; should be looking-at the correct name
       ;;
       (unless (looking-at (concat "\\<" defun-name "\\>"))
-        (error "Matching defun has different name: %s"
-               (buffer-substring (point)
-                                 (progn (forward-sexp 1) (point))))))))
+       (error "Matching defun has different name: %s"
+              (buffer-substring (point)
+                                (progn (forward-sexp 1) (point))))))))
 
 (defun ada-goto-matching-decl-start (&optional noerror recursive)
   "Move point to the matching declaration start of the current 'begin'.
@@ -3556,10 +3565,10 @@ If NOERROR is non-nil, it only returns nil if no match was found."
 
        ;;  first should be set to t if we should stop at the first
        ;;  "begin" we encounter.
-        (first (not recursive))
-        (count-generic nil)
+       (first (not recursive))
+       (count-generic nil)
        (stop-at-when nil)
-        )
+       )
 
     ;;  Ignore "when" most of the time, except if we are looking at the
     ;;  beginning of a block (structure:  case .. is
@@ -3567,65 +3576,65 @@ If NOERROR is non-nil, it only returns nil if no match was found."
     ;;                                       begin ...
     ;;                                       exception ... )
     (if (looking-at "begin")
-        (setq stop-at-when t))
+       (setq stop-at-when t))
 
     (if (or
-         (looking-at "\\<\\(package\\|procedure\\|function\\)\\>")
-         (save-excursion
-           (ada-search-ignore-string-comment
-            "\\<\\(package\\|procedure\\|function\\|generic\\)\\>" t)
-           (looking-at "generic")))
-        (setq count-generic t))
+        (looking-at "\\<\\(package\\|procedure\\|function\\)\\>")
+        (save-excursion
+          (ada-search-ignore-string-comment
+           "\\<\\(package\\|procedure\\|function\\|generic\\)\\>" t)
+          (looking-at "generic")))
+       (setq count-generic t))
 
     ;; search backward for interesting keywords
     (while (and
-            (not (zerop nest-count))
-            (ada-search-ignore-string-comment ada-matching-decl-start-re t))
+           (not (zerop nest-count))
+           (ada-search-ignore-string-comment ada-matching-decl-start-re t))
       ;;
       ;; calculate nest-depth
       ;;
       (cond
        ;;
        ((looking-at "end")
-        (ada-goto-matching-start 1 noerror)
-
-        ;;  In some case, two begin..end block can follow each other closely,
-        ;;  which we have to detect, as in
-        ;;     procedure P is
-        ;;        procedure Q is
-        ;;        begin
-        ;;        end;
-        ;;     begin    --  here we should go to procedure, not begin
-        ;;     end
-
-        (if (looking-at "begin")
-            (let ((loop-again t))
-              (save-excursion
-                (while loop-again
-                  ;;  If begin was just there as the beginning of a block
-                  ;;  (with no declare) then do nothing, otherwise just
-                  ;;  register that we have to find the statement that
-                  ;;  required the begin
-
-                  (ada-search-ignore-string-comment
-                   "\\<\\(declare\\|begin\\|end\\|procedure\\|function\\|task\\|package\\)\\>"
-                   t)
-
-                  (if (looking-at "end")
+       (ada-goto-matching-start 1 noerror)
+
+       ;;  In some case, two begin..end block can follow each other closely,
+       ;;  which we have to detect, as in
+       ;;     procedure P is
+       ;;        procedure Q is
+       ;;        begin
+       ;;        end;
+       ;;     begin    --  here we should go to procedure, not begin
+       ;;     end
+
+       (if (looking-at "begin")
+           (let ((loop-again t))
+             (save-excursion
+               (while loop-again
+                 ;;  If begin was just there as the beginning of a block
+                 ;;  (with no declare) then do nothing, otherwise just
+                 ;;  register that we have to find the statement that
+                 ;;  required the begin
+
+                 (ada-search-ignore-string-comment
+                  "\\<\\(declare\\|begin\\|end\\|procedure\\|function\\|task\\|package\\)\\>"
+                  t)
+
+                 (if (looking-at "end")
                      (ada-goto-matching-start 1 noerror t)
                    ;; (ada-goto-matching-decl-start noerror t)
 
-                    (setq loop-again nil)
-                    (unless (looking-at "begin")
-                      (setq nest-count (1+ nest-count))))
-                  ))
-              )))
+                   (setq loop-again nil)
+                   (unless (looking-at "begin")
+                     (setq nest-count (1+ nest-count))))
+                 ))
+             )))
        ;;
        ((looking-at "generic")
-        (if count-generic
-            (progn
-              (setq first nil)
-              (setq nest-count (1- nest-count)))))
+       (if count-generic
+           (progn
+             (setq first nil)
+             (setq nest-count (1- nest-count)))))
        ;;
        ((looking-at "if")
        (save-excursion
@@ -3637,49 +3646,49 @@ If NOERROR is non-nil, it only returns nil if no match was found."
 
        ;;
        ((looking-at "declare\\|generic")
-        (setq nest-count (1- nest-count))
-        (setq first t))
+       (setq nest-count (1- nest-count))
+       (setq first t))
        ;;
        ((looking-at "is")
-        ;; check if it is only a type definition, but not a protected
-        ;; type definition, which should be handled like a procedure.
-        (if (or (looking-at "is[ \t]+<>")
-                (save-excursion
-                  (forward-comment -10000)
-                  (forward-char -1)
-
-                  ;; Detect if we have a closing parenthesis (Could be
-                  ;; either the end of subprogram parameters or (<>)
-                  ;; in a type definition
-                  (if (= (char-after) ?\))
-                      (progn
-                        (forward-char 1)
-                        (backward-sexp 1)
-                        (forward-comment -10000)
-                        ))
-                  (skip-chars-backward "a-zA-Z0-9_.'")
-                  (ada-goto-previous-word)
-                  (and
-                   (looking-at "\\<\\(sub\\)?type\\|case\\>")
-                   (save-match-data
-                     (ada-goto-previous-word)
-                     (not (looking-at "\\<protected\\>"))))
-                  ))                    ; end of `or'
-            (goto-char (match-beginning 0))
-          (progn
-            (setq nest-count (1- nest-count))
-            (setq first nil))))
+       ;; check if it is only a type definition, but not a protected
+       ;; type definition, which should be handled like a procedure.
+       (if (or (looking-at "is[ \t]+<>")
+               (save-excursion
+                 (forward-comment -10000)
+                 (forward-char -1)
+
+                 ;; Detect if we have a closing parenthesis (Could be
+                 ;; either the end of subprogram parameters or (<>)
+                 ;; in a type definition
+                 (if (= (char-after) ?\))
+                     (progn
+                       (forward-char 1)
+                       (backward-sexp 1)
+                       (forward-comment -10000)
+                       ))
+                 (skip-chars-backward "a-zA-Z0-9_.'")
+                 (ada-goto-previous-word)
+                 (and
+                  (looking-at "\\<\\(sub\\)?type\\|case\\>")
+                  (save-match-data
+                    (ada-goto-previous-word)
+                    (not (looking-at "\\<protected\\>"))))
+                 ))                    ; end of `or'
+           (goto-char (match-beginning 0))
+         (progn
+           (setq nest-count (1- nest-count))
+           (setq first nil))))
 
        ;;
        ((looking-at "new")
-        (if (save-excursion
-              (ada-goto-previous-word)
-              (looking-at "is"))
-            (goto-char (match-beginning 0))))
+       (if (save-excursion
+             (ada-goto-previous-word)
+             (looking-at "is"))
+           (goto-char (match-beginning 0))))
        ;;
        ((and first
-             (looking-at "begin"))
-        (setq nest-count 0))
+            (looking-at "begin"))
+       (setq nest-count 0))
        ;;
        ((looking-at "when")
        (save-excursion
@@ -3694,20 +3703,20 @@ If NOERROR is non-nil, it only returns nil if no match was found."
        (setq first nil))
        ;;
        (t
-        (setq nest-count (1+ nest-count))
-        (setq first nil)))
+       (setq nest-count (1+ nest-count))
+       (setq first nil)))
 
       );; end of loop
 
     ;; check if declaration-start is really found
     (if (and
-         (zerop nest-count)
-         (if (looking-at "is")
-             (ada-search-ignore-string-comment ada-subprog-start-re t)
-           (looking-at "declare\\|generic")))
-        t
+        (zerop nest-count)
+        (if (looking-at "is")
+            (ada-search-ignore-string-comment ada-subprog-start-re t)
+          (looking-at "declare\\|generic")))
+       t
       (if noerror nil
-        (error "No matching proc/func/task/declare/package/protected")))
+       (error "No matching proc/func/task/declare/package/protected")))
     ))
 
 (defun ada-goto-matching-start (&optional nest-level noerror gotothen)
@@ -3716,110 +3725,170 @@ Which block depends on the value of NEST-LEVEL, which defaults to zero.
 If NOERROR is non-nil, it only returns nil if no matching start was found.
 If GOTOTHEN is non-nil, point moves to the 'then' following 'if'."
   (let ((nest-count (if nest-level nest-level 0))
-        (found nil)
-        (pos nil))
+       (found nil)
+
+       (last-was-begin '())
+       ;;  List all keywords encountered while traversing
+       ;;  something like '("end" "end" "begin")
+       ;;  This is removed from the list when "package", "procedure",...
+       ;;  are seen. The goal is to find whether a package has an elaboration
+       ;;  part
+
+       (pos nil))
 
-    ;;
     ;; search backward for interesting keywords
-    ;;
     (while (and
-            (not found)
-            (ada-search-ignore-string-comment ada-matching-start-re t))
+           (not found)
+           (ada-search-ignore-string-comment ada-matching-start-re t))
 
       (unless (and (looking-at "\\<record\\>")
-                   (save-excursion
-                     (forward-word -1)
-                     (looking-at "\\<null\\>")))
-        (progn
-          ;;
-          ;; calculate nest-depth
-          ;;
-          (cond
-           ;; found block end => increase nest depth
-           ((looking-at "end")
-            (setq nest-count (1+ nest-count)))
-
-           ;; found loop/select/record/case/if => check if it starts or
-           ;; ends a block
-           ((looking-at "loop\\|select\\|record\\|case\\|if")
-            (setq pos (point))
-            (save-excursion
-              ;;
-              ;; check if keyword follows 'end'
-              ;;
-              (ada-goto-previous-word)
-              (if (looking-at "\\<end\\>[ \t]*[^;]")
-                  ;; it ends a block => increase nest depth
-                 (setq nest-count (1+ nest-count)
-                       pos        (point))
-
-                ;; it starts a block => decrease nest depth
-                (setq nest-count (1- nest-count))))
-            (goto-char pos))
-
-           ;; found package start => check if it really is a block
-           ((looking-at "package")
-            (save-excursion
-              ;; ignore if this is just a renames statement
-              (let ((current (point))
-                    (pos (ada-search-ignore-string-comment
-                          "\\<\\(is\\|renames\\|;\\)\\>" nil)))
-                (if pos
-                    (goto-char (car pos))
-                  (error (concat
-                          "No matching 'is' or 'renames' for 'package' at"
-                          " line "
-                          (number-to-string (count-lines 1 (1+ current)))))))
-              (unless (looking-at "renames")
-                (progn
-                  (forward-word 1)
-                  (ada-goto-next-non-ws)
-                  ;; ignore it if it is only a declaration with 'new'
+                  (save-excursion
+                    (forward-word -1)
+                    (looking-at "\\<null\\>")))
+       (progn
+         ;; calculate nest-depth
+         (cond
+          ;; found block end => increase nest depth
+          ((looking-at "end")
+           (push nil last-was-begin)
+           (setq nest-count (1+ nest-count)))
+
+          ;; found loop/select/record/case/if => check if it starts or
+          ;; ends a block
+          ((looking-at "loop\\|select\\|record\\|case\\|if")
+           (setq pos (point))
+           (save-excursion
+             ;; check if keyword follows 'end'
+             (ada-goto-previous-word)
+             (if (looking-at "\\<end\\>[ \t]*[^;]")
+                 (progn
+                   ;; it ends a block => increase nest depth
+                   (setq nest-count (1+ nest-count)
+                         pos        (point))
+                   (push nil last-was-begin))
+
+               ;; it starts a block => decrease nest depth
+               (setq nest-count (1- nest-count))
+
+               ;; Some nested  "begin .. end" blocks with no "declare"?
+               ;;  => remove those entries
+               (while (car last-was-begin)
+                 (setq last-was-begin (cdr (cdr last-was-begin))))
+
+               (setq last-was-begin (cdr last-was-begin))
+               ))
+           (goto-char pos)
+           )
+
+          ;; found package start => check if it really is a block
+          ((looking-at "package")
+           (save-excursion
+             ;; ignore if this is just a renames statement
+             (let ((current (point))
+                   (pos (ada-search-ignore-string-comment
+                         "\\<\\(is\\|renames\\|;\\)\\>" nil)))
+               (if pos
+                   (goto-char (car pos))
+                 (error (concat
+                         "No matching 'is' or 'renames' for 'package' at"
+                         " line "
+                         (number-to-string (count-lines 1 (1+ current)))))))
+             (unless (looking-at "renames")
+               (progn
+                 (forward-word 1)
+                 (ada-goto-next-non-ws)
+                 ;; ignore it if it is only a declaration with 'new'
                  ;; We could have  package Foo is new ....
                  ;;  or            package Foo is separate;
                  ;;  or            package Foo is begin null; end Foo
                  ;;                     for elaboration code (elaboration)
-                  (if (not (looking-at "\\<\\(new\\|separate\\|begin\\)\\>"))
-                      (setq nest-count (1- nest-count)))))))
-           ;; found task start => check if it has a body
-           ((looking-at "task")
-            (save-excursion
-              (forward-word 1)
-              (ada-goto-next-non-ws)
-              (cond
-               ((looking-at "\\<body\\>"))
-               ((looking-at "\\<type\\>")
-                ;;  In that case, do nothing if there is a "is"
-                (forward-word 2);; skip "type"
-                (ada-goto-next-non-ws);; skip type name
-
-                ;; Do nothing if we are simply looking at a simple
-                ;; "task type name;" statement with no block
-                (unless (looking-at ";")
-                  (progn
-                    ;; Skip the parameters
-                    (if (looking-at "(")
-                        (ada-search-ignore-string-comment ")" nil))
-                    (let ((tmp (ada-search-ignore-string-comment
-                                "\\<\\(is\\|;\\)\\>" nil)))
-                      (if tmp
-                          (progn
-                            (goto-char (car tmp))
-                            (if (looking-at "is")
-                                (setq nest-count (1- nest-count)))))))))
-               (t
-                ;; Check if that task declaration had a block attached to
-                ;; it (i.e do nothing if we have just "task name;")
-                (unless (progn (forward-word 1)
-                               (looking-at "[ \t]*;"))
-                  (setq nest-count (1- nest-count)))))))
-           ;; all the other block starts
-           (t
-            (setq nest-count (1- nest-count)))) ; end of 'cond'
-
-          ;; match is found, if nest-depth is zero
-          ;;
-          (setq found (zerop nest-count))))) ; end of loop
+                 (if (and (not (looking-at "\\<\\(new\\|separate\\|begin\\)\\>"))
+                          (not (car last-was-begin)))
+                     (setq nest-count (1- nest-count))))))
+
+           (setq last-was-begin (cdr last-was-begin))
+           )
+          ;; found task start => check if it has a body
+          ((looking-at "task")
+           (save-excursion
+             (forward-word 1)
+             (ada-goto-next-non-ws)
+             (cond
+              ((looking-at "\\<body\\>"))
+              ((looking-at "\\<type\\>")
+               ;;  In that case, do nothing if there is a "is"
+               (forward-word 2);; skip "type"
+               (ada-goto-next-non-ws);; skip type name
+
+               ;; Do nothing if we are simply looking at a simple
+               ;; "task type name;" statement with no block
+               (unless (looking-at ";")
+                 (progn
+                   ;; Skip the parameters
+                   (if (looking-at "(")
+                       (ada-search-ignore-string-comment ")" nil))
+                   (let ((tmp (ada-search-ignore-string-comment
+                               "\\<\\(is\\|;\\)\\>" nil)))
+                     (if tmp
+                         (progn
+                           (goto-char (car tmp))
+                           (if (looking-at "is")
+                               (setq nest-count (1- nest-count)))))))))
+              (t
+               ;; Check if that task declaration had a block attached to
+               ;; it (i.e do nothing if we have just "task name;")
+               (unless (progn (forward-word 1)
+                              (looking-at "[ \t]*;"))
+                 (setq nest-count (1- nest-count))))))
+           (setq last-was-begin (cdr last-was-begin))
+           )
+
+          ((looking-at "declare")
+           ;;  remove entry for begin and end (include nested begin..end
+           ;;  groups)
+           (setq last-was-begin (cdr last-was-begin))
+           (let ((count 1))
+             (while (and (> count 0))
+               (if (equal (car last-was-begin) t)
+                   (setq count (1+ count))
+                 (setq count (1- count)))
+               (setq last-was-begin (cdr last-was-begin))
+               )))
+
+          ((looking-at "protected")
+           ;; Ignore if this is just a declaration
+           (save-excursion
+             (let ((pos (ada-search-ignore-string-comment
+                         "\\(\\<is\\>\\|\\<renames\\>\\|;\\)" nil)))
+               (if pos
+                   (goto-char (car pos)))
+               (if (looking-at "is")
+                   ;;  remove entry for end
+                   (setq last-was-begin (cdr last-was-begin)))))
+           (setq nest-count     (1- nest-count)))
+
+          ((or (looking-at "procedure")
+               (looking-at "function"))
+           ;; Ignore if this is just a declaration
+           (save-excursion
+             (let ((pos (ada-search-ignore-string-comment
+                         "\\(\\<is\\>\\|\\<renames\\>\\|)[ \t]*;\\)" nil)))
+               (if pos
+                   (goto-char (car pos)))
+               (if (looking-at "is")
+                   ;;  remove entry for begin and end
+                   (setq last-was-begin (cdr (cdr last-was-begin))))))
+           )
+
+          ;; all the other block starts
+          (t
+           (push (looking-at "begin") last-was-begin)
+           (setq nest-count (1- nest-count)))
+
+          )
+
+         ;; match is found, if nest-depth is zero
+         (setq found (zerop nest-count))))) ; end of loop
 
     (if (bobp)
        (point)
@@ -3861,7 +3930,7 @@ If GOTOTHEN is non-nil, point moves to the 'then' following 'if'."
 (defun ada-goto-matching-end (&optional nest-level noerror)
   "Move point to the end of a block.
 Which block depends on the value of NEST-LEVEL, which defaults to zero.
-If NOERROR is non-nil, it only returns nil if found no matching start."
+If NOERROR is non-nil, it only returns nil if no matching start found."
   (let ((nest-count (or nest-level 0))
        (regex (eval-when-compile
                 (concat "\\<"
@@ -3870,7 +3939,7 @@ If NOERROR is non-nil, it only returns nil if found no matching start."
                                       "procedure" "function") t)
                         "\\>")))
        found
-        pos
+       pos
 
        ;;  First is used for subprograms: they are generally handled
        ;;  recursively, but of course we do not want to do that the
@@ -3888,8 +3957,8 @@ If NOERROR is non-nil, it only returns nil if found no matching start."
     ;; search forward for interesting keywords
     ;;
     (while (and
-            (not found)
-            (ada-search-ignore-string-comment regex nil))
+           (not found)
+           (ada-search-ignore-string-comment regex nil))
 
       ;;
       ;; calculate nest-depth
@@ -3927,9 +3996,9 @@ If NOERROR is non-nil, it only returns nil if found no matching start."
 
        ;; found block end => decrease nest depth
        ((looking-at "\\<end\\>")
-        (setq nest-count (1- nest-count)
+       (setq nest-count (1- nest-count)
              found (<= nest-count 0))
-         ;; skip the following keyword
+        ;; skip the following keyword
        (if (progn
              (skip-chars-forward "end")
              (ada-goto-next-non-ws)
@@ -3939,13 +4008,13 @@ If NOERROR is non-nil, it only returns nil if found no matching start."
        ;; found package start => check if it really starts a block, and is not
        ;; in fact a generic instantiation for instance
        ((looking-at "\\<package\\>")
-        (ada-search-ignore-string-comment "is" nil nil nil
-                                          'word-search-forward)
-        (ada-goto-next-non-ws)
-        ;; ignore and skip it if it is only a 'new' package
-        (if (looking-at "\\<new\\>")
-            (goto-char (match-end 0))
-          (setq nest-count (1+ nest-count)
+       (ada-search-ignore-string-comment "is" nil nil nil
+                                         'word-search-forward)
+       (ada-goto-next-non-ws)
+       ;; ignore and skip it if it is only a 'new' package
+       (if (looking-at "\\<new\\>")
+           (goto-char (match-end 0))
+         (setq nest-count (1+ nest-count)
                found      (<= nest-count 0))))
 
        ;; all the other block starts
@@ -3953,34 +4022,35 @@ If NOERROR is non-nil, it only returns nil if found no matching start."
        (if (not first)
            (setq nest-count (1+ nest-count)))
        (setq found      (<= nest-count 0))
-        (forward-word 1)))              ; end of 'cond'
+       (forward-word 1)))              ; end of 'cond'
 
       (setq first nil))
 
     (if found
-        t
+       t
       (if noerror
-          nil
-        (error "No matching end")))
+         nil
+       (error "No matching end")))
     ))
 
 
 (defun ada-search-ignore-string-comment
   (search-re &optional backward limit paramlists search-func)
   "Regexp-search for SEARCH-RE, ignoring comments, strings.
-If PARAMLISTS is nil, ignore parameter lists.  Returns a cons cell of
-begin and end of match data or nil, if not found.
-The search is done using SEARCH-FUNC, which should search backward if
-BACKWARD is non-nil, forward otherwise.  SEARCH-FUNC can be optimized
-in case we are searching for a constant string.
+Returns a cons cell of begin and end of match data or nil, if not found.
+If BACKWARD is non-nil, search backward; search forward otherwise.
 The search stops at pos LIMIT.
+If PARAMLISTS is nil, ignore parameter lists.
+The search is done using SEARCH-FUNC. SEARCH-FUNC can be optimized
+in case we are searching for a constant string.
 Point is moved at the beginning of the SEARCH-RE."
   (let (found
-        begin
-        end
-        parse-result
-        (previous-syntax-table (syntax-table)))
+       begin
+       end
+       parse-result
+       (previous-syntax-table (syntax-table)))
 
+    ;; FIXME: need to pass BACKWARD to search-func!
     (unless search-func
       (setq search-func (if backward 're-search-backward 're-search-forward)))
 
@@ -3990,68 +4060,68 @@ Point is moved at the beginning of the SEARCH-RE."
     ;;
     (set-syntax-table ada-mode-symbol-syntax-table)
     (while (and (not found)
-                (or (not limit)
-                    (or (and backward (<= limit (point)))
-                        (>= limit (point))))
-                (funcall search-func search-re limit 1))
+               (or (not limit)
+                   (or (and backward (<= limit (point)))
+                       (>= limit (point))))
+               (funcall search-func search-re limit 1))
       (setq begin (match-beginning 0))
       (setq end (match-end 0))
 
       (setq parse-result (parse-partial-sexp
-                          (save-excursion (beginning-of-line) (point))
-                          (point)))
+                         (save-excursion (beginning-of-line) (point))
+                         (point)))
 
       (cond
        ;;
        ;; If inside a string, skip it (and the following comments)
        ;;
        ((ada-in-string-p parse-result)
-        (if (featurep 'xemacs)
-            (search-backward "\"" nil t)
-          (goto-char (nth 8 parse-result)))
-        (unless backward (forward-sexp 1)))
+       (if (featurep 'xemacs)
+           (search-backward "\"" nil t)
+         (goto-char (nth 8 parse-result)))
+       (unless backward (forward-sexp 1)))
        ;;
        ;; If inside a comment, skip it (and the following comments)
        ;; There is a special code for comments at the end of the file
        ;;
        ((ada-in-comment-p parse-result)
-        (if (featurep 'xemacs)
-            (progn
-              (forward-line 1)
-              (beginning-of-line)
-              (forward-comment -1))
-          (goto-char (nth 8 parse-result)))
-        (unless backward
-          ;;  at the end of the file, it is not possible to skip a comment
-          ;;  so we just go at the end of the line
-          (if (forward-comment 1)
-              (progn
-                (forward-comment 1000)
-                (beginning-of-line))
-            (end-of-line))))
+       (if (featurep 'xemacs)
+           (progn
+             (forward-line 1)
+             (beginning-of-line)
+             (forward-comment -1))
+         (goto-char (nth 8 parse-result)))
+       (unless backward
+         ;;  at the end of the file, it is not possible to skip a comment
+         ;;  so we just go at the end of the line
+         (if (forward-comment 1)
+             (progn
+               (forward-comment 1000)
+               (beginning-of-line))
+           (end-of-line))))
        ;;
        ;; directly in front of a comment => skip it, if searching forward
        ;;
        ((and (= (char-after begin) ?-) (= (char-after (1+ begin)) ?-))
-        (unless backward (progn (forward-char -1) (forward-comment 1000))))
+       (unless backward (progn (forward-char -1) (forward-comment 1000))))
 
        ;;
        ;; found a parameter-list but should ignore it => skip it
        ;;
        ((and (not paramlists) (ada-in-paramlist-p))
-        (if backward
-            (search-backward "(" nil t)
-          (search-forward ")" nil t)))
+       (if backward
+           (search-backward "(" nil t)
+         (search-forward ")" nil t)))
        ;;
        ;; found what we were looking for
        ;;
        (t
-        (setq found t))))               ; end of loop
+       (setq found t))))               ; end of loop
 
     (set-syntax-table previous-syntax-table)
 
     (if found
-        (cons begin end)
+       (cons begin end)
       nil)))
 
 ;; -------------------------------------------------------
@@ -4063,26 +4133,26 @@ Point is moved at the beginning of the SEARCH-RE."
 Assumes point to be at the end of a statement."
   (or (ada-in-paramlist-p)
       (save-excursion
-        (ada-goto-matching-decl-start t))))
+       (ada-goto-matching-decl-start t))))
 
 
 (defun ada-looking-at-semi-or ()
   "Return t if looking at an 'or' following a semicolon."
   (save-excursion
     (and (looking-at "\\<or\\>")
-         (progn
-           (forward-word 1)
-           (ada-goto-stmt-start)
-           (looking-at "\\<or\\>")))))
+        (progn
+          (forward-word 1)
+          (ada-goto-stmt-start)
+          (looking-at "\\<or\\>")))))
 
 
 (defun ada-looking-at-semi-private ()
   "Return t if looking at the start of a private section in a package.
-Returns nil if the private is part of the package name, as in
+Return nil if the private is part of the package name, as in
 'private package A is...' (this can only happen at top level)."
   (save-excursion
     (and (looking-at "\\<private\\>")
-         (not (looking-at "\\<private[ \t]*\\(package\\|generic\\)"))
+        (not (looking-at "\\<private[ \t]*\\(package\\|generic\\)"))
 
         ;;  Make sure this is the start of a private section (ie after
         ;;  a semicolon or just after the package declaration, but not
@@ -4113,8 +4183,8 @@ Returns nil if the private is part of the package name, as in
      (progn
        (skip-chars-backward " \t\n")
        (if (= (char-before) ?\")
-           (backward-char 3)
-         (backward-word 1))
+          (backward-char 3)
+        (backward-word 1))
        t)
 
      ;; and now over the second one
@@ -4131,17 +4201,17 @@ Returns nil if the private is part of the package name, as in
      ;; right keyword two words before parenthesis ?
      ;; Type is in this list because of discriminants
      (looking-at (eval-when-compile
-                   (concat "\\<\\("
-                           "procedure\\|function\\|body\\|"
-                           "task\\|entry\\|accept\\|"
-                           "access[ \t]+procedure\\|"
-                           "access[ \t]+function\\|"
-                           "pragma\\|"
-                           "type\\)\\>"))))))
+                  (concat "\\<\\("
+                          "procedure\\|function\\|body\\|"
+                          "task\\|entry\\|accept\\|"
+                          "access[ \t]+procedure\\|"
+                          "access[ \t]+function\\|"
+                          "pragma\\|"
+                          "type\\)\\>"))))))
 
 (defun ada-search-ignore-complex-boolean (regexp backwardp)
-  "Like `ada-search-ignore-string-comment', except that it also ignores
-boolean expressions 'and then' and 'or else'."
+  "Search for REGEXP, ignoring comments, strings, 'and then', 'or else'.
+If BACKWARDP is non-nil, search backward; search forward otherwise."
   (let (result)
   (while (and (setq result (ada-search-ignore-string-comment regexp backwardp))
              (save-excursion (forward-word -1)
@@ -4149,19 +4219,20 @@ boolean expressions 'and then' and 'or else'."
   result))
 
 (defun ada-in-open-paren-p ()
-  "Return the position of the first non-ws behind the last unclosed
+  "Non-nil if in an open parenthesis.
+Return value is the position of the first non-ws behind the last unclosed
 parenthesis, or nil."
   (save-excursion
     (let ((parse (parse-partial-sexp
-                  (point)
-                  (or (car (ada-search-ignore-complex-boolean
-                            "\\<\\(;\\|is\\|then\\|loop\\|begin\\|else\\)\\>"
-                            t))
-                      (point-min)))))
+                 (point)
+                 (or (car (ada-search-ignore-complex-boolean
+                           "\\<\\(;\\|is\\|then\\|loop\\|begin\\|else\\)\\>"
+                           t))
+                     (point-min)))))
 
       (if (nth 1 parse)
-          (progn
-            (goto-char (1+ (nth 1 parse)))
+         (progn
+           (goto-char (1+ (nth 1 parse)))
 
            ;;  Skip blanks, if they are not followed by a comment
            ;;  See:
@@ -4172,9 +4243,9 @@ parenthesis, or nil."
 
            (if (or (not ada-indent-handle-comment-special)
                    (not (looking-at "[ \t]+--")))
-               (skip-chars-forward " \t"))
+               (skip-chars-forward " \t"))
 
-            (point))))))
+           (point))))))
 
 \f
 ;; -----------------------------------------------------------
@@ -4187,20 +4258,21 @@ In Transient Mark mode, if the mark is active, operate on the contents
 of the region.  Otherwise, operate only on the current line."
   (interactive)
   (cond ((eq ada-tab-policy 'indent-rigidly) (ada-tab-hard))
-        ((eq ada-tab-policy 'indent-auto)
+       ((eq ada-tab-policy 'indent-auto)
         (if (ada-region-selected)
-             (ada-indent-region (region-beginning) (region-end))
-           (ada-indent-current)))
-        ((eq ada-tab-policy 'always-tab) (error "Not implemented"))
-        ))
+            (ada-indent-region (region-beginning) (region-end))
+          (ada-indent-current)))
+       ((eq ada-tab-policy 'always-tab) (error "Not implemented"))
+       ))
 
 (defun ada-untab (arg)
   "Delete leading indenting according to `ada-tab-policy'."
+  ;; FIXME: ARG is ignored
   (interactive "P")
   (cond ((eq ada-tab-policy 'indent-rigidly) (ada-untab-hard))
-        ((eq ada-tab-policy 'indent-auto) (error "Not implemented"))
-        ((eq ada-tab-policy 'always-tab) (error "Not implemented"))
-        ))
+       ((eq ada-tab-policy 'indent-auto) (error "Not implemented"))
+       ((eq ada-tab-policy 'always-tab) (error "Not implemented"))
+       ))
 
 (defun ada-indent-current-function ()
   "Ada mode version of the `indent-line-function'."
@@ -4209,7 +4281,7 @@ of the region.  Otherwise, operate only on the current line."
     (beginning-of-line)
     (ada-tab)
     (if (< (point) starting-point)
-        (goto-char starting-point))
+       (goto-char starting-point))
     (set-marker starting-point nil)
     ))
 
@@ -4225,9 +4297,9 @@ of the region.  Otherwise, operate only on the current line."
 (defun ada-untab-hard ()
   "Indent current line to previous tab stop."
   (interactive)
-  (let  ((bol (save-excursion (progn (beginning-of-line) (point))))
-         (eol (save-excursion (progn (end-of-line) (point)))))
-    (indent-rigidly bol eol  (- 0 ada-indent))))
+  (let ((bol (save-excursion (progn (beginning-of-line) (point))))
+       (eol (save-excursion (progn (end-of-line) (point)))))
+    (indent-rigidly bol eol (- 0 ada-indent))))
 
 
 \f
@@ -4237,16 +4309,16 @@ of the region.  Otherwise, operate only on the current line."
 
 ;;  Not needed any more for Emacs 21.2, but still needed for backward
 ;;  compatibility
-(defun ada-remove-trailing-spaces  ()
+(defun ada-remove-trailing-spaces ()
   "Remove trailing spaces in the whole buffer."
   (interactive)
   (save-match-data
     (save-excursion
       (save-restriction
-        (widen)
-        (goto-char (point-min))
-        (while (re-search-forward "[ \t]+$" (point-max) t)
-          (replace-match "" nil nil))))))
+       (widen)
+       (goto-char (point-min))
+       (while (re-search-forward "[ \t]+$" (point-max) t)
+         (replace-match "" nil nil))))))
 
 (defun ada-gnat-style ()
   "Clean up comments, `(' and `,' for GNAT style checking switch."
@@ -4328,40 +4400,40 @@ of the region.  Otherwise, operate only on the current line."
   "Move point to the matching start of the current Ada structure."
   (interactive)
   (let ((pos (point))
-        (previous-syntax-table (syntax-table)))
+       (previous-syntax-table (syntax-table)))
     (unwind-protect
-        (progn
-          (set-syntax-table ada-mode-symbol-syntax-table)
-
-          (save-excursion
-            ;;
-            ;; do nothing if in string or comment or not on 'end ...;'
-            ;;            or if an error occurs during processing
-            ;;
-            (or
-             (ada-in-string-or-comment-p)
-             (and (progn
-                    (or (looking-at "[ \t]*\\<end\\>")
-                        (backward-word 1))
-                    (or (looking-at "[ \t]*\\<end\\>")
-                        (backward-word 1))
-                    (or (looking-at "[ \t]*\\<end\\>")
-                        (error "Not on end ...;")))
-                  (ada-goto-matching-start 1)
-                  (setq pos (point))
-
-                  ;;
-                  ;; on 'begin' => go on, according to user option
-                  ;;
-                  ada-move-to-declaration
-                  (looking-at "\\<begin\\>")
-                  (ada-goto-matching-decl-start)
-                  (setq pos (point))))
-
-            )                           ; end of save-excursion
-
-          ;; now really move to the found position
-          (goto-char pos))
+       (progn
+         (set-syntax-table ada-mode-symbol-syntax-table)
+
+         (save-excursion
+           ;;
+           ;; do nothing if in string or comment or not on 'end ...;'
+           ;;            or if an error occurs during processing
+           ;;
+           (or
+            (ada-in-string-or-comment-p)
+            (and (progn
+                   (or (looking-at "[ \t]*\\<end\\>")
+                       (backward-word 1))
+                   (or (looking-at "[ \t]*\\<end\\>")
+                       (backward-word 1))
+                   (or (looking-at "[ \t]*\\<end\\>")
+                       (error "Not on end ...;")))
+                 (ada-goto-matching-start 1)
+                 (setq pos (point))
+
+                 ;;
+                 ;; on 'begin' => go on, according to user option
+                 ;;
+                 ada-move-to-declaration
+                 (looking-at "\\<begin\\>")
+                 (ada-goto-matching-decl-start)
+                 (setq pos (point))))
+
+           )                           ; end of save-excursion
+
+         ;; now really move to the found position
+         (goto-char pos))
 
       ;; restore syntax-table
       (set-syntax-table previous-syntax-table))))
@@ -4372,16 +4444,16 @@ Moves to 'begin' if in a declarative part."
   (interactive)
   (let ((pos (point))
        decl-start
-        (previous-syntax-table (syntax-table)))
+       (previous-syntax-table (syntax-table)))
     (unwind-protect
-        (progn
-          (set-syntax-table ada-mode-symbol-syntax-table)
+       (progn
+         (set-syntax-table ada-mode-symbol-syntax-table)
 
-          (save-excursion
+         (save-excursion
 
-            (cond
-             ;; Go to the beginning of the current word, and check if we are
-             ;; directly on 'begin'
+           (cond
+            ;; Go to the beginning of the current word, and check if we are
+            ;; directly on 'begin'
             ((save-excursion
                (skip-syntax-backward "w")
                (looking-at "\\<begin\\>"))
@@ -4395,31 +4467,31 @@ Moves to 'begin' if in a declarative part."
             ((save-excursion
                (and (skip-syntax-backward "w")
                     (looking-at "\\<function\\>\\|\\<procedure\\>" )
-                    (ada-search-ignore-string-comment "is\\|;")
-                    (not (= (char-before) ?\;))
-                    ))
+                    (ada-search-ignore-string-comment "is\\|;")
+                    (not (= (char-before) ?\;))
+                    ))
              (skip-syntax-backward "w")
              (ada-goto-matching-end 0 t))
 
-             ;; on first line of task declaration
-             ((save-excursion
-                (and (ada-goto-stmt-start)
-                     (looking-at "\\<task\\>" )
-                     (forward-word 1)
-                     (ada-goto-next-non-ws)
-                     (looking-at "\\<body\\>")))
-              (ada-search-ignore-string-comment "begin" nil nil nil
-                                                'word-search-forward))
-             ;; accept block start
-             ((save-excursion
-                (and (ada-goto-stmt-start)
-                     (looking-at "\\<accept\\>" )))
-              (ada-goto-matching-end 0))
-             ;; package start
-             ((save-excursion
+            ;; on first line of task declaration
+            ((save-excursion
+               (and (ada-goto-stmt-start)
+                    (looking-at "\\<task\\>" )
+                    (forward-word 1)
+                    (ada-goto-next-non-ws)
+                    (looking-at "\\<body\\>")))
+             (ada-search-ignore-string-comment "begin" nil nil nil
+                                               'word-search-forward))
+            ;; accept block start
+            ((save-excursion
+               (and (ada-goto-stmt-start)
+                    (looking-at "\\<accept\\>" )))
+             (ada-goto-matching-end 0))
+            ;; package start
+            ((save-excursion
                (setq decl-start (and (ada-goto-matching-decl-start t) (point)))
-                (and decl-start (looking-at "\\<package\\>")))
-              (ada-goto-matching-end 1))
+               (and decl-start (looking-at "\\<package\\>")))
+             (ada-goto-matching-end 1))
 
             ;;  On a "declare" keyword
             ((save-excursion
@@ -4427,19 +4499,19 @@ Moves to 'begin' if in a declarative part."
                (looking-at "\\<declare\\>"))
              (ada-goto-matching-end 0 t))
 
-             ;; inside a 'begin' ... 'end' block
-             (decl-start
+            ;; inside a 'begin' ... 'end' block
+            (decl-start
              (goto-char decl-start)
              (ada-goto-matching-end 0 t))
 
-             ;; (hopefully ;-) everything else
-             (t
-              (ada-goto-matching-end 1)))
-            (setq pos (point))
-            )
+            ;; (hopefully ;-) everything else
+            (t
+             (ada-goto-matching-end 1)))
+           (setq pos (point))
+           )
 
-          ;; now really move to the position found
-          (goto-char pos))
+         ;; now really move to the position found
+         (goto-char pos))
 
       ;; restore syntax-table
       (set-syntax-table previous-syntax-table))))
@@ -4449,7 +4521,7 @@ Moves to 'begin' if in a declarative part."
   (interactive)
   (end-of-line)
   (if (re-search-forward ada-procedure-start-regexp nil t)
-      (goto-char (match-beginning 2))
+      (goto-char (match-beginning 4))
     (error "No more functions/procedures/tasks")))
 
 (defun ada-previous-procedure ()
@@ -4457,7 +4529,7 @@ Moves to 'begin' if in a declarative part."
   (interactive)
   (beginning-of-line)
   (if (re-search-backward ada-procedure-start-regexp nil t)
-      (goto-char (match-beginning 2))
+      (goto-char (match-beginning 4))
     (error "No more functions/procedures/tasks")))
 
 (defun ada-next-package ()
@@ -4531,8 +4603,8 @@ Moves to 'begin' if in a declarative part."
   ;; and activated only if the right compiler is used
   (if (featurep 'xemacs)
       (progn
-        (define-key ada-mode-map '(shift button3) 'ada-point-and-xref)
-        (define-key ada-mode-map '(control tab) 'ada-complete-identifier))
+       (define-key ada-mode-map '(shift button3) 'ada-point-and-xref)
+       (define-key ada-mode-map '(control tab) 'ada-complete-identifier))
     (define-key ada-mode-map [C-tab] 'ada-complete-identifier)
     (define-key ada-mode-map [S-mouse-3] 'ada-point-and-xref))
 
@@ -4544,6 +4616,7 @@ Moves to 'begin' if in a declarative part."
   (define-key ada-mode-map "\C-cc"     'ada-change-prj)
   (define-key ada-mode-map "\C-cd"     'ada-set-default-project-file)
   (define-key ada-mode-map "\C-cg"     'ada-gdb-application)
+  (define-key ada-mode-map "\C-c\C-m"  'ada-set-main-compile-application)
   (define-key ada-mode-map "\C-cr"     'ada-run-application)
   (define-key ada-mode-map "\C-c\C-o"  'ada-goto-parent)
   (define-key ada-mode-map "\C-c\C-r"  'ada-find-references)
@@ -4601,8 +4674,7 @@ Moves to 'begin' if in a declarative part."
               (eq ada-which-compiler 'gnat)]
              ["Gdb Documentation"      (info "gdb")
               (eq ada-which-compiler 'gnat)]
-             ["Ada95 Reference Manual" (info "arm95")
-              (eq ada-which-compiler 'gnat)])
+             ["Ada95 Reference Manual" (info "arm95") t])
             ("Options"  :included (eq major-mode 'ada-mode)
              ["Auto Casing" (setq ada-auto-case (not ada-auto-case))
               :style toggle :selected ada-auto-case]
@@ -4627,15 +4699,16 @@ Moves to 'begin' if in a declarative part."
               :included (string-match "gvd" ada-prj-default-debugger)])
             ["Customize"     (customize-group 'ada)
              :included (fboundp 'customize-group)]
-            ["Check file"    ada-check-current   (eq ada-which-compiler 'gnat)]
-            ["Compile file"  ada-compile-current (eq ada-which-compiler 'gnat)]
-            ["Build"         ada-compile-application
-             (eq ada-which-compiler 'gnat)]
+            ["Check file"    ada-check-current   t]
+            ["Compile file"  ada-compile-current t]
+            ["Set main and Build" ada-set-main-compile-application t]
+            ["Show main" ada-show-current-main t]
+            ["Build"         ada-compile-application t]
             ["Run"           ada-run-application     t]
             ["Debug"         ada-gdb-application (eq ada-which-compiler 'gnat)]
             ["------"        nil nil]
             ("Project"
-              :included (eq ada-which-compiler 'gnat)
+             ["Show project" ada-show-current-project t]
              ["Load..."      ada-set-default-project-file t]
              ["New..."       ada-prj-new                  t]
              ["Edit..."      ada-prj-edit                 t])
@@ -4698,7 +4771,7 @@ Moves to 'begin' if in a declarative part."
              ["----"                        nil                          nil]
              ["Make body for subprogram"    ada-make-subprogram-body     t]
              ["-----"                       nil                          nil]
-              ["Narrow to subprogram"        ada-narrow-to-defun          t])
+             ["Narrow to subprogram"        ada-narrow-to-defun          t])
             ("Templates"
              :included  (eq major-mode 'ada-mode)
              ["Header"          ada-header          t]
@@ -4761,18 +4834,19 @@ Moves to 'begin' if in a declarative part."
 
 (defadvice comment-region (before ada-uncomment-anywhere disable)
   (if (and arg
-           (listp arg)  ;;  a prefix with \C-u is of the form '(4), whereas
-                      ;;  \C-u 2  sets arg to '2'  (fixed by S.Leake)
-           (string= mode-name "Ada"))
+          (listp arg)  ;;  a prefix with \C-u is of the form '(4), whereas
+                      ;;  \C-u 2  sets arg to '2'  (fixed by S.Leake)
+          (string= mode-name "Ada"))
       (save-excursion
-        (let ((cs (concat "^[ \t]*" (regexp-quote comment-start))))
-          (goto-char beg)
-          (while (re-search-forward cs end t)
-            (replace-match comment-start))
-          ))))
+       (let ((cs (concat "^[ \t]*" (regexp-quote comment-start))))
+         (goto-char beg)
+         (while (re-search-forward cs end t)
+           (replace-match comment-start))
+         ))))
 
 (defun ada-uncomment-region (beg end &optional arg)
-  "Delete `comment-start' at the beginning of a line in the region."
+  "Uncomment region BEG .. END.
+ARG gives number of comment characters."
   (interactive "r\nP")
 
   ;;  This advice is not needed anymore with Emacs21. However, for older
@@ -4806,18 +4880,18 @@ The paragraph is indented on the first line."
 
   ;; check if inside comment or just in front a comment
   (if (and (not (ada-in-comment-p))
-           (not (looking-at "[ \t]*--")))
+          (not (looking-at "[ \t]*--")))
       (error "Not inside comment"))
 
   (let* (indent from to
-         (opos (point-marker))
+        (opos (point-marker))
 
-         ;; Sets this variable to nil, otherwise it prevents
-         ;; fill-region-as-paragraph to work on Emacs <= 20.2
-         (parse-sexp-lookup-properties nil)
+        ;; Sets this variable to nil, otherwise it prevents
+        ;; fill-region-as-paragraph to work on Emacs <= 20.2
+        (parse-sexp-lookup-properties nil)
 
-         fill-prefix
-         (fill-column (current-fill-column)))
+        fill-prefix
+        (fill-column (current-fill-column)))
 
     ;;  Find end of paragraph
     (back-to-indentation)
@@ -4864,32 +4938,32 @@ The paragraph is indented on the first line."
     (setq fill-prefix ada-fill-comment-prefix)
     (set-left-margin from to indent)
     (if postfix
-        (setq fill-column (- fill-column (length ada-fill-comment-postfix))))
+       (setq fill-column (- fill-column (length ada-fill-comment-postfix))))
 
     (fill-region-as-paragraph from to justify)
 
     ;;  Add the postfixes if required
     (if postfix
-        (save-restriction
-          (goto-char from)
-          (narrow-to-region from to)
-          (while (not (eobp))
-            (end-of-line)
-            (insert-char ?  (- fill-column (current-column)))
-            (insert ada-fill-comment-postfix)
-            (forward-line))
-          ))
+       (save-restriction
+         (goto-char from)
+         (narrow-to-region from to)
+         (while (not (eobp))
+           (end-of-line)
+           (insert-char ?  (- fill-column (current-column)))
+           (insert ada-fill-comment-postfix)
+           (forward-line))
+         ))
 
     ;;  In Emacs <= 20.2 and XEmacs <=20.4, there is a bug, and a newline is
     ;;  inserted at the end. Delete it
     (if (or (featurep 'xemacs)
-            (<= emacs-major-version 19)
-            (and (= emacs-major-version 20)
-                 (<= emacs-minor-version 2)))
-        (progn
-          (goto-char to)
-          (end-of-line)
-          (delete-char 1)))
+           (<= emacs-major-version 19)
+           (and (= emacs-major-version 20)
+                (<= emacs-minor-version 2)))
+       (progn
+         (goto-char to)
+         (end-of-line)
+         (delete-char 1)))
 
     (goto-char opos)))
 
@@ -4910,7 +4984,8 @@ The paragraph is indented on the first line."
 ;; Overriden when we work with GNAT, to use gnatkrunch
 (defun ada-make-filename-from-adaname (adaname)
   "Determine the filename in which ADANAME is found.
-This is a generic function, independent from any compiler."
+This matches the GNAT default naming convention, except for
+pre-defined units."
   (while (string-match "\\." adaname)
     (setq adaname (replace-match "-" t t adaname)))
   (downcase adaname)
@@ -4924,7 +4999,7 @@ or the spec otherwise."
   (let ((is-spec nil)
        (is-body nil)
        (suffixes ada-spec-suffixes)
-       (name  (buffer-file-name)))
+       (name (buffer-file-name)))
 
     ;;  Guess whether we have a spec or a body, and get the basename of the
     ;;  file. Since the extension may not start with '.', we can not use
@@ -4977,18 +5052,19 @@ or the spec otherwise."
 
 (defun ada-which-function-are-we-in ()
   "Return the name of the function whose definition/declaration point is in.
-Redefines the function `ff-which-function-are-we-in'."
+Used in `ff-pre-load-hook'."
   (setq ff-function-name nil)
   (save-excursion
     (end-of-line);;  make sure we get the complete name
-    (if (or (re-search-backward ada-procedure-start-regexp nil t)
-            (re-search-backward ada-package-start-regexp nil t))
-        (setq ff-function-name (match-string 0)))
+    (or (if (re-search-backward ada-procedure-start-regexp nil t)
+            (setq ff-function-name (match-string 5)))
+        (if (re-search-backward ada-package-start-regexp nil t)
+            (setq ff-function-name (match-string 4))))
     ))
 
 
 (defvar ada-last-which-function-line -1
-  "Last on which `ada-which-function' was called.")
+  "Last line on which `ada-which-function' was called.")
 (defvar ada-last-which-function-subprog 0
   "Last subprogram name returned by `ada-which-function'.")
 (make-variable-buffer-local 'ada-last-which-function-subprog)
@@ -5002,18 +5078,18 @@ standard Emacs function `which-function' does not.
 Since the search can be long, the results are cached."
 
   (let ((line (count-lines 1 (point)))
-        (pos (point))
-        end-pos
-        func-name indent
-        found)
+       (pos (point))
+       end-pos
+       func-name indent
+       found)
 
     ;;  If this is the same line as before, simply return the same result
     (if (= line ada-last-which-function-line)
-        ada-last-which-function-subprog
+       ada-last-which-function-subprog
 
       (save-excursion
-        ;; In case the current line is also the beginning of the body
-        (end-of-line)
+       ;; In case the current line is also the beginning of the body
+       (end-of-line)
 
        ;;  Are we looking at "function Foo\n    (paramlist)"
        (skip-chars-forward " \t\n(")
@@ -5029,39 +5105,39 @@ Since the search can be long, the results are cached."
              (skip-chars-forward " \t\n")
              (skip-chars-forward "a-zA-Z0-9_'")))
 
-        ;; Can't simply do forward-word, in case the "is" is not on the
-        ;; same line as the closing parenthesis
-        (skip-chars-forward "is \t\n")
+       ;; Can't simply do forward-word, in case the "is" is not on the
+       ;; same line as the closing parenthesis
+       (skip-chars-forward "is \t\n")
 
-        ;; No look for the closest subprogram body that has not ended yet.
-        ;; Not that we expect all the bodies to be finished by "end <name>",
-        ;; or a simple "end;" indented in the same column as the start of
+       ;; No look for the closest subprogram body that has not ended yet.
+       ;; Not that we expect all the bodies to be finished by "end <name>",
+       ;; or a simple "end;" indented in the same column as the start of
        ;; the subprogram. The goal is to be as efficient as possible.
 
-        (while (and (not found)
-                    (re-search-backward ada-imenu-subprogram-menu-re nil t))
+       (while (and (not found)
+                   (re-search-backward ada-imenu-subprogram-menu-re nil t))
 
          ;; Get the function name, but not the properties, or this changes
          ;; the face in the modeline on Emacs 21
-          (setq func-name (match-string-no-properties 2))
-          (if (and (not (ada-in-comment-p))
-                   (not (save-excursion
-                          (goto-char (match-end 0))
-                          (looking-at "[ \t\n]*new"))))
-              (save-excursion
+         (setq func-name (match-string-no-properties 2))
+         (if (and (not (ada-in-comment-p))
+                  (not (save-excursion
+                         (goto-char (match-end 0))
+                         (looking-at "[ \t\n]*new"))))
+             (save-excursion
                (back-to-indentation)
                (setq indent (current-column))
-                (if (ada-search-ignore-string-comment
-                     (concat "end[ \t]+" func-name "[ \t]*;\\|^"
+               (if (ada-search-ignore-string-comment
+                    (concat "end[ \t]+" func-name "[ \t]*;\\|^"
                             (make-string indent ? ) "end;"))
-                    (setq end-pos (point))
-                  (setq end-pos (point-max)))
-                (if (>= end-pos pos)
-                    (setq found func-name))))
-          )
-        (setq ada-last-which-function-line line
-              ada-last-which-function-subprog found)
-        found))))
+                   (setq end-pos (point))
+                 (setq end-pos (point-max)))
+               (if (>= end-pos pos)
+                   (setq found func-name))))
+         )
+       (setq ada-last-which-function-line line
+             ada-last-which-function-subprog found)
+       found))))
 
 (defun ada-ff-other-window ()
   "Find other file in other window using `ff-find-other-file'."
@@ -5070,19 +5146,18 @@ Since the search can be long, the results are cached."
        (ff-find-other-file t)))
 
 (defun ada-set-point-accordingly ()
-  "Move to the function declaration that was set by
-`ff-which-function-are-we-in'."
+  "Move to the function declaration that was set by `ff-which-function-are-we-in'."
   (if ff-function-name
       (progn
-        (goto-char (point-min))
-        (unless (ada-search-ignore-string-comment
-                 (concat ff-function-name "\\b") nil)
-          (goto-char (point-min))))))
+       (goto-char (point-min))
+       (unless (ada-search-ignore-string-comment
+                (concat ff-function-name "\\b") nil)
+         (goto-char (point-min))))))
 
 (defun ada-get-body-name (&optional spec-name)
   "Return the file name for the body of SPEC-NAME.
 If SPEC-NAME is nil, return the body for the current package.
-Returns nil if no body was found."
+Return nil if no body was found."
   (interactive)
 
   (unless spec-name (setq spec-name (buffer-file-name)))
@@ -5102,15 +5177,15 @@ Returns nil if no body was found."
   ;; If find-file.el was available, use its functions
   (if (fboundp 'ff-get-file-name)
       (ff-get-file-name ada-search-directories-internal
-                        (ada-make-filename-from-adaname
-                         (file-name-nondirectory
-                          (file-name-sans-extension spec-name)))
-                        ada-body-suffixes)
+                       (ada-make-filename-from-adaname
+                        (file-name-nondirectory
+                         (file-name-sans-extension spec-name)))
+                       ada-body-suffixes)
     ;; Else emulate it very simply
     (concat (ada-make-filename-from-adaname
-             (file-name-nondirectory
-              (file-name-sans-extension spec-name)))
-            ".adb")))
+            (file-name-nondirectory
+             (file-name-sans-extension spec-name)))
+           ".adb")))
 
 \f
 ;; ---------------------------------------------------
@@ -5133,8 +5208,7 @@ Returns nil if no body was found."
   ;; This sets the properties of the characters, so that ada-in-string-p
   ;; correctly handles '"' too...
   '(("[^a-zA-Z0-9)]\\('\\)[^'\n]\\('\\)" (1 (7 . ?')) (2 (7 . ?')))
-    ("^[ \t]*\\(#\\(if\\|else\\|elsif\\|end\\)\\)" (1 (11 . ?\n)))
-    ))
+    ("^[ \t]*\\(#\\(if\\|else\\|elsif\\|end\\)\\)" (1 (11 . ?\n)))))
 
 (defvar ada-font-lock-keywords
   (eval-when-compile
@@ -5150,44 +5224,44 @@ Returns nil if no body was found."
      ;; accept, entry, function, package (body), protected (body|type),
      ;; pragma, procedure, task (body) plus name.
      (list (concat
-            "\\<\\("
-            "accept\\|"
-            "entry\\|"
-            "function\\|"
-            "package[ \t]+body\\|"
-            "package\\|"
-            "pragma\\|"
-            "procedure\\|"
-            "protected[ \t]+body\\|"
-            "protected[ \t]+type\\|"
-            "protected\\|"
-            "task[ \t]+body\\|"
-            "task[ \t]+type\\|"
-            "task"
-            "\\)\\>[ \t]*"
-            "\\(\\sw+\\(\\.\\sw*\\)*\\)?")
-           '(1 font-lock-keyword-face) '(2 font-lock-function-name-face nil t))
+           "\\<\\("
+           "accept\\|"
+           "entry\\|"
+           "function\\|"
+           "package[ \t]+body\\|"
+           "package\\|"
+           "pragma\\|"
+           "procedure\\|"
+           "protected[ \t]+body\\|"
+           "protected[ \t]+type\\|"
+           "protected\\|"
+           "task[ \t]+body\\|"
+           "task[ \t]+type\\|"
+           "task"
+           "\\)\\>[ \t]*"
+           "\\(\\sw+\\(\\.\\sw*\\)*\\)?")
+          '(1 font-lock-keyword-face) '(2 font-lock-function-name-face nil t))
      ;;
      ;; Optional keywords followed by a type name.
      (list (concat                      ; ":[ \t]*"
-            "\\<\\(access[ \t]+all\\|access[ \t]+constant\\|access\\|constant\\|in[ \t]+reverse\\|\\|in[ \t]+out\\|in\\|out\\)\\>"
-            "[ \t]*"
-            "\\(\\sw+\\(\\.\\sw*\\)*\\)?")
-           '(1 font-lock-keyword-face nil t) '(2 font-lock-type-face nil t))
+           "\\<\\(access[ \t]+all\\|access[ \t]+constant\\|access\\|constant\\|in[ \t]+reverse\\|\\|in[ \t]+out\\|in\\|out\\)\\>"
+           "[ \t]*"
+           "\\(\\sw+\\(\\.\\sw*\\)*\\)?")
+          '(1 font-lock-keyword-face nil t) '(2 font-lock-type-face nil t))
 
      ;;
      ;; Main keywords, except those treated specially below.
      (concat "\\<"
-             (regexp-opt
-              '("abort" "abs" "abstract" "accept" "access" "aliased" "all"
-                "and" "array" "at" "begin" "case" "declare" "delay" "delta"
-                "digits" "do" "else" "elsif" "entry" "exception" "exit" "for"
-                "generic" "if" "in" "is" "limited" "loop" "mod" "not"
-                "null" "or" "others" "private" "protected" "raise"
-                "range" "record" "rem" "renames" "requeue" "return" "reverse"
-                "select" "separate" "tagged" "task" "terminate" "then" "until"
-                "when" "while" "with" "xor") t)
-             "\\>")
+            (regexp-opt
+             '("abort" "abs" "abstract" "accept" "access" "aliased" "all"
+               "and" "array" "at" "begin" "case" "declare" "delay" "delta"
+               "digits" "do" "else" "elsif" "entry" "exception" "exit" "for"
+               "generic" "if" "in" "interface" "is" "limited" "loop" "mod" "not"
+               "null" "or" "others" "overriding" "private" "protected" "raise"
+               "range" "record" "rem" "renames" "requeue" "return" "reverse"
+               "select" "separate" "synchronized" "tagged" "task" "terminate"
+                "then" "until" "when" "while" "with" "xor") t)
+            "\\>")
      ;;
      ;; Anything following end and not already fontified is a body name.
      '("\\<\\(end\\)\\>\\([ \t]+\\)?\\(\\(\\sw\\|[_.]\\)+\\)?"
@@ -5195,19 +5269,19 @@ Returns nil if no body was found."
      ;;
      ;; Keywords followed by a type or function name.
      (list (concat "\\<\\("
-                   "new\\|of\\|subtype\\|type"
-                   "\\)\\>[ \t]*\\(\\sw+\\(\\.\\sw*\\)*\\)?[ \t]*\\((\\)?")
-           '(1 font-lock-keyword-face)
-           '(2 (if (match-beginning 4)
-                   font-lock-function-name-face
-                 font-lock-type-face) nil t))
+                  "new\\|of\\|subtype\\|type"
+                  "\\)\\>[ \t]*\\(\\sw+\\(\\.\\sw*\\)*\\)?[ \t]*\\((\\)?")
+          '(1 font-lock-keyword-face)
+          '(2 (if (match-beginning 4)
+                  font-lock-function-name-face
+                font-lock-type-face) nil t))
      ;;
      ;; Keywords followed by a (comma separated list of) reference.
      ;; Note that font-lock only works on single lines, thus we can not
      ;; correctly highlight a with_clause that spans multiple lines.
      (list (concat "\\<\\(goto\\|raise\\|use\\|with\\)"
-                   "[ \t]+\\([a-zA-Z0-9_., \t]+\\)\\W")
-           '(1 font-lock-keyword-face) '(2 font-lock-reference-face nil t))
+                  "[ \t]+\\([a-zA-Z0-9_., \t]+\\)\\W")
+          '(1 font-lock-keyword-face) '(2 font-lock-reference-face nil t))
 
      ;;
      ;; Goto tags.
@@ -5243,7 +5317,7 @@ Returns nil if no body was found."
   "Make text outside current subprogram invisible.
 The subprogram visible is the one that contains or follow point.
 Optional ARG is ignored.
-Use `M-x widen' to go back to the full visibility for the buffer."
+Use \\[widen] to go back to the full visibility for the buffer."
 
   (interactive)
   (save-excursion
@@ -5253,8 +5327,8 @@ Use `M-x widen' to go back to the full visibility for the buffer."
       (ada-previous-procedure)
 
       (save-excursion
-        (beginning-of-line)
-        (setq end (point)))
+       (beginning-of-line)
+       (setq end (point)))
 
       (ada-move-to-end)
       (end-of-line)
@@ -5264,7 +5338,7 @@ Use `M-x widen' to go back to the full visibility for the buffer."
 
 ;; ---------------------------------------------------------
 ;;    Automatic generation of code
-;; The Ada-mode has a set of function to automatically generate a subprogram
+;; The Ada mode has a set of function to automatically generate a subprogram
 ;; or package body from its spec.
 ;; These function only use a primary and basic algorithm, this could use a
 ;; lot of improvement.
@@ -5280,7 +5354,7 @@ for `ada-procedure-start-regexp'."
   (let (func-found procname functype)
     (cond
      ((or (looking-at "^[ \t]*procedure")
-          (setq func-found (looking-at "^[ \t]*function")))
+         (setq func-found (looking-at "^[ \t]*function")))
       ;; treat it as a proc/func
       (forward-word 2)
       (forward-word -1)
@@ -5291,126 +5365,125 @@ for `ada-procedure-start-regexp'."
 
       ;; skip over parameterlist
       (unless (looking-at "[ \t\n]*\\(;\\|return\\)")
-        (forward-sexp))
+       (forward-sexp))
 
       ;; if function, skip over 'return' and result type.
       (if func-found
-          (progn
-            (forward-word 1)
-            (skip-chars-forward " \t\n")
-            (setq functype (buffer-substring (point)
-                                             (progn
-                                               (skip-chars-forward
-                                                "a-zA-Z0-9_\.")
-                                               (point))))))
+         (progn
+           (forward-word 1)
+           (skip-chars-forward " \t\n")
+           (setq functype (buffer-substring (point)
+                                            (progn
+                                              (skip-chars-forward
+                                               "a-zA-Z0-9_\.")
+                                              (point))))))
       ;; look for next non WS
       (cond
        ((looking-at "[ \t]*;")
-        (delete-region (match-beginning 0) (match-end 0));; delete the ';'
-        (ada-indent-newline-indent)
-        (insert "is")
-        (ada-indent-newline-indent)
-        (if func-found
-            (progn
-              (insert "Result : " functype ";")
-              (ada-indent-newline-indent)))
-        (insert "begin")
-        (ada-indent-newline-indent)
-        (if func-found
-            (insert "return Result;")
-          (insert "null;"))
-        (ada-indent-newline-indent)
-        (insert "end " procname ";")
-        (ada-indent-newline-indent)
-        )
+       (delete-region (match-beginning 0) (match-end 0));; delete the ';'
+       (ada-indent-newline-indent)
+       (insert "is")
+       (ada-indent-newline-indent)
+       (if func-found
+           (progn
+             (insert "Result : " functype ";")
+             (ada-indent-newline-indent)))
+       (insert "begin")
+       (ada-indent-newline-indent)
+       (if func-found
+           (insert "return Result;")
+         (insert "null;"))
+       (ada-indent-newline-indent)
+       (insert "end " procname ";")
+       (ada-indent-newline-indent)
+       )
        ;; else
        ((looking-at "[ \t\n]*is")
-        ;; do nothing
-        )
+       ;; do nothing
+       )
        ((looking-at "[ \t\n]*rename")
-        ;; do nothing
-        )
+       ;; do nothing
+       )
        (t
-        (message "unknown syntax"))))
+       (message "unknown syntax"))))
      (t
       (if (looking-at "^[ \t]*task")
-          (progn
-            (message "Task conversion is not yet implemented")
-            (forward-word 2)
-            (if (looking-at "[ \t]*;")
-                (forward-line)
-              (ada-move-to-end))
-            ))))))
+         (progn
+           (message "Task conversion is not yet implemented")
+           (forward-word 2)
+           (if (looking-at "[ \t]*;")
+               (forward-line)
+             (ada-move-to-end))
+           ))))))
 
 (defun ada-make-body ()
   "Create an Ada package body in the current buffer.
-The potential old buffer contents is deleted first, then we copy the
-spec buffer in here and modify it to make it a body.
-This function typically is to be hooked into `ff-file-created-hooks'."
-  (interactive)
+The spec must be the previously visited buffer.
+This function typically is to be hooked into `ff-file-created-hook'."
   (delete-region (point-min) (point-max))
-  (insert-buffer (car (cdr (buffer-list))))
+  (insert-buffer-substring (car (cdr (buffer-list))))
+  (goto-char (point-min))
   (ada-mode)
 
   (let (found ada-procedure-or-package-start-regexp)
     (if (setq found
-             (ada-search-ignore-string-comment ada-package-start-regexp nil))
-        (progn (goto-char (cdr found))
-               (insert " body")
-               )
+            (ada-search-ignore-string-comment ada-package-start-regexp nil))
+       (progn (goto-char (cdr found))
+              (insert " body")
+              )
       (error "No package"))
 
     (setq ada-procedure-or-package-start-regexp
-         (concat ada-procedure-start-regexp
-                 "\\|"
-                 ada-package-start-regexp))
+        (concat ada-procedure-start-regexp
+                "\\|"
+                ada-package-start-regexp))
 
     (while (setq found
-                (ada-search-ignore-string-comment
-                 ada-procedure-or-package-start-regexp nil))
+               (ada-search-ignore-string-comment
+                ada-procedure-or-package-start-regexp nil))
       (progn
-        (goto-char (car found))
-        (if (looking-at ada-package-start-regexp)
-            (progn (goto-char (cdr found))
-                   (insert " body"))
-          (ada-gen-treat-proc found))))))
+       (goto-char (car found))
+       (if (looking-at ada-package-start-regexp)
+           (progn (goto-char (cdr found))
+                  (insert " body"))
+         (ada-gen-treat-proc found))))))
 
 
 (defun ada-make-subprogram-body ()
-  "Make one dummy subprogram body from spec surrounding point."
+  "Create a dummy subprogram body in package body file from spec surrounding point."
   (interactive)
   (let* ((found (re-search-backward ada-procedure-start-regexp nil t))
-         (spec  (match-beginning 0))
-         body-file)
+        (spec  (match-beginning 0))
+        body-file)
     (if found
-        (progn
-          (goto-char spec)
-          (if (and (re-search-forward "(\\|;" nil t)
-                   (= (char-before) ?\())
-              (progn
-                (ada-search-ignore-string-comment ")" nil)
-                (ada-search-ignore-string-comment ";" nil)))
-          (setq spec (buffer-substring spec (point)))
-
-          ;; If find-file.el was available, use its functions
-          (setq body-file (ada-get-body-name))
-          (if body-file
-              (find-file body-file)
-            (error "No body found for the package.  Create it first"))
-
-          (save-restriction
-            (widen)
-            (goto-char (point-max))
-            (forward-comment -10000)
-            (re-search-backward "\\<end\\>" nil t)
-            ;;  Move to the beginning of the elaboration part, if any
-            (re-search-backward "^begin" nil t)
-            (newline)
-            (forward-char -1)
-            (insert spec)
-            (re-search-backward ada-procedure-start-regexp nil t)
-            (ada-gen-treat-proc (cons (match-beginning 0) (match-end 0)))
-            ))
+       (progn
+         (goto-char spec)
+         (if (and (re-search-forward "(\\|;" nil t)
+                  (= (char-before) ?\())
+             (progn
+               (ada-search-ignore-string-comment ")" nil)
+               (ada-search-ignore-string-comment ";" nil)))
+         (setq spec (buffer-substring spec (point)))
+
+         ;; If find-file.el was available, use its functions
+         (setq body-file (ada-get-body-name))
+         (if body-file
+             (find-file body-file)
+           (error "No body found for the package.  Create it first"))
+
+         (save-restriction
+           (widen)
+           (goto-char (point-max))
+           (forward-comment -10000)
+           (re-search-backward "\\<end\\>" nil t)
+           ;;  Move to the beginning of the elaboration part, if any
+           (re-search-backward "^begin" nil t)
+           (newline)
+           (forward-char -1)
+           (insert spec)
+           (re-search-backward ada-procedure-start-regexp nil t)
+           (ada-gen-treat-proc (cons (match-beginning 0) (match-end 0)))
+           ))
       (error "Not in subprogram spec"))))
 
 ;; --------------------------------------------------------
@@ -5435,36 +5508,35 @@ This function typically is to be hooked into `ff-file-created-hooks'."
 ;;  Read the special cases for exceptions
 (ada-case-read-exceptions)
 
-;;  Setup auto-loading of the other ada-mode files.
-(if (equal ada-which-compiler 'gnat)
-    (progn
-      (autoload 'ada-change-prj                   "ada-xref" nil t)
-      (autoload 'ada-check-current                "ada-xref" nil t)
-      (autoload 'ada-compile-application          "ada-xref" nil t)
-      (autoload 'ada-compile-current              "ada-xref" nil t)
-      (autoload 'ada-complete-identifier          "ada-xref" nil t)
-      (autoload 'ada-find-file                    "ada-xref" nil t)
-      (autoload 'ada-find-any-references          "ada-xref" nil t)
-      (autoload 'ada-find-src-file-in-dir         "ada-xref" nil t)
-      (autoload 'ada-find-local-references        "ada-xref" nil t)
-      (autoload 'ada-find-references              "ada-xref" nil t)
-      (autoload 'ada-gdb-application              "ada-xref" nil t)
-      (autoload 'ada-goto-declaration             "ada-xref" nil t)
-      (autoload 'ada-goto-declaration-other-frame "ada-xref" nil t)
-      (autoload 'ada-goto-parent                  "ada-xref" nil t)
-      (autoload 'ada-make-body-gnatstub           "ada-xref" nil t)
-      (autoload 'ada-point-and-xref               "ada-xref" nil t)
-      (autoload 'ada-reread-prj-file              "ada-xref" nil t)
-      (autoload 'ada-run-application              "ada-xref" nil t)
-      (autoload 'ada-set-default-project-file     "ada-xref" nil nil)
-      (autoload 'ada-set-default-project-file     "ada-xref" nil t)
-      (autoload 'ada-xref-goto-previous-reference "ada-xref" nil t)
-
-      (autoload 'ada-customize                    "ada-prj"  nil t)
-      (autoload 'ada-prj-edit                     "ada-prj"  nil t)
-      (autoload 'ada-prj-new                      "ada-prj"  nil t)
-      (autoload 'ada-prj-save                     "ada-prj"  nil t)
-      ))
+;;  Setup auto-loading of the other Ada mode files.
+(autoload 'ada-change-prj                   "ada-xref" nil t)
+(autoload 'ada-check-current                "ada-xref" nil t)
+(autoload 'ada-compile-application          "ada-xref" nil t)
+(autoload 'ada-compile-current              "ada-xref" nil t)
+(autoload 'ada-complete-identifier          "ada-xref" nil t)
+(autoload 'ada-find-file                    "ada-xref" nil t)
+(autoload 'ada-find-any-references          "ada-xref" nil t)
+(autoload 'ada-find-src-file-in-dir         "ada-xref" nil t)
+(autoload 'ada-find-local-references        "ada-xref" nil t)
+(autoload 'ada-find-references              "ada-xref" nil t)
+(autoload 'ada-gdb-application              "ada-xref" nil t)
+(autoload 'ada-goto-declaration             "ada-xref" nil t)
+(autoload 'ada-goto-declaration-other-frame "ada-xref" nil t)
+(autoload 'ada-goto-parent                  "ada-xref" nil t)
+(autoload 'ada-make-body-gnatstub           "ada-xref" nil t)
+(autoload 'ada-point-and-xref               "ada-xref" nil t)
+(autoload 'ada-reread-prj-file              "ada-xref" nil t)
+(autoload 'ada-run-application              "ada-xref" nil t)
+(autoload 'ada-set-default-project-file     "ada-xref" nil nil)
+(autoload 'ada-set-default-project-file     "ada-xref" nil t)
+(autoload 'ada-xref-goto-previous-reference "ada-xref" nil t)
+(autoload 'ada-set-main-compile-application "ada-xref" nil t)
+(autoload 'ada-show-current-main            "ada-xref" nil t)
+
+(autoload 'ada-customize                    "ada-prj"  nil t)
+(autoload 'ada-prj-edit                     "ada-prj"  nil t)
+(autoload 'ada-prj-new                      "ada-prj"  nil t)
+(autoload 'ada-prj-save                     "ada-prj"  nil t)
 
 (autoload 'ada-array           "ada-stmt" nil t)
 (autoload 'ada-case            "ada-stmt" nil t)