diff --git a/ada-mode.el b/ada-mode.el
index 3a2a8f7..71bad32 100644
--- a/ada-mode.el
+++ b/ada-mode.el
@@ -232,6 +232,7 @@ Function to call to adjust the case of Ada keywords."
 Global value is default for project variable `case_keyword'.
 Function to call to adjust the case of Ada keywords."
   :type '(choice (const ada-mixed-case)
+                 (const ada-title-case)
 		 (const downcase-region)
 		 (const upcase-region))
   :group 'ada
@@ -287,6 +288,53 @@ must provide a parser for a file with one of these extensions."
   :type 'list
   :group 'ada)
 
+;; These are defined here so that they exists for use with title case
+;; customization via plist. If they are not defined, then customizing
+;; `ada-title-case-language' yields the cons (quote ada-λ-de) after
+;; necessary quoting, as otherwise the symbols are not defined ("as a
+;; variable"), but we need symbols like ada-λ-de for the plist.
+(defconst ada-λ-de nil)
+(defconst ada-λ-en nil)
+(defconst ada-λ-fr nil)
+
+(defcustom ada-title-case-words
+  '(;; ISO language code => list of words.
+    ;;
+    ;; The lists include only the words likely to be found disturbing
+    ;; if capitalized and only if controversy seems unlikely, in
+    ;; particular when considering their use as part of Ada
+    ;; identifiers.
+    ;;
+    ;; By assumption, the region has been downcased already, so is
+    ;; anything to be compared, then. Therefore, words are written in
+    ;; small letters.
+    ada-λ-de (list "und" "oder" "der" "des")
+    ada-λ-en (list "and" "or" "of" "a" "an")
+    ada-λ-fr (list)
+    )
+  "A table associating words to be treated specially for title
+case in Ada identifiers. If a word is found here, then the rules
+for mixed case will not apply and the word stays in lower case.
+
+The symbols that are used as indexing keys include, in their
+names, the 2-letter ISO codes of natural languages defined in
+`ada-title-case-language', which see."
+  :type '(plist)
+  :group 'ada
+)
+
+(defcustom ada-title-case-language nil
+  "If not nil, then a symbol denoting a natural language for
+indexing a table of lists of words not to be capitalized when
+using title case.  The table, `ada-title-case-words', has one
+association for each of the supported natural languages."
+  ;; See `ada-title-case-except'.
+  :type '(choice (const :tag "None (no title case)" nil)
+                 (const :tag "Deutsch" ada-λ-de)
+                 (const :tag "English" ada-λ-en)
+                 (const :tag "Français" ada-λ-fr))
+  :group 'ada)
+
 ;;;;; end of user variables
 
 (defconst ada-symbol-end
@@ -1061,8 +1109,12 @@ User is prompted to choose a file from project variable casing if it is a list."
 	       (point))))
     (member (downcase word) ada-keywords)))
 
-(defun ada-mixed-case (start end)
-  "Adjust case of region START END to Mixed_Case."
+(defun ada-mixed-case (start end &optional title-case-active)
+  "Adjust case of region START END to Mixed_Case.
+
+If TITLE-CASE-ACTIVE evaluates to t, the function excepts words
+that should not participate as specified via custom setting in
+`ada-title-case-language'. They will be in lower case."
   (let ((done nil)
 	next)
     (if ada-case-strict
@@ -1074,16 +1126,40 @@ User is prompted to choose a file from project variable casing if it is a list."
 	     (save-excursion (when (search-forward "_" end t) (point-marker)))
 	     (copy-marker (1+ end))))
 
-      ;; upcase first char
-      (insert-char (upcase (following-char)) 1)
-      (delete-char 1)
+      ;; If a title case language does not except the word by listing
+      ;; it, and provided that we are not looking at the first
+      ;; character of the entire identifier, upcase first char.
+      (unless (and title-case-active
+                   (> (point) start)
+                   (ada-title-case-except (buffer-substring-no-properties (point) (1- next))))
+        (insert-char (upcase (following-char)) 1)
+        (delete-char 1))
 
       (goto-char next)
-      (if (< (point) end)
-	  (setq start (point))
-	(setq done t))
+      (if (>= (point) end)
+	  ;;(setq start (point))
+          (setq done t))
       )))
 
+(defun ada-title-case (start end)
+  "Adjust case of region START END to Title_Case."
+  ;; here is is why `ada-mixed-case' has an optional argument:
+  (ada-mixed-case start end 't))
+
+(defun ada-title-case-except (word)
+  "If custom variable `ada-title-case-language' is `nil', returns `nil'.
+Otherwise, returns true if WORD is found in the list of words
+associated with the language in `ada-title-case-words'."
+  (and ada-title-case-language          ; a precaution that will not be necessary
+                                        ; if all calls are made only in suitable
+                                        ; circumstances
+       (let ((words-per-language
+              (plist-get ada-title-case-words ada-title-case-language)))
+         ;; (message "found %s for %s in %s" words-per-language
+         ;;          ada-title-case-language
+         ;;          ada-title-case-words)
+         (member word words-per-language))))
+
 (defun ada-case-adjust-identifier ()
   "Adjust case of the previous word as an identifier.
 Uses `ada-case-identifier', with exceptions defined in
