From ad1601f28307c9af81f8da1924f64f21ec9c2974 Mon Sep 17 00:00:00 2001
From: Karl Berry <karl@freefriends.org>
Date: Sun, 16 Aug 2015 21:17:20 +0000
Subject: acro (16aug15)

git-svn-id: svn://tug.org/texlive/trunk@38132 c570f23f-e606-0410-a88d-b1316a301751
---
 Master/texmf-dist/tex/latex/acro/acro.sty | 1730 ++++++++++++++++++-----------
 1 file changed, 1064 insertions(+), 666 deletions(-)

(limited to 'Master/texmf-dist/tex/latex/acro/acro.sty')

diff --git a/Master/texmf-dist/tex/latex/acro/acro.sty b/Master/texmf-dist/tex/latex/acro/acro.sty
index b53f44f44cb..0bf51f6373b 100644
--- a/Master/texmf-dist/tex/latex/acro/acro.sty
+++ b/Master/texmf-dist/tex/latex/acro/acro.sty
@@ -31,24 +31,10 @@
 \RequirePackage{expl3,l3sort,xparse,l3keys2e,xtemplate}
 \ProvidesExplPackage
   {acro}
-  {2015/05/10}
-  {1.6b}
+  {2015/08/16}
+  {2.0}
   {Typeset Acronyms}
 
-% --------------------------------------------------------------------------
-% check expl3 version:
-\@ifpackagelater { expl3 } { 2012/11/21 }
-  { }
-  {
-    \PackageError {acro} { Support~package~expl3~too~old }
-      {
-        You~need~to~update~your~installation~of~the~bundles~'l3kernel'~and~
-        'l3packages'.\MessageBreak
-        Loading~acro~will~abort!
-      }
-    \tex_endinput:D
-  }
-
 % --------------------------------------------------------------------------
 % warning and error messages:
 \msg_new:nnn {acro} {undefined}
@@ -77,69 +63,75 @@
     I~encourage~you~to~remove~it~from~your~document.
   }
 
-% message macros:
-\bool_new:N \l__acro_silence_bool
-
-\cs_new_protected:Npn \acro_serious_message:nn
+\msg_new:nnn {acro} {substitute-short}
   {
-    \bool_if:NTF \l__acro_silence_bool
-      { \msg_warning:nn }
-      { \msg_error:nn }
+    No~ short~ form~ set~ for~ acronym~ `#1'.~ Setting~ the~ short~ form~
+    equal~ to~ the~ ID~ `#1'.~ If~ that~ is~ not~ what~ you~ want~ add~ an~
+    explicit~ short~ form.
   }
-
-\cs_new_protected:Npn \acro_serious_message:nnn
+\msg_new:nnn {acro} {ending-exists}
   {
-    \bool_if:NTF \l__acro_silence_bool
-      { \msg_warning:nnn }
-      { \msg_error:nnn }
+    An~ ending~ with~ the~ name~ `#1'~ already~ exists.~ I'm~ doing~ nothing.
   }
 
-\cs_new_protected:Npn \acro_serious_message:nnnn
+\msg_new:nnn {acro} {ending-before-acronyms}
   {
-    \bool_if:NTF \l__acro_silence_bool
-      { \msg_warning:nnnn }
-      { \msg_error:nnnn }
+    You~ are~ using~ \token_to_str:N \ProvideAcroEnding \c_space_tl after~
+    you've~ declared~ at~ least~ one~ acronym.~ This~ will~ lead~ to~
+    trouble!~ Define~ endings~ before~ any~ acronym~ declarations!
   }
 
-\cs_new_protected:Npn \acro_harmless_message:nnn
+\msg_new:nnn {acro} {no-alternative}
   {
-    \bool_if:NTF \l__acro_silence_bool
-      { \msg_info:nnn }
-      { \msg_warning:nnn }
+    There~ is~ no~ alternative~ form~ for~ acronym~ `#1'.~ Using~ the~ short~
+    form~ instead.
   }
 
-\cs_new_protected:Npn \acro_harmless_message:nnnn
-  {
-    \bool_if:NTF \l__acro_silence_bool
-      { \msg_info:nnnn }
-      { \msg_warning:nnnn }
-  }
+% message macros:
+\bool_new:N \l__acro_silence_bool
+
+\cs_new:Npn \__acro_remove_backslash:N #1
+  { \exp_after:wN \use_none:n \token_to_str:N #1 }
 
-\cs_new_protected:Npn \acro_harmless_message:nnnnn
+\cs_new_protected:Npn \acro_new_message_commands:Nnnn #1#2#3#4
   {
-    \bool_if:NTF \l__acro_silence_bool
-      { \msg_info:nnnnn }
-      { \msg_warning:nnnnn }
+    \clist_map_inline:nn {#2}
+      {
+        \cs_new_protected:cpn { \__acro_remove_backslash:N #1 ##1 }
+          {
+            \bool_if:NTF \l__acro_silence_bool
+              { \use:c { \__acro_remove_backslash:N #3 n##1 } {acro} }
+              { \use:c { \__acro_remove_backslash:N #4 n##1 } {acro} }
+          }
+      }
   }
 
+\acro_new_message_commands:Nnnn \acro_serious_message: {n,nn,nnn}
+  { \msg_warning: }
+  { \msg_error: }
+
+\acro_new_message_commands:Nnnn \acro_harmless_message: {n,nn,nnn,nnnn}
+  { \msg_info: }
+  { \msg_warning: }
+
 \cs_new_protected:Npn \acro_option_deprecated:nn #1#2
   {
     \tl_if_blank:nTF {#2}
-      { \acro_harmless_message:nnnn  {acro} {deprecated} {option} {#1 } }
-      { \acro_harmless_message:nnnnn {acro} {replaced}   {option} {#1} {#2} }
+      { \acro_harmless_message:nnn  {deprecated} {option} {#1} }
+      { \acro_harmless_message:nnnn {replaced}   {option} {#1} {#2} }
   }
+\cs_new_protected:Npn \acro_option_deprecated:n #1
+  { \cs_new_protected:Npn \acro_option_deprecated:nn {#1} {} }
 
 \cs_new_protected:Npn \acro_command_deprecated:NN #1#2
   {
     \tl_if_blank:nTF {#2}
       {
-        \acro_harmless_message:nnnnn {acro} {deprecated}
-          {command}
+        \acro_harmless_message:nnn {deprecated} {command}
           { \token_to_str:N #1 }
       }
       {
-        \acro_harmless_message:nnnnn {acro} {replaced}
-          {command}
+        \acro_harmless_message:nnnn {replaced} {command}
           { \token_to_str:N #1 }
           { \token_to_str:N #2 }
       }
@@ -161,12 +153,15 @@
 
 % --------------------------------------------------------------------------
 % variants of kernel commands
-\cs_generate_variant:Nn \quark_if_no_value:nTF { V }
-\cs_generate_variant:Nn \tl_put_right:Nn       { NV }
-\cs_generate_variant:Nn \tl_if_eq:nnT          { V }
-\cs_generate_variant:Nn \tl_if_eq:nnF          { V }
-\cs_generate_variant:Nn \seq_use:Nnnn          { c }
-\cs_generate_variant:Nn \seq_gset_split:Nnn    { c }
+\cs_generate_variant:Nn \quark_if_no_value:nTF  { V }
+\cs_generate_variant:Nn \tl_put_right:Nn        { NV, Nv }
+\cs_generate_variant:Nn \tl_if_eq:nnT           { V }
+\cs_generate_variant:Nn \tl_if_eq:nnF           { V }
+\cs_generate_variant:Nn \seq_use:Nnnn           { c }
+\cs_generate_variant:Nn \seq_gset_split:Nnn     { c }
+\cs_generate_variant:Nn \prop_put:Nnn           { NnV, cnx, cnv }
+\cs_generate_variant:Nn \prop_get:NnNF          { cn, cnc }
+\cs_generate_variant:Nn \cs_generate_variant:Nn { c }
 
 % --------------------------------------------------------------------------
 % boolean variables:
@@ -175,7 +170,6 @@
 \bool_new:N      \l__acro_use_single_bool
 \bool_new:N      \l__acro_print_only_used_bool
 \bool_set_true:N \l__acro_print_only_used_bool
-\bool_new:N      \l__acro_use_plural_bool
 \bool_new:N      \l__acro_hyperref_loaded_bool
 \bool_new:N      \l__acro_use_hyperref_bool
 \bool_new:N      \l__acro_custom_format_bool
@@ -193,6 +187,7 @@
 \bool_new:N      \l__acro_citation_all_bool
 \bool_new:N      \l__acro_citation_first_bool
 \bool_set_true:N \l__acro_citation_first_bool
+\bool_new:N      \l__acro_group_citation_bool
 \bool_new:N      \l__acro_acc_supp_bool
 \bool_new:N      \l__acro_following_page_bool
 \bool_new:N      \l__acro_following_pages_bool
@@ -214,11 +209,14 @@
 \bool_new:N      \l__acro_place_label_bool
 \bool_new:N      \l__acro_list_all_pages_bool
 \bool_set_true:N \l__acro_list_all_pages_bool
+\bool_new:N      \g__acro_first_acronym_declared_bool
+\bool_new:N      \l__acro_include_endings_format_bool
 
 % --------------------------------------------------------------------------
 % token list variables:
 \tl_new:N   \l__acro_ignore_tl
 \tl_new:N   \l__acro_short_format_tl
+\tl_new:N   \l__acro_alt_format_tl
 \tl_new:N   \l__acro_list_short_format_tl
 \tl_new:N   \l__acro_long_format_tl
 \tl_new:N   \l__acro_first_long_format_tl
@@ -254,17 +252,14 @@
 \tl_new:N   \l__acro_list_name_tl
 \tl_set:Nn  \l__acro_list_name_tl      { Acronyms }
 \tl_new:N   \l__acro_short_tl
-\tl_new:N   \l__acro_short_plural_tl
-\tl_new:N   \l__acro_default_plural_tl
-\tl_set:Nn  \l__acro_default_plural_tl { s }
 \tl_new:N   \l__acro_alt_tl
 \tl_new:N   \l__acro_long_tl
 \tl_new:N   \l__acro_long_pre_tl
 \tl_new:N   \l__acro_long_post_tl
 \tl_new:N   \l__acro_custom_format_tl
 \tl_new:N   \l__acro_first_between_tl
-\tl_new:N   \l__acro_citation_space_tl
-\tl_set:Nn  \l__acro_citation_space_tl { \nobreakspace }
+\tl_new:N   \l__acro_citation_connect_tl
+\tl_new:N   \l__acro_between_group_connect_citation_tl
 \tl_new:N   \l__acro_extra_brackets_tl
 \tl_new:N   \l__acro_extra_punct_tl
 \tl_new:N   \l__acro_first_brackets_tl
@@ -280,6 +275,8 @@
 \tl_new:N   \l__acro_acc_supp_options_tl
 \tl_new:N   \l__acro_label_prefix_tl
 \tl_set:Nn  \l__acro_label_prefix_tl { ac: }
+\tl_new:N   \l__acro_single_form_tl
+\tl_set:Nn  \l__acro_single_form_tl {long}
 
 % --------------------------------------------------------------------------
 % length variables:
@@ -292,7 +289,7 @@
 \cs_new:Npn \acro_no_break: { \tex_penalty:D \c_ten_thousand }
 
 \cs_new_protected:Npn \__acro_first_upper_case:n #1
-  { \tl_mixed_case:n {#1} }
+  { \tl_upper_case:n { \tl_head:n {#1} } \tl_tail:n {#1} }
 \cs_generate_variant:Nn \__acro_first_upper_case:n { x }
 \cs_generate_variant:Nn \tl_mixed_case:n { x }
 
@@ -305,94 +302,133 @@
 % options:
 \keys_define:nn {acro}
   {
-    version           .code:n     = 
-      \acro_option_deprecated:nn { version } { }               ,
+    version           .code:n     = \acro_option_deprecated:n {version} ,
     messages          .choice: ,
     messages / silent .code:n     =
       \bool_set_true:N \l__acro_silence_bool ,
-    messages / loud .code:n     =
+    messages / loud .code:n       =
       \bool_set_false:N \l__acro_silence_bool ,
-    accsupp           .bool_set:N = \l__acro_acc_supp_bool          ,
-    accsupp-options   .tl_set:N   = \l__acro_acc_supp_options_tl    ,
-    macros            .bool_set:N = \l__acro_create_macros_bool     ,
-    xspace            .bool_set:N = \l__acro_xspace_bool            ,
-    strict            .bool_set:N = \l__acro_strict_bool            ,
-    sort              .bool_set:N = \l__acro_sort_bool              ,
+    messages          .value_required:n = true ,
+    accsupp           .bool_set:N = \l__acro_acc_supp_bool ,
+    accsupp-options   .tl_set:N   = \l__acro_acc_supp_options_tl ,
+    macros            .bool_set:N = \l__acro_create_macros_bool ,
+    xspace            .bool_set:N = \l__acro_xspace_bool ,
+    strict            .bool_set:N = \l__acro_strict_bool ,
+    sort              .bool_set:N = \l__acro_sort_bool ,
     short-format      .code:n     =
       \tl_set:Nn \l__acro_short_format_tl {#1}
-      \tl_set:Nn \l__acro_list_short_format_tl {#1}                 ,
+      \tl_set_eq:NN \l__acro_alt_format_tl \l__acro_short_format_tl
+      \tl_set:Nn \l__acro_list_short_format_tl {#1} ,
+    short-format      .value_required:n = true ,
     long-format       .code:n     =
       \tl_set:Nn \l__acro_long_format_tl {#1}
       \tl_set:Nn \l__acro_first_long_format_tl {#1}
-      \tl_set:Nn \l__acro_list_long_format_tl {#1}                  ,
+      \tl_set:Nn \l__acro_list_long_format_tl {#1} ,
+    long-format       .value_required:n = true ,
     first-long-format .code:n     =
-      \tl_set:Nn \l__acro_first_long_format_tl {#1}                 ,
-    display-foreign   .bool_set:N = \l__acro_foreign_bool           ,
-    foreign-format    .tl_set:N   = \l__acro_foreign_format_tl      ,
-    list-short-format .tl_set:N   = \l__acro_list_short_format_tl   ,
-    list-long-format  .tl_set:N   = \l__acro_list_long_format_tl    ,
+      \tl_set:Nn \l__acro_first_long_format_tl {#1} ,
+    first-long-format .value_required:n = true ,
+    format-include-endings .bool_set:N = \l__acro_include_endings_format_bool ,
+    display-foreign   .bool_set:N = \l__acro_foreign_bool ,
+    foreign-format    .tl_set:N   = \l__acro_foreign_format_tl ,
+    foreign-format    .value_required:n = true ,
+    list-short-format .tl_set:N   = \l__acro_list_short_format_tl ,
+    list-short-format .value_required:n = true ,
+    list-long-format  .tl_set:N   = \l__acro_list_long_format_tl ,
+    list-long-format  .value_required:n = true ,
     list-foreign-format .tl_set:N = \l__acro_foreign_list_format_tl ,
-    extra-format      .tl_set:N   = \l__acro_extra_format_tl        ,
-    single            .bool_set:N = \l__acro_use_single_bool        ,
-    first-style       .tl_set:N   = \l__acro_first_instance_tl      ,
-    extra-style       .tl_set:N   = \l__acro_extra_instance_tl      ,
-    label             .bool_set:N = \l__acro_place_label_bool       ,
-    label-prefix      .tl_set:N   = \l__acro_label_prefix_tl        ,
+    list-foreign-format .value_required:n = true ,
+    extra-format      .tl_set:N   = \l__acro_extra_format_tl ,
+    extra-format      .value_required:n = true ,
+    single            .bool_set:N = \l__acro_use_single_bool ,
+    single-form       .tl_set:N   = \l__acro_single_form_tl ,
+    single-form       .value_required:n = true ,
+    first-style       .tl_set:N   = \l__acro_first_instance_tl ,
+    first-style       .value_required:n = true ,
+    extra-style       .tl_set:N   = \l__acro_extra_instance_tl ,
+    extra-style       .value_required:n = true ,
+    label             .bool_set:N = \l__acro_place_label_bool ,
+    label-prefix      .tl_set:N   = \l__acro_label_prefix_tl ,
+    label-prefix      .value_required:n = true ,
     pages             .choice: ,
     pages / all       .code:n     =
-      \bool_set_true:N \l__acro_list_all_pages_bool                 ,
+      \bool_set_true:N \l__acro_list_all_pages_bool ,
     pages / first     .code:n     =
       \bool_set_true:N \l__acro_place_label_bool
-      \bool_set_false:N \l__acro_list_all_pages_bool                ,
-    page-ref          .tl_set:N   = \l__acro_page_instance_tl       ,
-    page-name         .tl_set:N   = \l__acro_page_name_tl           ,
-    pages-name        .tl_set:N   = \l__acro_pages_name_tl          ,
+      \bool_set_false:N \l__acro_list_all_pages_bool ,
+    pages             .value_required:n = true ,
+    page-ref          .tl_set:N   = \l__acro_page_instance_tl ,
+    page-ref          .value_required:n = true ,
+    page-name         .tl_set:N   = \l__acro_page_name_tl ,
+    page-name         .value_required:n = true ,
+    pages-name        .tl_set:N   = \l__acro_pages_name_tl ,
+    pages-name        .value_required:n = true ,
     page-ranges       .code:n     =
       \bool_set_false:N \l__acro_following_page_bool
       \bool_set_false:N \l__acro_following_pages_bool
-      \acro_option_deprecated:nn { pages-ranges } { }               ,
-    following-page    .bool_set:N = \l__acro_following_page_bool    ,
-    following-pages   .bool_set:N = \l__acro_following_pages_bool   ,
-    record-pages      .code:n     = 
-      \acro_option_deprecated:nn { record-pages } { }               ,
-    next-page         .tl_set:N   = \l__acro_next_page_tl           ,
-    next-pages        .tl_set:N   = \l__acro_next_pages_tl          ,
-    list-style        .tl_set:N   = \l__acro_list_instance_tl       ,
-    list-type         .tl_set:N   = \l__acro_list_type_tl           ,
+      \acro_option_deprecated:n {pages-ranges} ,
+    following-page    .bool_set:N = \l__acro_following_page_bool ,
+    following-pages   .bool_set:N = \l__acro_following_pages_bool ,
+    record-pages      .code:n     = \acro_option_deprecated:n {record-pages} ,
+    next-page         .tl_set:N   = \l__acro_next_page_tl ,
+    next-page         .value_required:n = true ,
+    next-pages        .tl_set:N   = \l__acro_next_pages_tl ,
+    next-pages        .value_required:n = true ,
+    list-style        .tl_set:N   = \l__acro_list_instance_tl ,
+    list-style        .value_required:n = true ,
+    list-type         .tl_set:N   = \l__acro_list_type_tl ,
+    list-type         .value_required:n = true ,
     list-header       .code:n     =
-      \acro_option_deprecated:nn { list-header } { list-heading }
-      \tl_set:Nn \l__acro_list_title_tl {#1}                      ,
-    list-heading      .tl_set:N   = \l__acro_list_title_tl          ,
-    list-name         .tl_set:N   = \l__acro_list_name_tl           ,
-    list-table-width  .dim_set:N  = \l__acro_table_width_dim        ,
-    hyperref          .bool_set:N = \l__acro_use_hyperref_bool      ,
-    only-used         .bool_set:N = \l__acro_print_only_used_bool   ,
+      \acro_option_deprecated:nn {list-header} {list-heading}
+      \tl_set:Nn \l__acro_list_title_tl {#1} ,
+    list-heading      .tl_set:N   = \l__acro_list_title_tl ,
+    list-heading      .value_required:n = true ,
+    list-name         .tl_set:N   = \l__acro_list_name_tl ,
+    list-name         .value_required:n = true ,
+    list-table-width  .dim_set:N  = \l__acro_table_width_dim ,
+    list-table-width  .value_required:n = true ,
+    hyperref          .bool_set:N = \l__acro_use_hyperref_bool ,
+    only-used         .bool_set:N = \l__acro_print_only_used_bool ,
     mark-as-used      .choice: ,
     mark-as-used / first .code:n  =
-      \bool_gset_true:N \g__acro_mark_first_as_used_bool            ,
+      \bool_gset_true:N \g__acro_mark_first_as_used_bool ,
     mark-as-used / any   .code:n  =
-      \bool_gset_false:N \g__acro_mark_first_as_used_bool           ,
-    plural-ending     .tl_set:N   = \l__acro_default_plural_tl      ,
-    list-caps         .bool_set:N = \l__acro_capitalize_list_bool   ,
-    cite              .choice:                                      ,
+      \bool_gset_false:N \g__acro_mark_first_as_used_bool ,
+    mark-as-used      .default:n  = any ,
+    list-caps         .bool_set:N = \l__acro_capitalize_list_bool ,
+    cite              .choice: ,
     cite / all        .code:n     =
       \bool_set_true:N \l__acro_citation_all_bool
-      \bool_set_true:N \l__acro_citation_first_bool                 ,
+      \bool_set_true:N \l__acro_citation_first_bool ,
     cite / none       .code:n     =
       \bool_set_false:N \l__acro_citation_all_bool
-      \bool_set_false:N \l__acro_citation_first_bool                ,
+      \bool_set_false:N \l__acro_citation_first_bool ,
     cite / first      .code:n     =
       \bool_set_false:N \l__acro_citation_all_bool
-      \bool_set_true:N  \l__acro_citation_first_bool                ,
-%     cite              .default:n  = all                             ,
+      \bool_set_true:N  \l__acro_citation_first_bool ,
+    cite              .default:n  = all ,
     cite-cmd          .code:n     =
-      \cs_set:Npn \__acro_citation_cmd:w {#1}                     ,
-    cite-space        .tl_set:N   = \l__acro_citation_space_tl      ,
-    index             .bool_set:N = \l__acro_addto_index_bool       ,
+      \cs_set:Npn \__acro_citation_cmd:w {#1} ,
+    cite-cmd          .value_required:n = true ,
+    group-cite-cmd    .code:n     =
+      \cs_set:Npn \__acro_group_citation_cmd:w {#1} ,
+    group-cite-cmd    .value_required:n = true ,
+    group-citation    .bool_set:N = \l__acro_group_citation_bool ,
+    cite-connect      .tl_set:N   = \l__acro_citation_connect_tl ,
+    cite-connect      .initial:n  = \nobreakspace ,
+    cite-connect      .value_required:n = true ,
+    cite-space        .code:n     =
+      \acro_option_deprecated:nn {cite-space} {cite-connect} ,
+    group-cite-connect .tl_set:N = \l__acro_between_group_connect_citation_tl ,
+    group-cite-connect .initial:n = {,\nobreakspace} ,
+    group-cite-connect .value_required:n = true ,
+    index             .bool_set:N = \l__acro_addto_index_bool ,
     index-cmd         .code:n     =
       \cs_set:Npn \__acro_index_cmd:n {#1} ,
+    index-cmd         .value_required:n = true ,
     uc-cmd            .code:n     =
-      \cs_set_eq:NN \__acro_first_upper_case:n #1
+      \cs_set_eq:NN \__acro_first_upper_case:n #1 ,
+    uc-cmd            .value_required:n = true
   }
 
 \AtBeginDocument
@@ -415,32 +451,42 @@
   { \keys_set:nn {acro} {#1} \ignorespaces }
 
 % --------------------------------------------------------------------------
-\cs_new_protected:Npn \acro_plural:
-  { \bool_set_true:N \l__acro_use_plural_bool }
-
-\cs_new_protected:Npn \acro_upper:
-  { \bool_set_true:N \l__acro_first_upper_bool }
-
 % typeset the short form:
-\cs_new:Npn \__acro_write_short:n #1
+% #1: ID
+% #2: short form
+\cs_new_protected:Npn \acro_write_short:nn #1#2
   {
     \mode_if_horizontal:F { \leavevmode }
     \group_begin:
       \bool_if:NTF \l__acro_custom_format_bool
         { \l__acro_custom_format_tl }
         { \l__acro_short_format_tl }
-      {  #1 }
+      {#2}
     \group_end:
-    \bool_if:NT \l__acro_use_plural_bool
-      { \tl_use:N \l__acro_short_plural_tl }
   }
-\cs_generate_variant:Nn \__acro_write_short:n { V }
+\cs_generate_variant:Nn \acro_write_short:nn { nV , nv }
+
+% #1: ID
+% #2: alt form
+\cs_new_protected:Npn \acro_write_alt:nn #1#2
+  {
+    \mode_if_horizontal:F { \leavevmode }
+    \group_begin:
+      \bool_if:NTF \l__acro_custom_format_bool
+        { \l__acro_custom_format_tl }
+        { \l__acro_alt_format_tl }
+      {#2}
+    \group_end:
+  }
+\cs_generate_variant:Nn \acro_write_alt:nn { nV , nv }
 
 % typeset the longform,...:
 % TODO: rethink the formatting mechanism
 % right now a custom format gets applied additionally to the global one
 % although before it
-\cs_new_protected:Npn \__acro_write_long:Nn #1#2
+% #1: tl holding format
+% #2: long form
+\cs_new_protected:Npn \acro_write_long:Nn #1#2
   {
     \mode_if_horizontal:F { \leavevmode }
     \group_begin:
@@ -457,7 +503,7 @@
       }
     \group_end:
   }
-\cs_generate_variant:Nn \__acro_write_long:Nn { NV,No,Nf }
+\cs_generate_variant:Nn \acro_write_long:Nn { NV,No,Nf }
 
 % --------------------------------------------------------------------------
 % hyperref support
@@ -474,21 +520,25 @@
       }
   }
 
-\cs_new_protected:Npn \__acro_make_link:nNN #1#2#3
+% #1: tl var
+% #2: id
+% #3: text
+\cs_new_protected:Npn \__acro_make_link:Nnn #1#2#3
   {
     \bool_if:nTF
       { \l__acro_use_hyperref_bool && \l__acro_hyperref_loaded_bool }
       {
-        \tl_set:Nn #2
+        \tl_set:Nn #1
            {
-             \acro_hyper_link:nn {#1} { \phantom {#3} }
-             \__acro_is_single:nTF {#1}
+             \acro_hyper_link:nn {#2} { \phantom {#3} }
+             \acro_if_is_single:nTF {#2}
                { \hbox_overlap_left:n {#3} }
                { \acro_color_link:n { \hbox_overlap_left:n {#3} } }
            }
        }
-       { \tl_set:Nn #2 {#3} }
+       { \tl_set:Nn #1 {#3} }
   }
+\cs_generate_variant:Nn \__acro_make_link:Nnn {NnV}
 
 \cs_new:Npn \acro_color_link:n #1
   {
@@ -545,13 +595,14 @@
     \AssignTemplateKeys
     \bool_if:nT { !\l__acro_first_only_short_bool && !\l__acro_first_reversed_bool }
       {
-        \__acro_indefinite:nn {#1} { long }
-        \__acro_write_long:No \l__acro_first_long_format_tl {#3}
-        \tl_use:N \c_space_tl
+        \acro_write_indefinite:nn {#1} {long}
+        \acro_write_long:No \l__acro_first_long_format_tl {#3}
+        \acro_endings:nn {#1} {long}
+        \acro_space:
         \tl_if_blank:VF \l__acro_first_between_tl
           {
             \tl_use:N \l__acro_first_between_tl
-            \tl_use:N \c_space_tl
+            \acro_space:
           }
       }
     \bool_if:nT
@@ -575,41 +626,58 @@
       }
     \bool_if:nT
       { \l__acro_first_reversed_bool || \l__acro_first_only_short_bool }
-      { \__acro_indefinite:nn {#1} { short } }
-    \__acro_acc_supp:nn {#1} { \__acro_write_short:n {#2} }
+      { \acro_write_indefinite:nn {#1} {short} }
+    \group_begin:
+      \bool_if:nT
+        { !\l__acro_first_reversed_bool && !\l__acro_first_only_short_bool }
+        {
+          \prop_map_inline:Nn \l__acro_trailing_tokens_prop
+            { \acro_deactivate_trailing_action:n {##1} }
+        }
+      \acro_acc_supp:nn {#1} { \acro_write_short:nn {#1} {#2} }
+      \acro_endings:nn {#1} {short}
+    \group_end:
+    \bool_if:nT
+      { \l__acro_group_citation_bool && !\l__acro_first_reversed_bool }
+      { \acro_group_cite:n {#1} }
     \bool_if:nT
       { \l__acro_first_use_brackets_bool && !\l__acro_first_reversed_bool }
       { \tl_tail:N \l__acro_first_brackets_tl }
-    \bool_if:nT
-      { !\l__acro_first_only_short_bool && \l__acro_first_reversed_bool }
+    \bool_if:NT \l__acro_first_reversed_bool
       {
-        \tl_if_blank:VF \l__acro_first_between_tl
+        \bool_if:NF \l__acro_first_only_short_bool
           {
+            \tl_if_blank:VF \l__acro_first_between_tl
+              {
+                \tl_use:N \c_space_tl
+                \tl_use:N \l__acro_first_between_tl
+              }
             \tl_use:N \c_space_tl
-            \tl_use:N \l__acro_first_between_tl
-          }
-        \tl_use:N \c_space_tl
-        \bool_if:nT
-          { \l__acro_first_use_brackets_bool && \l__acro_first_reversed_bool }
-          { \tl_head:N \l__acro_first_brackets_tl }
-        \__acro_write_long:No \l__acro_first_long_format_tl {#3}
-        \bool_if:nT { \l__acro_foreign_bool && \l__acro_first_reversed_bool }
-          {
-            \prop_get:NnNT \l__acro_foreign_prop {#1} \l__acro_foreign_tl
+            \bool_if:NT \l__acro_first_use_brackets_bool
+              { \tl_head:N \l__acro_first_brackets_tl }
+            \acro_write_long:No \l__acro_first_long_format_tl {#3}
+            \bool_if:NT \l__acro_foreign_bool
               {
-                \tl_use:N \l__acro_foreign_sep_tl
-                \group_begin:
-                  \tl_use:N \l__acro_foreign_format_tl
-                  \tl_use:N \l__acro_foreign_tl
-                \group_end:
+                \prop_get:NnNT \l__acro_foreign_prop {#1} \l__acro_foreign_tl
+                  {
+                    \tl_use:N \l__acro_foreign_sep_tl
+                    \group_begin:
+                      \tl_use:N \l__acro_foreign_format_tl
+                      \tl_use:N \l__acro_foreign_tl
+                    \group_end:
+                  }
               }
           }
         \bool_if:nT
-          { \l__acro_first_use_brackets_bool && \l__acro_first_reversed_bool }
+          { \l__acro_group_citation_bool && !\l__acro_first_reversed_bool }
+          { \acro_group_cite:n {#1} }
+        \bool_if:nT
+          { \l__acro_first_use_brackets_bool && !\l__acro_first_only_short_bool }
           { \tl_tail:N \l__acro_first_brackets_tl }
       }
-    \__acro_cite_if:Nn \l__acro_citation_first_bool {#1}
-    \__acro_index_if:Nn \l__acro_addto_index_bool {#1}
+    \bool_if:NF \l__acro_group_citation_bool
+      { \acro_cite_if:Nn \l__acro_citation_first_bool {#1} }
+    \acro_index_if:Nn \l__acro_addto_index_bool {#1}
   }
 
 % template for footnotes, sidenotes, ...
@@ -628,13 +696,13 @@
   }
   {
     \AssignTemplateKeys
-    \__acro_indefinite:nn {#1} { short }
-    \__acro_acc_supp:nn {#1} { \__acro_write_short:n {#2} }
+    \acro_write_indefinite:nn {#1} {short}
+    \acro_acc_supp:nn {#1} { \acro_write_short:nn {#1} {#2} }
     \bool_if:NT \l__acro_use_note_bool
       {
         \__acro_note_command:n
           {
-            \__acro_write_long:No \l__acro_first_long_format_tl {#3}
+            \acro_write_long:No \l__acro_first_long_format_tl {#3}
             \bool_if:NT \l__acro_foreign_bool
               {
                 \prop_get:NnNT \l__acro_foreign_prop {#1} \l__acro_foreign_tl
@@ -648,8 +716,8 @@
                     )
                   }
               }
-            \__acro_cite_if:Nn \l__acro_citation_first_bool {#1}
-            \__acro_index_if:Nn \l__acro_addto_index_bool {#1}
+            \acro_cite_if:Nn \l__acro_citation_first_bool {#1}
+            \acro_index_if:Nn \l__acro_addto_index_bool {#1}
           }
       }
   }
@@ -727,7 +795,7 @@
       { \tl_use:N \l__acro_extra_punct_tl \tl_use:N \c_space_tl }
     \bool_if:NT \l__acro_extra_use_brackets_bool
       { \tl_head:N \l__acro_extra_brackets_tl }
-    \__acro_write_long:Nn \l__acro_extra_format_tl {#1}
+    \acro_write_long:Nn \l__acro_extra_format_tl {#1}
     \bool_if:NT \l__acro_extra_use_brackets_bool
       { \tl_tail:N \l__acro_extra_brackets_tl }
   }
@@ -963,12 +1031,12 @@
 % the title of the list:
 \cs_new:Npn \acro_list_title_format:n #1 {#1}
 
-\DeclareObjectType { acro-title } { 1 }
+\DeclareObjectType {acro-title} {1}
 
-\DeclareTemplateInterface { acro-title } { sectioning } { 1 }
+\DeclareTemplateInterface {acro-title} {sectioning} {1}
   { name-format : function 1 = #1 }
 
-\DeclareTemplateCode { acro-title } { sectioning } { 1 }
+\DeclareTemplateCode {acro-title} {sectioning} {1}
   { name-format = \acro_list_title_format:n }
   {
     \AssignTemplateKeys
@@ -976,27 +1044,31 @@
   }
 
 % the different styles:
-\DeclareInstance { acro-title } { chapter*    } { sectioning }
+\DeclareInstance {acro-title} {chapter*} {sectioning}
   { name-format = \chapter* {#1} }
-\DeclareInstance { acro-title } { part*       } { sectioning }
+\DeclareInstance {acro-title} {part*} {sectioning}
   { name-format = \part* {#1} }
-\DeclareInstance { acro-title } { section*    } { sectioning }
+\DeclareInstance {acro-title} {section*} {sectioning}
   { name-format = \section* {#1} }
-\DeclareInstance { acro-title } { subsection* } { sectioning }
+\DeclareInstance {acro-title} {subsection*} {sectioning}
   { name-format = \subsection* {#1} }
-\DeclareInstance { acro-title } { chapter     } { sectioning }
+\DeclareInstance {acro-title} {subsubsection*} {sectioning}
+  { name-format = \subsubsection* {#1} }
+\DeclareInstance {acro-title} {chapter} {sectioning}
   { name-format = \chapter {#1} }
-\DeclareInstance { acro-title } { part        } { sectioning }
+\DeclareInstance {acro-title} {part} {sectioning}
   { name-format = \part {#1} }
-\DeclareInstance { acro-title } { section     } { sectioning }
+\DeclareInstance {acro-title} {section} {sectioning}
   { name-format = \section {#1} }
-\DeclareInstance { acro-title } { subsection  } { sectioning }
+\DeclareInstance {acro-title} {subsection} {sectioning}
   { name-format = \subsection {#1} }
-\DeclareInstance { acro-title } { addchap     } { sectioning }
+\DeclareInstance {acro-title} {subsubsection} {sectioning}
+  { name-format = \subsubsection {#1} }
+\DeclareInstance {acro-title} {addchap} {sectioning}
   { name-format = \addchap {#1} }
-\DeclareInstance { acro-title } { addsec      } { sectioning }
+\DeclareInstance {acro-title} {addsec} {sectioning}
   { name-format = \addsec {#1} }
-\DeclareInstance { acro-title } { none        } { sectioning }
+\DeclareInstance {acro-title} {none} {sectioning}
   { name-format = \use_none:n {#1} }
 
 % --------------------------------------------------------------------------
@@ -1124,21 +1196,21 @@
             \acro_hyper_target:nn
               {##1}
               {
-                \__acro_acc_supp:nn
+                \acro_acc_supp:nn
                   {##1}
-                  { \__acro_write_short:n { \l__acro_list_short_format_tl { ##2 } } }
+                  { \acro_write_short:nn {##1} { \l__acro_list_short_format_tl {##2} } }
               }
           ]
       }
     \cs_set:Npn \acro_print_list_long:n ##1
       {
-        \__acro_write_long:Nf \l__acro_list_long_format_tl
+        \acro_write_long:Nf \l__acro_list_long_format_tl
           {
             \prop_if_in:NnTF \l__acro_list_prop {##1}
-              { \prop_get:Nn \l__acro_list_prop {##1} }
-              { \prop_get:Nn \l__acro_long_prop {##1} }
+              { \prop_item:Nn \l__acro_list_prop {##1} }
+              { \prop_item:Nn \l__acro_long_prop {##1} }
           }
-        \__acro_cite_if:Nn \l__acro_citation_all_bool {##1}
+        \acro_cite_if:Nn \l__acro_citation_all_bool {##1}
       }
     \cs_set_protected:Npn \acro_print_list_extra:n ##1
       {
@@ -1180,21 +1252,21 @@
         \acro_hyper_target:nn
           {##1}
           {
-            \__acro_acc_supp:nn
+            \acro_acc_supp:nn
               {##1}
-              { \__acro_write_short:n { \l__acro_list_short_format_tl { ##2 } } }
+              { \acro_write_short:nn {##1} { \l__acro_list_short_format_tl {##2} } }
           }
         &
       }
     \cs_set:Npn \acro_print_list_long:n ##1
       {
-        \__acro_write_long:Nf \l__acro_list_long_format_tl
+        \acro_write_long:Nf \l__acro_list_long_format_tl
           {
             \prop_if_in:NnTF \l__acro_list_prop {##1}
-              { \prop_get:Nn \l__acro_list_prop {##1} }
-              { \prop_get:Nn \l__acro_long_prop {##1} }
+              { \prop_item:Nn \l__acro_list_prop {##1} }
+              { \prop_item:Nn \l__acro_long_prop {##1} }
           }
-        \__acro_cite_if:Nn \l__acro_citation_all_bool {##1}
+        \acro_cite_if:Nn \l__acro_citation_all_bool {##1}
       }
     \cs_set_protected:Npn \acro_print_list_extra:n ##1
       {
@@ -1210,9 +1282,14 @@
           { \UseInstance { acro-page-number } { \l__acro_page_instance_tl } {##1} }
         \tabularnewline
       }
-    \exp_args:Noo \begin { \l__acro_list_table_tl } { \l__acro_list_table_spec_tl }
-      \acro_list_allow_items:nn {#2} {#3}
-    \exp_args:No \end { \l__acro_list_table_tl }
+    % \exp_args:Noo \begin { \l__acro_list_table_tl } { \l__acro_list_table_spec_tl }
+    %   \acro_list_allow_items:nn {#2} {#3}
+    % \exp_args:No \end { \l__acro_list_table_tl }
+    \use:x {
+      \exp_not:N \begin { \exp_not:V \l__acro_list_table_tl } { \exp_not:V \l__acro_list_table_spec_tl }
+      \exp_not:n { \acro_list_allow_items:nn {#2} {#3} }
+      \exp_not:N \end { \exp_not:V \l__acro_list_table_tl }
+    }
   }
 
 % extra-table template:
@@ -1235,21 +1312,21 @@
         \acro_hyper_target:nn
           {##1}
           {
-            \__acro_acc_supp:nn
+            \acro_acc_supp:nn
               {##1}
-              { \__acro_write_short:n { \l__acro_list_short_format_tl { ##2 } } }
+              { \acro_write_short:nn {##1} { \l__acro_list_short_format_tl {##2} } }
           }
         &
       }
     \cs_set:Npn \acro_print_list_long:n ##1
       {
-        \__acro_write_long:Nf \l__acro_list_long_format_tl
+        \acro_write_long:Nf \l__acro_list_long_format_tl
           {
             \prop_if_in:NnTF \l__acro_list_prop {##1}
-              { \prop_get:Nn \l__acro_list_prop {##1} }
-              { \prop_get:Nn \l__acro_long_prop {##1} }
+              { \prop_item:Nn \l__acro_list_prop {##1} }
+              { \prop_item:Nn \l__acro_long_prop {##1} }
           }
-        \__acro_cite_if:Nn \l__acro_citation_all_bool {##1}
+        \acro_cite_if:Nn \l__acro_citation_all_bool {##1}
         &
       }
     \cs_set_protected:Npn \acro_print_list_extra:n ##1
@@ -1267,9 +1344,11 @@
           { \UseInstance { acro-page-number } { \l__acro_page_instance_tl } {##1} }
         \tabularnewline
       }
-    \exp_args:Noo \begin { \l__acro_list_table_tl } { \l__acro_list_table_spec_tl }
+    \exp_args:Noo
+    \begin { \l__acro_list_table_tl } { \l__acro_list_table_spec_tl }
       \acro_list_allow_items:nn {#2} {#3}
-    \exp_args:No \end { \l__acro_list_table_tl }
+    \exp_args:No
+    \end { \l__acro_list_table_tl }
   }
 
 % extra-table-rev template:
@@ -1291,20 +1370,20 @@
       {
         \acro_hyper_target:nn
           {##1}
-          { \__acro_acc_supp:nn {##1} { \__acro_write_short:n { ##2 } } }
+          { \acro_acc_supp:nn {##1} { \acro_write_short:nn {##1} {##2} } }
         &
       }
     \cs_set_protected:Npn \acro_print_list_extra:n ##1
       {
         \bool_if:NT \l__acro_capitalize_list_bool
           { \bool_set_true:N \l__acro_first_upper_bool }
-        \__acro_write_long:Nf \l__acro_long_format_tl
+        \acro_write_long:Nf \l__acro_long_format_tl
           {
             \prop_if_in:NnTF \l__acro_list_prop {##1}
-              { \prop_get:Nn \l__acro_list_prop {##1} }
-              { \prop_get:Nn \l__acro_long_prop {##1} }
+              { \prop_item:Nn \l__acro_list_prop {##1} }
+              { \prop_item:Nn \l__acro_long_prop {##1} }
           }
-        \__acro_cite_if:Nn \l__acro_citation_all_bool {##1}
+        \acro_cite_if:Nn \l__acro_citation_all_bool {##1}
         &
       }
     \cs_set_protected:Npn \acro_print_list_long:n ##1
@@ -1360,20 +1439,18 @@
     \acro_is_used:nTF {#1}
       {
         % this is not the first time
-        \__acro_indefinite:nn {#1} {short}
-        \__acro_acc_supp:nn
+        \acro_write_indefinite:nn {#1} {short}
+        \acro_acc_supp:nn
           {#1}
-          { \__acro_write_short:V \l__acro_short_tl }
+          { \acro_write_short:nV {#1} \l__acro_short_tl }
+        \acro_endings:nn {#1} {short}
         \acro_after:n {#1}
       }
       {
         % this is the first time
         \bool_gset_true:c { g__acro_#1_first_use_bool }
-        \__acro_is_single:nTF {#1}
-          {
-            \__acro_indefinite:nn {#1} {long}
-            \__acro_write_long:NV \l__acro_long_format_tl \l__acro_long_tl
-          }
+        \acro_if_is_single:nTF {#1}
+          { \acro_single:n {#1} }
           { 
             \UseInstance {acro-first} { \l__acro_first_instance_tl }
               {#1}
@@ -1383,7 +1460,35 @@
       }
   }
 
-\prg_new_conditional:Npnn \__acro_is_single:n #1 { p,T,TF }
+\cs_new_protected:Npn \acro_single_form:nn #1#2
+  {
+    \acro_write_indefinite:nn {#1} {#2}
+    \str_case:nnF {#2}
+      {
+        {long} {
+          \acro_write_long:NV \l__acro_long_format_tl \l__acro_long_tl
+          \acro_endings:nn {#1} {#2}
+          \acro_cite:n {#1}
+        }
+        {first} {
+          \UseInstance {acro-first} { \l__acro_first_instance_tl }
+            {#1}
+            { \l__acro_short_tl }
+            { \l__acro_long_tl }
+        }
+      }
+      {
+        \use:c {acro_write_#2:nv} {#1} {l__acro_#2_tl}
+        \acro_endings:nn {#1} {#2}
+        \acro_cite:n {#1}
+      }
+  }
+\cs_generate_variant:Nn \acro_single_form:nn {nV}
+
+\cs_new_protected:Npn \acro_single:n #1
+  { \acro_single_form:nV {#1} \l__acro_single_form_tl }
+
+\prg_new_conditional:Npnn \acro_if_is_single:n #1 { p,T,TF }
   {
     \bool_if:nTF { !\l__acro_use_single_bool || \cs_if_exist_p:c { acro@#1@twice } }
       { \prg_return_false: } { \prg_return_true: }
@@ -1397,19 +1502,23 @@
 \cs_new_protected:Npn \acro_defined:n #1
   {
     \prop_if_in:NnF \l__acro_short_prop {#1}
-      { \acro_serious_message:nnn {acro} {undefined} {#1} }
+      { \acro_serious_message:nn {undefined} {#1} }
   }
 
 \cs_new_protected:Npn \acro_get:n #1
   {
-    \bool_if:NF \l__acro_in_list_bool
-      { \leavevmode }
-    % \acro_defined:n {#1}
+    \bool_if:NF \l__acro_in_list_bool { \leavevmode }
     \__acro_activate_hyperref_support:
+    % short:
     \prop_get:NnNF \l__acro_short_prop {#1} \l__acro_tmpa_tl {}
-    \__acro_make_link:nNN {#1} \l__acro_short_tl \l__acro_tmpa_tl
-    \prop_get:NnNF \l__acro_short_plural_prop {#1} \l__acro_short_plural_tl {}
+    \__acro_make_link:NnV \l__acro_short_tl {#1} \l__acro_tmpa_tl
+     % alt:
+    \prop_get:NnNTF \l__acro_alt_prop {#1} \l__acro_tmpa_tl
+      { \__acro_make_link:NnV \l__acro_alt_tl {#1} \l__acro_tmpa_tl }
+      { \tl_set_eq:NN \l__acro_alt_tl \l__acro_short_tl }
+    % long:
     \prop_get:NnNF \l__acro_long_prop {#1} \l__acro_long_tl {}
+    % formatting
     \prop_get:NnNTF \l__acro_long_format_prop {#1}
       \l__acro_custom_long_format_tl
       { \bool_set_true:N  \l__acro_custom_long_format_bool }
@@ -1417,31 +1526,193 @@
     \prop_get:NnNF \l__acro_first_long_format_prop {#1}
       \l__acro_first_long_format_tl
       {}% to avoid hanging compilation if first-long-format hasn't been set
-    \prop_get:NnNT \l__acro_long_pre_prop {#1} \l__acro_long_pre_tl
-      { \tl_put_left:NV \l__acro_long_tl \l__acro_long_pre_tl }
-    \prop_get:NnNF \l__acro_alt_prop {#1} \l__acro_tmpb_tl {}
-    \__acro_make_link:nNN {#1} \l__acro_alt_tl \l__acro_tmpb_tl
     \prop_get:NnNTF \l__acro_format_prop {#1} \l__acro_custom_format_tl
       { \bool_set_true:N \l__acro_custom_format_bool }
       { \bool_set_false:N \l__acro_custom_format_bool }
-    \__acro_set_plural:n {#1}
+    \seq_map_inline:Nn \l__acro_endings_seq
+      {
+        \bool_if:cT {l__acro_##1_bool}
+          { \__acro_set_ending_for:nnn {##1} {#1} {long} }
+      }
     \prop_get:NnNT \l__acro_long_post_prop {#1} \l__acro_long_post_tl
       { \tl_put_right:NV \l__acro_long_tl \l__acro_long_post_tl }
+    \prop_get:NnNT \l__acro_long_pre_prop {#1} \l__acro_long_pre_tl
+      { \tl_put_left:NV \l__acro_long_tl \l__acro_long_pre_tl }
+  }
+
+% --------------------------------------------------------------------------
+% plural endings and similar concepts:
+\seq_new:N \l__acro_endings_seq
+
+% #1: ending
+% #2: ID
+\cs_new_protected:Npn \__acro_set_ending:nn #1#2
+  {
+    \bool_if:cT {l__acro_#1_bool}
+      {
+        \__acro_set_ending_for:nnn {#1} {#2} {short}
+        \__acro_set_ending_for:nnn {#1} {#2} {alt}
+        \__acro_set_ending_for:nnn {#1} {#2} {long}
+      }
   }
 
-\cs_new_protected:Npn \__acro_set_plural:n #1
+\tl_new:N \l__acro_endings_tl
+
+% #1: ending
+% #2: id
+% #3: short|alt|long
+\cs_new_protected:Npn \__acro_set_ending_for:nnn #1#2#3
   {
-    \bool_if:NT \l__acro_use_plural_bool
+    \bool_if:nTF { \prop_item:cn {l__acro_#3_#1_form_prop} {#2} }
+      { \prop_get:cncF {l__acro_#3_#1_prop} {#2} {l__acro_#3_tl} {} }
       {
-        \bool_if:nTF { \prop_get:Nn \l__acro_long_plural_form_prop {#1} }
-          { \prop_get:NnNF \l__acro_long_plural_prop {#1} \l__acro_long_tl {} }
+        \tl_set:cx {l__acro_#3_#1_tl}
+          { \prop_item:cn {l__acro_#3_#1_prop} {#2} }
+      }
+  }
+
+\cs_new_protected:Npn \__acro_set_endings:n #1
+  {
+    \seq_map_inline:Nn \l__acro_endings_seq
+      { \__acro_set_ending:nn {##1} {#1} }
+  }
+
+\cs_new_protected:Npn \acro_endings:nn #1#2
+  {
+    \group_begin:
+      \bool_if:NTF \l__acro_include_endings_format_bool
+        {
+          \bool_if:NTF \l__acro_custom_format_bool
+            { \l__acro_custom_format_tl }
+            { \tl_use:c {l__acro_#2_format_tl} }
+        }
+        { \use:n }
+        {
+          \seq_map_inline:Nn \l__acro_endings_seq
+            {
+              \__acro_set_ending_for:nnn {##1} {#1} {#2}
+              \bool_if:cT {l__acro_##1_bool}
+                { \tl_use:c {l__acro_#2_##1_tl} }
+            }
+        }
+    \group_end:
+  }
+
+% #1: name
+% #2: default short
+% #3: default long
+\cs_new_protected:Npn \acro_provide_ending:nnn #1#2#3
+  {
+    \seq_if_in:NnTF \l__acro_endings_seq {#1}
+      { \acro_harmless_message:nn {ending-exists} {#1} }
+      {
+        % registering:
+        \bool_if:NT \g__acro_first_acronym_declared_bool
+          { \acro_serious_message:n {ending-before-acronyms} }
+        \seq_put_right:Nn \l__acro_endings_seq {#1}
+        \bool_new:c {l__acro_#1_bool}
+        % short variables
+        \acro_define_and_set_ending_variables:nnn {short} {#1} {#2}
+        % alt variables
+        \acro_define_and_set_ending_variables:nnn {alt} {#1} {#2}
+        % long variables
+        \acro_define_and_set_ending_variables:nnn {long} {#1} {#3}
+        % define setup command:
+        \tl_set:Nn \l__acro_tmpa_tl {#1}
+        \tl_replace_all:Nnn \l__acro_tmpa_tl {-} {_}
+        \cs_new_protected:cpn {acro_ \l__acro_tmpa_tl :}
+          { \bool_set_true:c {l__acro_#1_bool} }
+        % acronym properties:
+        % short-<ending>:
+        \acro_declare_key:nnn {short_#1} {short-#1}
+          {
+            \prop_put:cnn {l__acro_short_#1_form_prop} {##1} { \c_false_bool }
+            \prop_put:cnx {l__acro_pdfstring_short_#1_prop}
+              {##1} { \prop_get:Nn \l__acro_short_prop {##1} \exp_not:n {##2} }
+          }
+        % short-<ending>-form:
+        \acro_declare_key_generic:nnn {short_#1_form} {short-#1-form}
+          {
+            \__acro_key_check:nn {##1} {short-#1-form}
+            \prop_put:cnn {l__acro_short_#1_form_prop} {##1} { \c_true_bool }
+            \prop_put:cnn {l__acro_short_#1_prop} {##1} {##2}
+            \prop_put:cnn {l__acro_pdfstring_short_#1_prop} {##1} {##2}
+          }
+        % alt-<ending>:
+        \acro_declare_key:nnn {alt_#1} {alt-#1}
+          {
+            \prop_put:cnn {l__acro_alt_#1_form_prop} {##1} { \c_false_bool }
+            \prop_put:cnx {l__acro_pdfstring_alt_#1_prop}
+              {##1} { \prop_get:Nn \l__acro_alt_prop {##1} \exp_not:n {##2} }
+          }
+        % alt-<ending>-form:
+        \acro_declare_key_generic:nnn {alt_#1_form} {alt-#1-form}
+          {
+            \__acro_key_check:nn {##1} {alt-#1-form}
+            \prop_put:cnn {l__acro_alt_#1_form_prop} {##1} { \c_true_bool }
+            \prop_put:cnn {l__acro_alt_#1_prop} {##1} {##2}
+            \prop_put:cnn {l__acro_pdfstring_alt_#1_prop} {##1} {##2}
+          }
+        % long-<ending>:
+        \acro_declare_key:nnn {long_#1} {long-#1}
+          { \prop_put:cnn {l__acro_long_#1_form_prop} {##1} { \c_false_bool } }
+        % long-<ending>-form:
+        \acro_declare_key_generic:nnn {long_#1_form} {long-#1-form}
+          {
+            \__acro_key_check:nn {##1} {long-#1-form}
+            \prop_put:cnn {l__acro_long_#1_form_prop} {##1} { \c_true_bool }
+            \prop_put:cnn {l__acro_long_#1_prop} {##1} {##2}
+          }
+        % options:
+        %   short-<ending>-ending
+        %   alt-<ending>-ending
+        %   long-<ending>-ending
+        %   <ending>-ending
+        \keys_define:nn {acro}
+          {
+            short-#1-ending .tl_set:c = {l__acro_default_short_#1_tl} ,
+            alt-#1-ending   .tl_set:c = {l__acro_default_alt_#1_tl} ,
+            long-#1-ending  .tl_set:c = {l__acro_default_long_#1_tl} ,
+            #1-ending       .code:n   =
+              \tl_set:cn {l__acro_default_short_#1_tl} {##1}
+              \tl_set:cn {l__acro_default_alt_#1_tl} {##1}
+              \tl_set:cn {l__acro_default_long_#1_tl}  {##1}
+          }
+        % pdfstrings:
+        \prop_new:c {l__acro_pdfstring_short_#1_prop}
+        \cs_new:cpn {acro_pdf_string_short_#1:n} ##1
+          {
+            \acro_if_star_gobble:nTF {##1}
+              { \prop_item:cn {l__acro_pdfstring_short_#1_prop} }
+              { \prop_item:cn {l__acro_pdfstring_short_#1_prop} {##1} }
+          }
+        \cs_new:cpn {acpdfstring#1} { \use:c {acro_pdf_string_short_#1:n} }
+        \prop_new:c {l__acro_pdfstring_alt_#1_prop}
+        \cs_new:cpn {acro_pdf_string_alt_#1:n} ##1
           {
-            \tl_put_right:Nn \l__acro_long_tl
-              { \prop_get:Nn \l__acro_long_plural_prop {#1} }
+            \acro_if_star_gobble:nTF {##1}
+              { \prop_item:cn {l__acro_pdfstring_alt_#1_prop} }
+              { \prop_item:cn {l__acro_pdfstring_alt_#1_prop} {##1} }
           }
+        \cs_new:cpn {acpdfstringalt#1} { \use:c {acro_pdf_string_alt_#1:n} }
       }
   }
 
+% #1: short|alt|long
+% #2: ending
+% #3: default ending
+\cs_new_protected:Npn \acro_define_and_set_ending_variables:nnn #1#2#3
+  {
+    \prop_new:c {l__acro_#1_#2_prop}
+    \prop_new:c {l__acro_#1_#2_form_prop}
+    \tl_new:c   {l__acro_#1_#2_tl}
+    \tl_new:c   {l__acro_default_#1_#2_tl}
+    \tl_set:cn  {l__acro_default_#1_#2_tl} {#3}
+  }
+  
+\NewDocumentCommand \ProvideAcroEnding {mmm}
+  { \acro_provide_ending:nnn {#1} {#2} {#3} }
+
 % --------------------------------------------------------------------------
 % enable us to know if the acronym is used only once and provide a different
 % style for that:
@@ -1585,7 +1856,8 @@
         \token_to_str:N \providecommand \token_to_str:N \acro@used@once [4] {} ^^J
         \token_to_str:N \providecommand \token_to_str:N \acro@used@twice [4] {} ^^J
         \token_to_str:N \providecommand \token_to_str:N \acro@pages [2] {} ^^J
-        \token_to_str:N \providecommand \token_to_str:N \acro@rerun@check {}
+        \token_to_str:N \providecommand \token_to_str:N \acro@rerun@check {} ^^J
+        \token_to_str:N \providecommand \token_to_str:N \acro@print@list {}
       }
   }
 \fi
@@ -1593,8 +1865,8 @@
 % --------------------------------------------------------------------------
 \cs_new:Npn \acro_after:n #1
   {
-    \__acro_cite_if:Nn \l__acro_citation_all_bool {#1}
-    \__acro_index_if:Nn \l__acro_addto_index_bool {#1}
+    \acro_cite_if:Nn \l__acro_citation_all_bool {#1}
+    \acro_index_if:Nn \l__acro_addto_index_bool {#1}
   }
 
 % the standard internals:
@@ -1602,12 +1874,13 @@
   {
     \acro_get:n {#1}
     \acro_is_used:n {#1}
-    \__acro_indefinite:nn {#1} { short }
-    \__acro_is_single:nT {#1}
+    \acro_write_indefinite:nn {#1} {short}
+    \acro_if_is_single:nT {#1}
       { \cs_set_eq:NN \acro_hyper_link:nn \use_ii:nn }
-    \__acro_acc_supp:nn
+    \acro_acc_supp:nn
       {#1}
-      { \__acro_write_short:V \l__acro_short_tl }
+      { \acro_write_short:nV {#1} \l__acro_short_tl }
+    \acro_endings:nn {#1} {short}
     \acro_after:n {#1}
   }
 
@@ -1616,12 +1889,14 @@
   {
     \acro_get:n {#1}
     \acro_is_used:n {#1}
-    \__acro_indefinite:nn {#1} { alt }
-    \__acro_is_single:nT {#1}
+    \acro_alt_error:n {#1}
+    \acro_write_indefinite:nn {#1} {alt}
+    \acro_if_is_single:nT {#1}
       { \cs_set_eq:NN \acro_hyper_link:nn \use_ii:nn }
-    \__acro_acc_supp:nn
+    \acro_acc_supp:nn
       {#1}
-      { \__acro_write_short:V \l__acro_alt_tl }
+      { \acro_write_alt:nV {#1} \l__acro_alt_tl }
+    \acro_endings:nn {#1} {alt}
     \acro_after:n {#1}
   }
 
@@ -1630,10 +1905,11 @@
   {
     \acro_get:n {#1}
     \acro_is_used:n {#1}
-    \__acro_indefinite:nn {#1} { long }
-    \__acro_is_single:nT {#1}
+    \acro_write_indefinite:nn {#1} {long}
+    \acro_if_is_single:nT {#1}
       { \cs_set_eq:NN \acro_hyper_link:nn \use_ii:nn }
-    \__acro_write_long:NV \l__acro_long_format_tl \l__acro_long_tl
+    \acro_write_long:NV \l__acro_long_format_tl \l__acro_long_tl
+    \acro_endings:nn {#1} {long}
     \acro_after:n {#1}
   }
 
@@ -1643,9 +1919,9 @@
     \bool_gset_true:c { g__acro_#1_first_use_bool }
     \acro_get:n {#1}
     \acro_is_used:n {#1}
-    \__acro_is_single:nT {#1}
+    \acro_if_is_single:nT {#1}
       { \cs_set_eq:NN \acro_hyper_link:nn \use_ii:nn }
-    \UseInstance { acro-first } { \l__acro_first_instance_tl }
+    \UseInstance {acro-first} { \l__acro_first_instance_tl }
       {#1}
       { \l__acro_short_tl }
       { \l__acro_long_tl }
@@ -1657,7 +1933,7 @@
     \bool_gset_true:c { g__acro_#1_first_use_bool }
     \acro_get:n {#1}
     \acro_is_used:n {#1}
-    \__acro_is_single:nT {#1}
+    \acro_if_is_single:nT {#1}
       { \cs_set_eq:NN \acro_hyper_link:nn \use_ii:nn }
     \UseInstance { acro-first } { \l__acro_first_instance_tl }
       {#1}
@@ -1668,9 +1944,7 @@
 % ----------------------------------------------------------------------------
 % citations:
 \cs_new:Npn \__acro_citation_cmd:w { \cite } %{}
-
-\cs_new_protected:Npn \acro_cite:
-  { \bool_set_true:N \l__acro_citation_all_bool }
+\cs_new:Npn \__acro_group_citation_cmd:w { \cite } %{}
 
 % #1 pre
 % #2 post
@@ -1687,27 +1961,38 @@
   }
 \cs_generate_variant:Nn \__acro_cite:nnn { VVV }
 
-\cs_new_protected:Npn \__acro_cite_if:Nn #1#2
+\cs_new_protected:Npn \acro_cite:n #1
   {
-    \bool_if:NT #1
+    \prop_get:NnNT \l__acro_citation_prop {#1} \l__acro_tmpa_tl
       {
-        \prop_get:NnNT \l__acro_citation_prop {#2} \l__acro_tmpa_tl
-          {
-            \prop_get:NnN \l__acro_citation_pre_prop {#2} \l__acro_tmpb_tl
-            \prop_get:NnN \l__acro_citation_post_prop {#2} \l__acro_tmpc_tl
-            \acro_no_break:
-            \tl_use:N \l__acro_citation_space_tl
-            \__acro_cite:VVV
-              \l__acro_tmpb_tl
-              \l__acro_tmpc_tl
-              \l__acro_tmpa_tl
-          }
+        \prop_get:NnN \l__acro_citation_pre_prop {#1} \l__acro_tmpb_tl
+        \prop_get:NnN \l__acro_citation_post_prop {#1} \l__acro_tmpc_tl
+        \acro_no_break:
+        \tl_use:N \l__acro_citation_connect_tl
+        \__acro_cite:VVV
+          \l__acro_tmpb_tl
+          \l__acro_tmpc_tl
+          \l__acro_tmpa_tl
       }
   }
 
+\cs_new_protected:Npn \acro_group_cite:n #1
+  {
+    \group_begin:
+      \cs_set_eq:NN \__acro_citation_cmd:w \__acro_group_citation_cmd:w
+      \tl_set_eq:NN
+        \l__acro_citation_connect_tl
+        \l__acro_between_group_connect_citation_tl
+      \acro_cite_if:Nn \l__acro_citation_first_bool {#1}
+    \group_end:
+  }
+
+\cs_new_protected:Npn \acro_cite_if:Nn #1#2
+  { \bool_if:NT #1 { \acro_cite:n {#2} } }
+
 % ----------------------------------------------------------------------------
 % indexing:
-\cs_new_protected:Npn \__acro_index_if:Nn #1#2
+\cs_new_protected:Npn \acro_index_if:Nn #1#2
   {
     \bool_if:nT { #1 && \l__acro_mark_as_used_bool }
       {
@@ -1722,9 +2007,6 @@
       }
   }
 
-\cs_new_protected:Npn \acro_index:
-  { \bool_set_true:N \l__acro_addto_index_bool }
-
 \cs_new:Npn \__acro_index_cmd:n { \index }
 
 % #1: cmd
@@ -1752,50 +2034,60 @@
 
 % ----------------------------------------------------------------------------
 % accessability support
-\cs_new_eq:NN \__acro_acc_supp:nn \use_ii:nn
+\cs_new_eq:NN \acro_acc_supp:nn \use_ii:nn
 
-\cs_new:Npn \acro_acc_supp:nnn #1#2#3
+\cs_new_protected:Npn \acro_get_acc_supp:nn #1#2
+  {
+    \prop_get:NnNF \l__acro_acc_supp_prop {#1} \l__acro_acc_supp_tl
+      { \prop_get:NnNF \l__acro_short_prop {#1} \l__acro_acc_supp_tl {} }
+    \seq_map_inline:Nn \l__acro_endings_seq
+      {
+        \bool_if:cT {l__acro_##1_bool}
+          {
+            \tl_put_right:Nv
+              \l__acro_acc_supp_tl
+              {l__acro_short_##1_tl}
+          }
+      }
+    \acro_do_acc_supp:VVn
+      \l__acro_acc_supp_tl
+      \l__acro_acc_supp_options_tl
+      {#2}
+  }
+
+\cs_new:Npn \acro_do_acc_supp:nnn #1#2#3
   {
     \BeginAccSupp { ActualText = #1 , #2 }
       #3
     \EndAccSupp { }
   }
-\cs_generate_variant:Nn \acro_acc_supp:nnn { VV }
+\cs_generate_variant:Nn \acro_do_acc_supp:nnn { VV }
+
+% macro to redefine to adapt definition of \acro_acc_supp:nn, for cases like
+% http://tex.stackexchange.com/a/161521/
+\cs_new_protected:Npn \acro_set_accsupp:
+  { \cs_set_eq:NN \acro_acc_supp:nn \acro_get_acc_supp:nn }
 
 \AtBeginDocument
   {
     \bool_if:NT \l__acro_acc_supp_bool
       {
-        \RequirePackage { accsupp }
-        \cs_set_protected:Npn \__acro_acc_supp:nn #1#2
-          {
-            \prop_get:NnNF \l__acro_acc_supp_prop {#1} \l__acro_acc_supp_tl
-              { \prop_get:NnNF \l__acro_short_prop {#1} \l__acro_acc_supp_tl {} }
-            \bool_if:NT \l__acro_use_plural_bool
-              { \tl_put_right:NV \l__acro_acc_supp_tl \l__acro_short_plural_tl }
-            \acro_acc_supp:VVn
-              \l__acro_acc_supp_tl
-              \l__acro_acc_supp_options_tl
-              {#2}
-          }
+        \RequirePackage {accsupp}
+        \acro_set_accsupp:
       }
   }
 
 % --------------------------------------------------------------------------
 % indefinite articles:
-\cs_new_protected:Npn \acro_indefinite:
-  {
-    \bool_if:NTF \l__acro_first_upper_bool
-      { \bool_set_true:N \l__acro_upper_indefinite_bool }
-      { \bool_set_true:N \l__acro_indefinite_bool }
-  }
 
-\cs_new_protected:Npn \__acro_indefinite:nn #1#2
+% #1: ID
+% #2: short|long|alt
+\cs_new_protected:Npn \acro_write_indefinite:nn #1#2
   {
     \bool_if:NT \l__acro_indefinite_bool
       { \prop_get:cn { l__acro_#2_indefinite_prop } {#1} ~ }
     \bool_if:NT \l__acro_upper_indefinite_bool
-      {
+      { %  \bool_set_true:N \l__acro_first_upper_bool
          \__acro_first_upper_case:x
            { \prop_get:cn { l__acro_#2_indefinite_prop } {#1} } ~
       }
@@ -1889,407 +2181,466 @@
   { \cs_if_exist:NF \acro@printed@list { \cs_new:Npn \acro@printed@list { printed } } }
 
 % --------------------------------------------------------------------------
-% the user commands:
-% #1: ID
-% #2: true|false
-\cs_new_protected:Npn \acro_check_acronym:nn #1#2
+% trailing tokens and what to do when present
+\prop_new:N \l__acro_trailing_tokens_prop
+\prop_new:N \l__acro_trailing_actions_prop
+\bool_new:N \l__acro_trailing_tokens_bool
+\tl_new:N   \l__acro_trailing_tokens_tl
+
+\cs_new_protected:Npn \acro_new_trailing_token:n #1
+  { \bool_new:c {l__acro_trailing_#1_bool} }
+\cs_new_protected:Npn \acro_activate_trailing_action:n #1
+  { \bool_set_true:c {l__acro_trailing_#1_bool} }
+\cs_new_protected:Npn \acro_deactivate_trailing_action:n #1
+  { \bool_set_false:c {l__acro_trailing_#1_bool} }
+
+% register a new token but don't activate its action:
+% #1: token
+% #2: name
+\cs_new_protected:Npn \acro_register_trailing_token:Nn #1#2
   {
-    \acro_defined:n {#1}
-    \acro_use_acronym:n {#2}
+    \prop_put:Nnn \l__acro_trailing_tokens_prop {#2} {#1}
+    \prop_put:Nnn \l__acro_trailing_actions_prop {#1}
+      { \acro_activate_trailing_action:n {#2} }
+    \acro_new_trailing_token:n {#2}
   }
 
-% automatic:
-\NewDocumentCommand \ac { sm }
+\NewDocumentCommand \AcroRegisterTrailing {mm}
+  { \acro_register_trailing_token:Nn #1 {#2} }
+
+% activate a token:
+\cs_new_protected:Npn \acro_activate_trailing_token:n #1
   {
-    \group_begin:
-      \IfBooleanTF #1
-        { \acro_check_acronym:nn {#2} {false} }
-        { \acro_check_acronym:nn {#2} {true} }
-      \acro_use:n {#2}
-    \group_end:
+    \prop_get:NnN \l__acro_trailing_tokens_prop {#1} \l__acro_tmpa_tl
+    \tl_put_right:NV \l__acro_trailing_tokens_tl \l__acro_tmpa_tl
   }
 
-\NewDocumentCommand \iac { sm }
+% deactivate a token:
+\cs_new_protected:Npn \acro_deactivate_trailing_token:n #1
   {
-    \group_begin:
-      \IfBooleanTF #1
-        { \acro_check_acronym:nn {#2} {false} }
-        { \acro_check_acronym:nn {#2} {true} }
-      \acro_indefinite:
-      \acro_use:n {#2}
-    \group_end:
+    \prop_get:NnN \l__acro_trailing_tokens_prop {#1} \l__acro_tmpa_tl
+    \tl_remove_all:NV \l__acro_trailing_tokens_tl \l__acro_tmpa_tl
   }
 
-\NewDocumentCommand \Iac { sm }
+% #1: name
+\prg_new_conditional:Npnn \acro_if_trailing_token:n #1 {p,T,F,TF}
   {
-    \group_begin:
-      \IfBooleanTF #1
-        { \acro_check_acronym:nn {#2} {false} }
-        { \acro_check_acronym:nn {#2} {true} }
-      \acro_upper:
-      \acro_indefinite:
-      \acro_use:n {#2}
-    \group_end:
+    \bool_if:cTF {l__acro_trailing_#1_bool}
+      { \prg_return_true: }
+      { \prg_return_false: }
   }
 
-\NewDocumentCommand \Ac { sm }
+% #1: csv list of names
+\prg_new_protected_conditional:Npnn \acro_if_trailing_tokens:n #1 {T,F,TF}
   {
-    \group_begin:
-      \IfBooleanTF #1
-        { \acro_check_acronym:nn {#2} {false} }
-        { \acro_check_acronym:nn {#2} {true} }
-      \acro_upper:
-      \acro_use:n {#2}
-    \group_end:
+    \bool_set_false:N \l__acro_trailing_tokens_bool
+    \clist_map_inline:nn {#1}
+      {
+        \bool_if:cT {l__acro_trailing_##1_bool}
+          {
+            \bool_set_true:N \l__acro_trailing_tokens_bool
+            \clist_map_break:
+          }
+      }
+    \bool_if:NTF \l__acro_trailing_tokens_bool
+      { \prg_return_true: }
+      { \prg_return_false: }
   }
 
-\NewDocumentCommand \acp { sm }
+\cs_new_protected:Npn \aciftrailing { \acro_if_trailing_tokens:nTF }
+
+\cs_new_protected:Npn \acro_treat_trail:
   {
-    \group_begin:
-      \IfBooleanTF #1
-        { \acro_check_acronym:nn {#2} {false} }
-        { \acro_check_acronym:nn {#2} {true} }
-      \acro_plural:
-      \acro_use:n {#2}
-    \group_end:
+    \tl_map_inline:Nn \l__acro_trailing_tokens_tl
+      {
+        \token_if_eq_meaning:NNT \l_peek_token ##1
+          { \prop_get:Nn \l__acro_trailing_actions_prop {##1} }
+      }
   }
 
-\NewDocumentCommand \Acp { sm }
+% register some tokens to be checked for:
+\AcroRegisterTrailing . {dot}
+\AcroRegisterTrailing - {dash}
+\AcroRegisterTrailing \babelhyphen {babel-hyphen}
+
+% options for activating actions:
+\keys_define:nn {acro}
   {
-    \group_begin:
-      \IfBooleanTF #1
-        { \acro_check_acronym:nn {#2} {false} }
-        { \acro_check_acronym:nn {#2} {true} }
-      \acro_plural:
-      \acro_upper:
-      \acro_use:n {#2}
-    \group_end:
+    activate-trailing-tokens   .code:n =
+      \clist_map_inline:nn {#1} { \acro_activate_trailing_token:n {##1} } ,
+    activate-trailing-tokens   .initial:n = dot ,
+    deactivate-trailing-tokens .code:n =
+      \clist_map_inline:nn {#1} { \acro_deactivate_trailing_token:n {##1} }
   }
 
-% short:
-\NewDocumentCommand \acs { sm }
+% some user macros:
+\cs_new_protected:Npn \acro_dot: { \aciftrailing {dot} {} {.} }
+\cs_new_eq:NN \acdot \acro_dot:
+
+\cs_new_protected:Npn \acro_space:
+  { \aciftrailing {dash,babel-hyphen} {} {\space} }
+\cs_new_eq:NN \acspace \acro_space:
+
+% ---------------------------------------------------------------------------
+% reset outputs, they'll behave like the first time again (!not like the _only_
+% time!):
+\cs_new_protected:Npn \acro_reset:n #1
   {
-    \group_begin:
-      \IfBooleanTF #1
-        { \acro_check_acronym:nn {#2} {false} }
-        { \acro_check_acronym:nn {#2} {true} }
-      \acro_short:n {#2}
-    \group_end:
+    \bool_gset_false:c { g__acro_#1_used_bool }
+    \bool_gset_false:c { g__acro_#1_first_use_bool }
   }
 
-\NewDocumentCommand \iacs { sm }
+\cs_new_protected:Npn \acro_mark_as_used:n #1
   {
-    \group_begin:
-      \IfBooleanTF #1
-        { \acro_check_acronym:nn {#2} {false} }
-        { \acro_check_acronym:nn {#2} {true} }
-      \acro_indefinite:
-      \acro_short:n {#2}
-    \group_end:
+    \bool_gset_true:c { g__acro_#1_used_bool }
+    \bool_gset_true:c { g__acro_#1_first_use_bool }
+    \bool_gset_true:c { g__acro_#1_in_list_bool }
+    \if@filesw
+      \iow_shipout_x:Nn \@auxout
+        { \token_to_str:N \acro@used@once {#1} {} {} {} }
+      \iow_shipout_x:Nn \@auxout
+        { \token_to_str:N \acro@used@twice {#1} {} {} {} }
+    \fi
   }
 
-\NewDocumentCommand \Iacs { sm }
+
+\cs_new_protected:Npn \acro_reset_all:
+  { \prop_map_inline:Nn \l__acro_short_prop { \acro_reset:n {##1} } }
+
+\cs_new_protected:Npn \acro_mark_all_as_used:
+  { \prop_map_inline:Nn \l__acro_short_prop { \acro_mark_as_used:n {##1} } }
+
+\DeclareExpandableDocumentCommand \acifused { m }
+  { \acro_if_acronym_used:nTF {#1} }
+
+\prg_new_conditional:Npnn \acro_if_acronym_used:n #1 { p,T,F,TF }
   {
-    \group_begin:
-      \IfBooleanTF #1
-        { \acro_check_acronym:nn {#2} {false} }
-        { \acro_check_acronym:nn {#2} {true} }
-      \acro_upper:
-      \acro_indefinite:
-      \acro_short:n {#2}
-    \group_end:
+    \bool_if:nTF
+      {
+        \bool_if_p:c { g__acro_#1_used_bool } &&
+        ( !\__acro_is_single_p:n {#1} )
+      }
+      { \prg_return_true: }
+      { \prg_return_false: }
   }
 
-\NewDocumentCommand \acsp { sm }
+\NewDocumentCommand \acresetall {}
+  { \acro_reset_all: }
+
+\NewDocumentCommand \acuseall {}
+  { \acro_mark_all_as_used: }
+
+\NewDocumentCommand \acreset { > { \SplitList { , } } m }
+  { \ProcessList {#1} { \acro_reset:n } \ignorespaces }
+
+\NewDocumentCommand \acuse { > { \SplitList { , } } m }
+  { \ProcessList {#1} { \acro_mark_as_used:n } \ignorespaces }
+
+% --------------------------------------------------------------------------
+% the user commands -- preparation:
+\cs_new_protected:Npn \acro_begin:
   {
     \group_begin:
-      \IfBooleanTF #1
-        { \acro_check_acronym:nn {#2} {false} }
-        { \acro_check_acronym:nn {#2} {true} }
-      \acro_plural:
-      \acro_short:n {#2}
-    \group_end:
+    \__acro_check_after_end:w
   }
 
-% alt:
-\NewDocumentCommand \aca { sm }
+\cs_new_protected:Npn \__acro_check_after_end:w #1 \acro_end:
   {
-    \group_begin:
-      \IfBooleanTF #1
-        { \acro_check_acronym:nn {#2} {false} }
-        { \acro_check_acronym:nn {#2} {true} }
-      \acro_alt:n {#2}
-    \group_end:
+    \cs_set:Npn \__acro_execute:
+      {
+        \acro_treat_trail:
+        #1
+        \acro_end: % this will end the group opened by \acro_begin:
+      }
+    \peek_after:Nw \__acro_execute:
   }
 
-\NewDocumentCommand \iaca { sm }
+\cs_new_protected:Npn \acro_end: { \group_end: }
+
+% #1: ID
+% #2: true|false
+\cs_new_protected:Npn \acro_check_acronym:nn #1#2
   {
-    \group_begin:
-      \IfBooleanTF #1
-        { \acro_check_acronym:nn {#2} {false} }
-        { \acro_check_acronym:nn {#2} {true} }
-      \acro_indefinite:
-      \acro_alt:n {#2}
-    \group_end:
+    \acro_defined:n {#1}
+    \acro_use_acronym:n {#2}
   }
 
-\NewDocumentCommand \Iaca { sm }
+% #1: boolean
+% #2: ID
+\cs_new_protected:Npn \acro_check_and_mark_if:nn #1#2
   {
-    \group_begin:
-      \IfBooleanTF #1
-        { \acro_check_acronym:nn {#2} {false} }
-        { \acro_check_acronym:nn {#2} {true} }
-      \acro_upper:
-      \acro_indefinite:
-      \acro_alt:n {#2}
-    \group_end:
+    \bool_if:nTF {#1}
+      { \acro_check_acronym:nn {#2} {false} }
+      { \acro_check_acronym:nn {#2} {true} }
   }
 
-\NewDocumentCommand \acap { sm }
+% commands for (re)defining \ac-like macros:
+\cs_new_protected:Npn \acro_define_new_acro_command:NN #1#2
   {
-    \group_begin:
-      \IfBooleanTF #1
-        { \acro_check_acronym:nn {#2} {false} }
-        { \acro_check_acronym:nn {#2} {true} }
-      \acro_plural:
-      \acro_alt:n {#2}
-    \group_end:
+    % #1: csname
+    % #2: definition where `#1' refers to the ID
+    \cs_new_protected:Npn #1 ##1##2
+      {
+        \cs_set:Npn \__acro_tmp_command:n ####1 {##2}
+        \exp_args:NNnx #2 ##1 {sm}
+          {
+            \acro_begin:
+              \acro_check_and_mark_if:nn {########1} {########2}
+              \exp_not:o { \__acro_tmp_command:n {####2} }
+            \acro_end:
+          }
+      }
   }
+\cs_generate_variant:Nn \acro_define_new_acro_command:NN {cc}
 
-% long:
-\NewDocumentCommand \acl { sm }
+% commands for (re)defining \acflike-like macros:
+\cs_new_protected:Npn \acro_define_new_acro_pseudo_command:NN #1#2
   {
-    \group_begin:
-      \IfBooleanTF #1
-        { \acro_check_acronym:nn {#2} {false} }
-        { \acro_check_acronym:nn {#2} {true} }
-      \acro_long:n {#2}
-    \group_end:
+    % #1: csname
+    % #2: definition where `#1' refers to the ID and `#2' to the pseudo long form
+    \cs_new_protected:Npn #1 ##1##2
+      {
+        \cs_set:Npn \__acro_tmp_command:nn ####1####2 {##2}
+        \exp_args:NNnx #2 ##1 {smm}
+          {
+            \acro_begin:
+              \acro_check_and_mark_if:nn {########1} {########2}
+              \exp_not:o { \__acro_tmp_command:nn {####2} {####3} }
+            \acro_end:
+          }
+      }
   }
+\cs_generate_variant:Nn \acro_define_new_acro_pseudo_command:NN {cc}
 
-\NewDocumentCommand \iacl { sm }
+\clist_map_inline:nn {New,Renew,Declare,Provide}
   {
-    \group_begin:
-      \IfBooleanTF #1
-        { \acro_check_acronym:nn {#2} {false} }
-        { \acro_check_acronym:nn {#2} {true} }
-      \acro_indefinite:
-      \acro_long:n {#2}
-    \group_end:
+    \acro_define_new_acro_command:cc
+      {#1AcroCommand}
+      {#1DocumentCommand}
+    \acro_define_new_acro_pseudo_command:cc
+      {#1PseudoAcroCommand}
+      {#1DocumentCommand}
   }
 
-\NewDocumentCommand \Iacl { sm }
+% --------------------------------------------------------------------------
+% user commands -- facilities
+\cs_new_protected:Npn \acro_first_upper:
   {
-    \group_begin:
-      \IfBooleanTF #1
-        { \acro_check_acronym:nn {#2} {false} }
-        { \acro_check_acronym:nn {#2} {true} }
-      \acro_upper:
-      \acro_indefinite:
-      \acro_long:n {#2}
-    \group_end:
+    \bool_if:NTF \l__acro_indefinite_bool
+      {
+        \bool_set_false:N \l__acro_indefinite_bool
+        \bool_set_true:N \l__acro_upper_indefinite_bool
+      }
+      { \bool_set_true:N \l__acro_first_upper_bool }
   }
 
-\NewDocumentCommand \Acl { sm }
+\cs_new_protected:Npn \acro_indefinite:
   {
-    \group_begin:
-      \IfBooleanTF #1
-        { \acro_check_acronym:nn {#2} {false} }
-        { \acro_check_acronym:nn {#2} {true} }
-      \acro_upper:
-      \acro_long:n {#2}
-    \group_end:
+    \bool_if:NTF \l__acro_first_upper_bool
+      {
+        \bool_set_true:N \l__acro_upper_indefinite_bool
+        \bool_set_false:N \l__acro_first_upper_bool
+      }
+      { \bool_set_true:N \l__acro_indefinite_bool }
   }
 
-\NewDocumentCommand \aclp { sm }
+\cs_new_protected:Npn \acro_cite:
   {
-    \group_begin:
-      \IfBooleanTF #1
-        { \acro_check_acronym:nn {#2} {false} }
-        { \acro_check_acronym:nn {#2} {true} }
-      \acro_plural:
-      \acro_long:n {#2}
-    \group_end:
+    \bool_set_true:N \l__acro_citation_all_bool
+    \bool_set_true:N \l__acro_citation_first_bool
   }
 
-\NewDocumentCommand \Aclp { sm }
+\cs_new_protected:Npn \acro_no_cite:
   {
-    \group_begin:
-      \IfBooleanTF #1
-        { \acro_check_acronym:nn {#2} {false} }
-        { \acro_check_acronym:nn {#2} {true} }
-      \acro_plural:
-      \acro_upper:
-      \acro_long:n {#2}
-    \group_end:
+    \bool_set_false:N \l__acro_citation_all_bool
+    \bool_set_false:N \l__acro_citation_first_bool
   }
 
-% first:
-\NewDocumentCommand \acf { sm }
+\cs_new_protected:Npn \acro_index:
+  { \bool_set_true:N \l__acro_addto_index_bool }
+
+% similar macros \acro_<ending>: are defined by \acro_provide_ending:nnn
+
+% --------------------------------------------------------------------------
+% the user commands
+% automatic:
+\NewAcroCommand \ac
+  { \acro_use:n {#1} }
+
+\NewAcroCommand \iac
   {
-    \group_begin:
-      \IfBooleanTF #1
-        { \acro_check_acronym:nn {#2} {false} }
-        { \acro_check_acronym:nn {#2} {true} }
-      \acro_first:n {#2}
-    \group_end:
+    \acro_indefinite:
+    \acro_use:n {#1}
   }
 
-\NewDocumentCommand \iacf { sm }
+\NewAcroCommand \Iac
   {
-    \group_begin:
-      \IfBooleanTF #1
-        { \acro_check_acronym:nn {#2} {false} }
-        { \acro_check_acronym:nn {#2} {true} }
-      \acro_indefinite:
-      \acro_first:n {#2}
-    \group_end:
+    \acro_first_upper:
+    \acro_indefinite:
+    \acro_use:n {#1}
   }
 
-\NewDocumentCommand \Iacf { sm }
+\NewAcroCommand \Ac
   {
-    \group_begin:
-      \IfBooleanTF #1
-        { \acro_check_acronym:nn {#2} {false} }
-        { \acro_check_acronym:nn {#2} {true} }
-      \acro_upper:
-      \acro_indefinite:
-      \acro_first:n {#2}
-    \group_end:
+    \acro_first_upper:
+    \acro_use:n {#1}
   }
 
-\NewDocumentCommand \Acf { sm }
+\NewAcroCommand \acp
   {
-    \group_begin:
-      \IfBooleanTF #1
-        { \acro_check_acronym:nn {#2} {false} }
-        { \acro_check_acronym:nn {#2} {true} }
-      \acro_upper:
-      \acro_first:n {#2}
-    \group_end:
+    \acro_plural:
+    \acro_use:n {#1}
   }
 
-\NewDocumentCommand \acfp { sm }
+\NewAcroCommand \Acp
   {
-    \group_begin:
-      \IfBooleanTF #1
-        { \acro_check_acronym:nn {#2} {false} }
-        { \acro_check_acronym:nn {#2} {true} }
-      \acro_plural:
-      \acro_first:n {#2}
-    \group_end:
+    \acro_plural:
+    \acro_first_upper:
+    \acro_use:n {#1}
   }
 
-\NewDocumentCommand \Acfp { sm }
+\NewAcroCommand \acsingle { \acro_get:n {#1} \acro_single:n {#1} }
+
+% short:
+\NewAcroCommand \acs
+  { \acro_short:n {#1} }
+
+\NewAcroCommand \iacs
   {
-    \group_begin:
-      \IfBooleanTF #1
-        { \acro_check_acronym:nn {#2} {false} }
-        { \acro_check_acronym:nn {#2} {true} }
-      \acro_plural:
-      \acro_upper:
-      \acro_first:n {#2}
-    \group_end:
+    \acro_indefinite:
+    \acro_short:n {#1}
   }
 
-% first-like:
-\NewDocumentCommand \acflike { smm }
+\NewAcroCommand \Iacs
   {
-    \group_begin:
-      \IfBooleanTF #1
-        { \acro_check_acronym:nn {#2} {false} }
-        { \acro_check_acronym:nn {#2} {true} }
-      \acro_first_like:nn {#2} {#3}
-    \group_end:
+    \acro_first_upper:
+    \acro_indefinite:
+    \acro_short:n {#1}
   }
 
-\NewDocumentCommand \iacflike { smm }
+\NewAcroCommand \acsp
   {
-    \group_begin:
-      \IfBooleanTF #1
-        { \acro_check_acronym:nn {#2} {false} }
-        { \acro_check_acronym:nn {#2} {true} }
-      \acro_indefinite:
-      \acro_first_like:nn {#2} {#3}
-    \group_end:
+    \acro_plural:
+    \acro_short:n {#1}
   }
 
-\NewDocumentCommand \Iacflike { smm }
+% alt:
+\NewAcroCommand \aca
+  { \acro_alt:n {#1} }
+
+\NewAcroCommand \iaca
   {
-    \group_begin:
-      \IfBooleanTF #1
-        { \acro_check_acronym:nn {#2} {false} }
-        { \acro_check_acronym:nn {#2} {true} }
-      \acro_upper:
-      \acro_indefinite:
-      \acro_first_like:nn {#2} {#3}
-    \group_end:
+    \acro_indefinite:
+    \acro_alt:n {#1}
   }
 
-\NewDocumentCommand \acfplike { smm }
+\NewAcroCommand \Iaca
   {
-    \group_begin:
-      \IfBooleanTF #1
-        { \acro_check_acronym:nn {#2} {false} }
-        { \acro_check_acronym:nn {#2} {true} }
-      \acro_plural:
-      \acro_first_like:nn {#2} {#3}
-    \group_end:
+    \acro_first_upper:
+    \acro_indefinite:
+    \acro_alt:n {#1}
   }
 
-% reset outputs, they'll behave like the first time again (!not like the _only_
-% time!):
-\cs_new_protected:Npn \acro_reset:n #1
+\NewAcroCommand \acap
   {
-    \bool_gset_false:c { g__acro_#1_used_bool }
-    \bool_gset_false:c { g__acro_#1_first_use_bool }
+    \acro_plural:
+    \acro_alt:n {#1}
   }
 
-\cs_new_protected:Npn \acro_mark_as_used:n #1
+% long:
+\NewAcroCommand \acl
+  { \acro_long:n {#1} }
+
+\NewAcroCommand \iacl
   {
-    \bool_gset_true:c { g__acro_#1_used_bool }
-    \bool_gset_true:c { g__acro_#1_first_use_bool }
-    \bool_gset_true:c { g__acro_#1_in_list_bool }
-    \if@filesw
-      \iow_shipout_x:Nn \@auxout
-        { \token_to_str:N \acro@used@once {#1} {} {} {} }
-      \iow_shipout_x:Nn \@auxout
-        { \token_to_str:N \acro@used@twice {#1} {} {} {} }
-    \fi
+    \acro_indefinite:
+    \acro_long:n {#1}
   }
 
+\NewAcroCommand \Iacl
+  {
+    \acro_first_upper:
+    \acro_indefinite:
+    \acro_long:n {#1}
+  }
 
-\cs_new_protected:Npn \acro_reset_all:
-  { \prop_map_inline:Nn \l__acro_short_prop { \acro_reset:n {##1} } }
+\NewAcroCommand \Acl
+  {
+    \acro_first_upper:
+    \acro_long:n {#1}
+  }
 
-\cs_new_protected:Npn \acro_mark_all_as_used:
-  { \prop_map_inline:Nn \l__acro_short_prop { \acro_mark_as_used:n {##1} } }
+\NewAcroCommand \aclp
+  {
+    \acro_plural:
+    \acro_long:n {#1}
+  }
 
-\DeclareExpandableDocumentCommand \acifused { m }
-  { \acro_if_acronym_used:nTF {#1} }
+\NewAcroCommand \Aclp
+  {
+    \acro_plural:
+    \acro_first_upper:
+    \acro_long:n {#1}
+  }
 
-\prg_new_conditional:Npnn \acro_if_acronym_used:n #1 { p,T,F,TF }
+% first:
+\NewAcroCommand \acf
+  { \acro_first:n {#1} }
+
+\NewAcroCommand \iacf
   {
-    \bool_if:nTF
-      {
-        \bool_if_p:c { g__acro_#1_used_bool } &&
-        ( !\__acro_is_single_p:n {#1} )
-      }
-      { \prg_return_true: }
-      { \prg_return_false: }
+    \acro_indefinite:
+    \acro_first:n {#1}
   }
 
-\NewDocumentCommand \acresetall {}
-  { \acro_reset_all: }
+\NewAcroCommand \Iacf
+  {
+    \acro_first_upper:
+    \acro_indefinite:
+    \acro_first:n {#1}
+  }
 
-\NewDocumentCommand \acuseall {}
-  { \acro_mark_all_as_used: }
+\NewAcroCommand \Acf
+  {
+    \acro_first_upper:
+    \acro_first:n {#1}
+  }
 
-\NewDocumentCommand \acreset { > { \SplitList { , } } m }
-  { \ProcessList {#1} { \acro_reset:n } \ignorespaces }
+\NewAcroCommand \acfp
+  {
+    \acro_plural:
+    \acro_first:n {#1}
+  }
 
-\NewDocumentCommand \acuse { > { \SplitList { , } } m }
-  { \ProcessList {#1} { \acro_mark_as_used:n } \ignorespaces }
+\NewAcroCommand \Acfp
+  {
+    \acro_plural:
+    \acro_first_upper:
+    \acro_first:n {#1}
+  }
+
+% first-like:
+\NewPseudoAcroCommand \acflike
+  { \acro_first_like:nn {#1} {#2} }
+
+\NewPseudoAcroCommand \iacflike
+  {
+    \acro_indefinite:
+    \acro_first_like:nn {#1} {#2}
+  }
+
+\NewPseudoAcroCommand \Iacflike
+  {
+    \acro_first_upper:
+    \acro_indefinite:
+    \acro_first_like:nn {#1} {#2}
+  }
+
+\NewPseudoAcroCommand \acfplike
+  {
+    \acro_plural:
+    \acro_first_like:nn {#1} {#2}
+  }
 
 % ---------------------------------------------------------------------------
 % process options:
@@ -2298,10 +2649,10 @@
 % ---------------------------------------------------------------------------
 % PDF bookmark support
 \cs_new:Npn \acpdfstring
-  { \acro_pdf_string:n }
+  { \acro_pdf_string_short:n }
 
-\cs_new:Npn \acpdfstringplural
-  { \acro_pdf_string_plural:n }
+\cs_new:Npn \acpdfstringalt
+  { \acro_pdf_string_alt:n }
 
 \prg_new_conditional:Npnn \acro_if_star_gobble:n #1 {TF}
   {
@@ -2312,18 +2663,18 @@
     \fi:
   }
 
-\cs_new:Npn \acro_pdf_string:n #1
+\cs_new:Npn \acro_pdf_string_short:n #1
   {
     \acro_if_star_gobble:nTF {#1}
-      { \prop_get:Nn \l__acro_pdfstring_prop }
-      { \prop_get:Nn \l__acro_pdfstring_prop {#1} }
+      { \prop_item:Nn \l__acro_pdfstring_short_prop }
+      { \prop_item:Nn \l__acro_pdfstring_short_prop {#1} }
   }
-
-\cs_new:Npn \acro_pdf_string_plural:n #1
+  
+\cs_new:Npn \acro_pdf_string_alt:n #1
   {
     \acro_if_star_gobble:nTF {#1}
-      { \prop_get:Nn \l__acro_pdfstring_plural_prop }
-      { \prop_get:Nn \l__acro_pdfstring_plural_prop {#1} }
+      { \prop_item:Nn \l__acro_pdfstring_alt_prop }
+      { \prop_item:Nn \l__acro_pdfstring_alt_prop {#1} }
   }
 
 \AtBeginDocument
@@ -2340,7 +2691,7 @@
             \cs_set_eq:NN \Acl  \acpdfstring
             \cs_set_eq:NN \acf  \acpdfstring
             \cs_set_eq:NN \Acf  \acpdfstring
-            \cs_set_eq:NN \aca  \acpdfstring
+            \cs_set_eq:NN \aca  \acpdfstringalt
             \cs_set_eq:NN \acp  \acpdfstringplural
             \cs_set_eq:NN \Acp  \acpdfstringplural
             \cs_set_eq:NN \acsp \acpdfstringplural
@@ -2348,7 +2699,7 @@
             \cs_set_eq:NN \Aclp \acpdfstringplural
             \cs_set_eq:NN \acfp \acpdfstringplural
             \cs_set_eq:NN \Acfp \acpdfstringplural
-            \cs_set_eq:NN \acap \acpdfstringplural
+            \cs_set_eq:NN \acap \acpdfstringaltplural
           }
         \cs_set_protected:Npn \acro_hyper_page:n #1 { \hyperpage {#1} }
       } {}
@@ -2374,26 +2725,31 @@
 
 \msg_new:nnn {acro} {doubled-key}
   {
-    It~seems~to~me~you~have~used~the~`#1'~key~before.~If~you~haven't~there's~
-    something~different~wrong~and~I'm~lost.~You~'re~on~your~own~now.
+    It~ seems~ to~ me~ you~ have~ used~ the~ `#2'~ key~ twice~ in~ the~
+    declaration~ of~ acronym~ `#1'.~ If~ you~ haven't~ there's~
+    something~ different~ wrong~ and~ I'm~ lost.~ You~'re~ on~ your~ own~
+    then.
   }
 
 \cs_new_protected:Npn \__acro_key_check:nn #1#2
   {
     \tl_if_blank:VT \l__acro_current_key_tl
-      { \acro_serious_message:nn {acro} {no-id} }
+      { \acro_serious_message:n {no-id} }
     \bool_if:cF { l__acro_#1_short_set_bool }
-      { \acro_serious_message:nnnn {acro} {before-short} {#1} {#2} }
+      {
+        \keys_set:nn { acro / declare-acronym } { short = {#1} }
+        \acro_harmless_message:nn {substitute-short} {#1}
+      }
     \bool_new:c { l__acro_#1_#2_set_bool }
     \bool_set_true:c { l__acro_#1_#2_set_bool }
   }
 
-\cs_new_protected:Npn \__acro_first_key_check:n #1
+\cs_new_protected:Npn \__acro_first_key_check:nn #1#2
   {
     \cs_if_exist:cTF { l__acro_#1_short_set_bool }
       {
          \bool_if:cT { l__acro_#1_short_set_bool }
-           { \acro_serious_message:nnn {acro} {doubled-key} {#1} }
+           { \acro_serious_message:nnn {doubled-key} {#1} {#2} }
       }
       {
         \bool_new:c { l__acro_#1_short_set_bool }
@@ -2409,11 +2765,8 @@
 % #3: action
 \cs_new_protected:Npn \acro_declare_key_generic:nnn #1#2#3
   {
-    \prop_new:c { l__acro_#1_prop }
-    \cs_new_protected:cpn { __acro_declare_#1:nn } ##1##2
-      {
-        #3
-      }
+    \prop_clear_new:c { l__acro_#1_prop }
+    \cs_new_protected:cpn { __acro_declare_#1:nn } ##1##2 {#3}
     \cs_generate_variant:cn { __acro_declare_#1:nn } { V }
     \keys_define:nn { acro / declare-acronym }
       {
@@ -2421,7 +2774,6 @@
           \use:c {__acro_declare_#1:Vn} \l__acro_current_key_tl {##1}
       }
   }
-\cs_generate_variant:Nn \cs_generate_variant:Nn {c}
 
 % #1: name in associated cs
 % #2: key name
@@ -2462,52 +2814,53 @@
 % short:
 \acro_declare_key_generic:nnn {short} {short}
   {
-    \__acro_first_key_check:n {#1}
+    \__acro_first_key_check:nn {#1} {short}
     \prop_put:Nnn \l__acro_short_prop      {#1} {#2}
     \prop_put:Nnn \l__acro_sort_prop       {#1} {#1}
     \prop_put:Nnn \l__acro_index_sort_prop {#1} {#1}
     \prop_put:Nnn \l__acro_alt_prop        {#1} {#2}
-    \prop_put:Nnx \l__acro_pdfstring_prop  {#1} { \exp_not:n {#2} }
-    \prop_put:Nnn \l__acro_short_plural_prop
-      {#1} { \l__acro_default_plural_tl }
-    \prop_put:Nnx \l__acro_short_indefinite_prop
-      {#1} { \l__acro_default_indefinite_tl }
-    \prop_put:Nnx \l__acro_alt_indefinite_prop
-      {#1} { \l__acro_default_indefinite_tl }
-    \prop_put:Nnx \l__acro_pdfstring_plural_prop
-      {#1} { \exp_not:n {#2} \exp_not:V \l__acro_default_plural_tl }
+    \prop_put:Nnn \l__acro_pdfstring_short_prop {#1} {#2}
+    \prop_put:Nnn \l__acro_pdfstring_alt_prop {#1} {#2}
+    \seq_map_inline:Nn \l__acro_endings_seq
+      {
+        \prop_put:cnv {l__acro_short_##1_prop}
+          {#1} {l__acro_default_short_##1_tl}
+        \prop_put:cnx {l__acro_pdfstring_short_##1_prop}
+          {#1} { \exp_not:n {#2} \exp_not:v {l__acro_default_short_##1_tl} }
+        \prop_put:cnn {l__acro_short_##1_form_prop} {#1} { \c_false_bool }
+        \prop_put:cnv {l__acro_alt_##1_prop}
+          {#1} {l__acro_default_alt_##1_tl}
+        \prop_put:cnx {l__acro_pdfstring_alt_##1_prop}
+          {#1} { \exp_not:n {#2} \exp_not:v {l__acro_default_short_##1_tl} }
+        \prop_put:cnn {l__acro_alt_##1_form_prop} {#1} { \c_false_bool }
+      }
+    \prop_put:NnV \l__acro_short_indefinite_prop
+      {#1} \l__acro_default_indefinite_tl
+    \prop_put:NnV \l__acro_alt_indefinite_prop
+      {#1} \l__acro_default_indefinite_tl
   }
 
-% short plural:
-\acro_declare_simple_key:n {short-plural}
-
 % long:
 \acro_declare_key:nnn {long} {long}
   {
-    \prop_put:Nnn \l__acro_long_plural_form_prop {#1} { \c_false_bool }
-    \prop_put:Nnx \l__acro_long_indefinite_prop
-      {#1} { \l__acro_default_indefinite_tl }
-    \bool_if:cF { l__acro_#1_long-plural_set_bool }
+    \seq_map_inline:Nn \l__acro_endings_seq
+      { \prop_put:cnn {l__acro_long_##1_form_prop} {#1} { \c_false_bool } }
+    \prop_put:NnV \l__acro_long_indefinite_prop
+      {#1}
+      \l__acro_default_indefinite_tl
+    \seq_map_inline:Nn \l__acro_endings_seq
       {
-        \prop_put:Nnn \l__acro_long_plural_prop
-          {#1} { \l__acro_default_plural_tl }
+        \bool_if:cF {l__acro_#1_long-##1_set_bool}
+          { \prop_put:cnv {l__acro_long_##1_prop} {#1} {l__acro_default_long_##1_tl} }
       }
   }
 
 % list:
 \acro_declare_simple_key:n {list}
 
-% long plural:
-\acro_declare_key:nnn {long_plural} {long-plural}
-  { \prop_put:Nnn \l__acro_long_plural_form_prop {#1} { \c_false_bool } }
-
-% long plural form:
-\acro_declare_key_generic:nnn {long_plural_form} {long-plural-form}
-  {
-    \__acro_key_check:nn {#1} { long-plural-form }
-    \prop_put:Nnn \l__acro_long_plural_form_prop {#1} { \c_true_bool }
-    \prop_put:Nnn \l__acro_long_plural_prop {#1} {#2}
-  }
+% defines `short-plural', `long-plural' and `long-plural-form' as well as the
+% options `plural-ending', `short-plural-ending' and `long-plural-ending':
+\ProvideAcroEnding {plural} {s} {s}
 
 % short indefinite article:
 \acro_declare_simple_key:n {short-indefinite}
@@ -2531,8 +2884,15 @@
 % alternative:
 \acro_declare_key:nnn {alt} {alt}
   {
-    \prop_put:Nnx \l__acro_alt_indefinite_prop
-      {#1} { \l__acro_default_indefinite_tl }
+    \prop_put:Nnn \l__acro_pdfstring_alt_prop {#1} {#2}
+    \prop_put:NnV \l__acro_alt_indefinite_prop
+      {#1} \l__acro_default_indefinite_tl
+  }
+
+\cs_set_protected:Npn \acro_alt_error:n #1
+  {
+    \bool_if:cF {l__acro_#1_alt_set_bool} 
+      { \acro_harmless_message:nn {no-alternative} {#1} }
   }
 
 % alt. indefinite article:
@@ -2554,20 +2914,22 @@
 \acro_declare_simple_key:n {first-long-format}
 
 % pdfstring:
-\prop_new:N \l__acro_pdfstring_prop
-\prop_new:N \l__acro_pdfstring_plural_prop
+\prop_new:N \l__acro_pdfstring_short_prop
 \cs_new_protected:Npn \__acro_declare_pdfstring:nw #1#2/#3/#4 \acro_stop:
   {
     \__acro_key_check:nn {#1} { pdfstring }
-    \prop_put:Nnx \l__acro_pdfstring_prop {#1} {#2}
-    \tl_if_empty:nTF { #3 }
+    \prop_put:Nnn \l__acro_pdfstring_short_prop {#1} {#2}
+    \seq_map_inline:Nn \l__acro_endings_seq
       {
-        \prop_put:Nnx \l__acro_pdfstring_plural_prop
-          {#1} { \exp_not:n {#2} \exp_not:V \l__acro_default_plural_tl }
-      }
-      {
-        \prop_put:Nnx \l__acro_pdfstring_plural_prop
-          {#1} { \exp_not:n { #2#3 } }
+        \tl_if_empty:nTF {#3}
+          {
+            \prop_put:cnx {l__acro_pdfstring_short_##1_prop}
+              {#1} { \exp_not:n {#2} \exp_not:v {l__acro_default_short_##1_tl} }
+          }
+          {
+            \prop_put:cnn {l__acro_pdfstring_short_##1_prop}
+              {#1} {#2#3}
+          }
       }
   }
 \cs_generate_variant:Nn \__acro_declare_pdfstring:nw { V }
@@ -2577,6 +2939,28 @@
       \__acro_declare_pdfstring:Vw \l__acro_current_key_tl #1 // \acro_stop: ,
   }
 
+\prop_new:N \l__acro_pdfstring_alt_prop
+\cs_new_protected:Npn \__acro_declare_pdfstring_alt:nw #1#2/#3/#4 \acro_stop:
+  {
+    \__acro_key_check:nn {#1} { pdfstring-alt }
+    \prop_put:Nnn \l__acro_pdfstring_alt_prop {#1} {#2}
+    \seq_map_inline:Nn \l__acro_endings_seq
+      {
+        \tl_if_empty:nTF {#3}
+          {
+            \prop_put:cnx {l__acro_pdfstring_alt_##1_prop}
+              {#1} { \exp_not:n {#2} \exp_not:v {l__acro_default_alt_##1_tl} }
+          }
+          { \prop_put:cnn {l__acro_pdfstring_alt_##1_prop} {#1} {#2#3} }
+      }
+  }
+\cs_generate_variant:Nn \__acro_declare_pdfstring_alt:nw { V }
+\keys_define:nn { acro / declare-acronym }
+  {
+    pdfstring-alt .code:n =
+      \__acro_declare_pdfstring_alt:Vw \l__acro_current_key_tl #1 // \acro_stop: ,
+  }
+  
 % class:
 \acro_declare_simple_key:n {class}
 
@@ -2656,7 +3040,7 @@
           {
             \bool_if:NTF \l__acro_strict_bool
               { \cs_set:cpn {#1} { \ac {#1} \acro_xspace: } }
-              { \acro_serious_message:nnn {acro} {macro} {#1} }
+              { \acro_serious_message:nn {macro} {#1} }
           }
           { \cs_new:cpn {#1} { \ac {#1} \acro_xspace: } }
       }
@@ -2666,6 +3050,7 @@
 % internal acronym declaring function:
 \cs_new_protected:Npn \acro_declare_acronym:nn #1#2
   {
+    \bool_gset_true:N \g__acro_first_acronym_declared_bool
     \tl_set:Nn \l__acro_current_key_tl {#1}
     \keys_set:nn { acro / declare-acronym } {#2}
     \bool_new:c { g__acro_#1_first_use_bool }
@@ -2678,9 +3063,9 @@
     \acro_define_acronym_macro:n {#1}
     \tl_clear:N \l__acro_current_key_tl
     \bool_if:cF { l__acro_#1_short_set_bool }
-      { \acro_serious_message:nnnn {acro} {missing} {#1} {short} }
+      { \acro_serious_message:nnn {missing} {#1} {short} }
     \bool_if:cF { l__acro_#1_long_set_bool }
-      { \acro_serious_message:nnnn {acro} {missing} {#1} {long} }
+      { \acro_serious_message:nnn {missing} {#1} {long} }
   }
 
 % --------------------------------------------------------------------------
@@ -2708,7 +3093,7 @@
     exclude-classes .tl_set:N   = \l__acro_excluded_classes_tl ,
     name            .tl_set:N   = \l__acro_list_name_tl ,
     header          .code:n     =
-      \acro_option_deprecated:nn { header } { heading }
+      \acro_option_deprecated:nn {header} {heading}
       \tl_set:Nn \l__acro_list_title_tl {#1} ,
     heading         .tl_set:N   = \l__acro_list_title_tl ,
     sort            .bool_set:N = \l__acro_sort_bool
@@ -2727,7 +3112,7 @@
       \iow_now:Nx \@auxout { \string \acro@print@list }
       \bool_if:NT \l__acro_sort_bool
         { \acro_sort_prop:N \l__acro_short_prop }
-      \UseInstance { acro-title } { \l__acro_list_title_tl }
+      \UseInstance {acro-title} { \l__acro_list_title_tl }
         { \l__acro_list_name_tl }
       \cs_if_exist:NTF \acro@printed@list
         {
@@ -2902,14 +3287,27 @@
 2015/05/10 v1.6b - \ProcessKeysPackageOptions ,
                  - correct bug http://tex.stackexchange.com/q/236860/ :
                    option `pages = first' works again
+2015/08/16 v2.0  - fix https://bitbucket.org/cgnieder/acro/issue/36
+                 - implement https://bitbucket.org/cgnieder/acro/issue/39
+                 - implement https://bitbucket.org/cgnieder/acro/issue/40
+                   (=> new option `group-cite-cmd')
+                 - add ideas for https://bitbucket.org/cgnieder/acro/issue/41
+                 - implement https://bitbucket.org/cgnieder/acro/issue/18
+                 - implement https://bitbucket.org/cgnieder/acro/issue/43
+                 - further generalization for defining user commands:
+                   \NewAcroCommand, \NewPseudoAcroCommand and siblings
+                 - bug fix in indefinite versions with first-upper
+                 - add `short-<ending>-form' equivalent to
+                   `long-<ending>-form'
+                   (https://bitbucket.org/cgnieder/acro/issue/44)
+                 - implement https://bitbucket.org/cgnieder/acro/issue/35
+                 - new option `single-form'
 
 % --------------------------------------------------------------------------
+update => http://tex.stackexchange.com/questions/236362
+
 % TODO:
-- issue 18: https://bitbucket.org/cgnieder/acro/issue/18
 - extend option `macros' to also define uppercase macros, possibly as a choice
-- https://bitbucket.org/cgnieder/acro/issue/18
-- options user1, user2, user3? (Genitiv lang, Akkusativ lang,...) Bsp: ``des
-  Bundesinstituts für Risikobewertung''
 - Option `totoc'!?
 - revise list styles to allow _full_ customization by creating own instances!
   this probably needs a handfull of macros that give access to the entries
-- 
cgit v1.2.3

