Cs_cz.t

--- cs_cz/en_us.t	2011-09-03 12:47:25.000000000 +0200
+++ cs_cz/cs_cz.t	2011-10-16 19:10:25.000000000 +0200
@@ -1,10774 +1,11046 @@
-#charset "us-ascii"
+#charset "utf-8"
 
 /*
+ *   Czech version is copyright 2010, 2011 Tomas Blaha.
+ *
+ *   Based on English language module by Michael J. Roberts with permission.
+ *   Original copyright below:
+ *
  *   Copyright 2000, 2006 Michael J. Roberts.  All Rights Reserved.
  *.  Past-tense extensions written by Michel Nizette, and incorporated by
  *   permission.
  *   
  *   TADS 3 Library - English (United States variant) implementation
  *   
  *   This defines the parts of the TADS 3 library that are specific to the
  *   English language as spoken (and written) in the United States.
  *   
  *   We have attempted to isolate here the parts of the library that are
  *   language-specific, so that translations to other languages or dialects
  *   can be created by replacing this module, without changing the rest of
  *   the library.
  *   
  *   In addition to this module, a separate set of US English messages are
  *   defined in the various msg_xxx.t modules.  Those modules define
  *   messages in English for different stylistic variations.  For a given
  *   game, the author must select one of the message modules - but only
  *   one, since they all define variations of the same messages.  To
  *   translate the library, a translator must create at least one module
  *   defining those messages as well; only one message module is required
  *   per language.
  *   
  *   The past-tense system was contributed by Michel Nizette.
  *   
  *.                                  -----
  *   
  *   "Watch an immigrant struggling with a second language or a stroke
  *   patient with a first one, or deconstruct a snatch of baby talk, or try
  *   to program a computer to understand English, and ordinary speech
  *   begins to look different."
  *   
  *.         Stephen Pinker, "The Language Instinct"
  */
 
 #include "tads.h"
 #include "tok.h"
 #include "adv3.h"
-#include "en_us.h"
+#include "cs_cz.h"
 #include <vector.h>
 #include <dict.h>
 #include <gramprod.h>
 #include <strcomp.h>
 
 
 /* ------------------------------------------------------------------------ */
 /*
  *   Fill in the default language for the GameInfo metadata class.
  */
 modify GameInfoModuleID
-    languageCode = 'en-US'
+    languageCode = 'cs-CZ'
 ;
 
 /* ------------------------------------------------------------------------ */
 /*
  *   Simple yes/no confirmation.  The caller must display a prompt; we'll
  *   read a command line response, then return true if it's an affirmative
  *   response, nil if not.
  */
 yesOrNo()
 {
     /* switch to no-command mode for the interactive input */
     "<.commandnone>";
 
     /*
      *   Read a line of input.  Do not allow real-time event processing;
      *   this type of prompt is used in the middle of a command, so we
      *   don't want any interruptions.  Note that the caller must display
      *   any desired prompt, and since we don't allow interruptions, we
      *   won't need to redisplay the prompt, so we pass nil for the prompt
      *   callback.
      */
     local str = inputManager.getInputLine(nil, nil);
 
     /* switch back to mid-command mode */
     "<.commandmid>";
 
     /*
      *   If they answered with something starting with 'Y', it's
      *   affirmative, otherwise it's negative.  In reading the response,
      *   ignore any leading whitespace.
      */
-    return rexMatch('<space>*[yY]', str) != nil;
+    return rexMatch('<space>*[aA]', str) != nil;
 }
 
 /* ------------------------------------------------------------------------ */
 /*
  *   During start-up, install a case-insensitive truncating comparator in
  *   the main dictionary.
  */
 PreinitObject
+    /*
+     *   String komparátoru poskytneme mapu ekvivalentních znaků, aby poznal
+     *   objekty i tehdy, když hráč bude psát bez háčků a čárek.
+     *   http://www.tads.org/t3doc/doc/sysman/strcomp.htm
+     *
+     *   TODO: Nefunguje, pokud je přeloženo bez debug informací (t3make -d)
+     */
+    mappings =
+    [
+        ['ř', 'r', 0, 0],
+        ['í', 'i', 0, 0],
+        ['š', 's', 0, 0],
+        ['ž', 'z', 0, 0],
+        ['ť', 't', 0, 0],
+        ['č', 'c', 0, 0],
+        ['ý', 'y', 0, 0],
+        ['ů', 'u', 0, 0],
+        ['ň', 'n', 0, 0],
+        ['ú', 'u', 0, 0],
+        ['ě', 'e', 0, 0],
+        ['ď', 'd', 0, 0],
+        ['á', 'a', 0, 0],
+        ['é', 'e', 0, 0],
+        ['ó', 'o', 0, 0]
+    ]
     execute()
     {
         /* set up the main dictionary's comparator */
         languageGlobals.setStringComparator(
-            new StringComparator(gameMain.parserTruncLength, nil, []));
+            new StringComparator(gameMain.parserTruncLength, nil, mappings));
     }
 
     /*
      *   Make sure we run BEFORE the main library preinitializer, so that
      *   we install the comparator in the dictionary before we add the
      *   vocabulary words to the dictionary.  This doesn't make any
      *   difference in terms of the correctness of the dictionary, since
      *   the dictionary will automatically rebuild itself whenever we
      *   install a new comparator, but it makes the preinitialization run
      *   a tiny bit faster by avoiding that rebuild step.
      */
     execAfterMe = [adv3LibPreinit]
 ;
 
 /* ------------------------------------------------------------------------ */
 /*
  *   Language-specific globals
  */
 languageGlobals: object
     /*
      *   Set the StringComparator object for the parser.  This sets the
      *   comparator that's used in the main command parser dictionary. 
      */
     setStringComparator(sc)
     {
         /* remember it globally, and set it in the main dictionary */
         dictComparator = sc;
         cmdDict.setComparator(sc);
     }
 
     /*
      *   The character to use to separate groups of digits in large
      *   numbers.  US English uses commas; most Europeans use periods.
      *
      *   Note that this setting does not affect system-level BigNumber
      *   formatting, but this information can be passed when calling
      *   BigNumber formatting routines.
      */
-    digitGroupSeparator = ','
+    digitGroupSeparator = '.'
 
     /*
      *   The decimal point to display in floating-point numbers.  US
      *   English uses a period; most Europeans use a comma.
      *
      *   Note that this setting doesn't affect system-level BigNumber
      *   formatting, but this information can be passed when calling
      *   BigNumber formatting routines.
      */
-    decimalPointCharacter = '.'
+    decimalPointCharacter = ','
 
     /* the main dictionary's string comparator */
     dictComparator = nil
 ;
 
 
 /* ------------------------------------------------------------------------ */
 /*
  *   Language-specific extension of the default gameMain object
  *   implementation.
  */
 modify GameMainDef
     /*
      *   Option setting: the parser's truncation length for player input.
      *   As a convenience to the player, we can allow the player to
      *   truncate long words, entering only the first, say, 6 characters.
      *   For example, rather than typing "x flashlight", we could allow the
      *   player to simply type "x flashl" - truncating "flashlight" to six
      *   letters.
      *   
      *   We use a default truncation length of 6, but games can change this
      *   by overriding this property in gameMain.  We use a default of 6
      *   mostly because that's what the old Infocom games did - many
      *   long-time IF players are accustomed to six-letter truncation from
      *   those games.  Shorter lengths are superficially more convenient
      *   for the player, obviously, but there's a trade-off, which is that
      *   shorter truncation lengths create more potential for ambiguity.
      *   For some games, a longer length might actually be better for the
      *   player, because it would reduce spurious ambiguity due to the
      *   parser matching short input against long vocabulary words.
      *   
      *   If you don't want to allow the player to truncate long words at
      *   all, set this to nil.  This will require the player to type every
      *   word in its entirety.
      *   
      *   Note that changing this property dynamicaly will have no effect.
      *   The library only looks at it once, during library initialization
      *   at the very start of the game.  If you want to change the
      *   truncation length dynamically, you must instead create a new
      *   StringComparator object with the new truncation setting, and call
      *   languageGlobals.setStringComparator() to select the new object.  
      */
     parserTruncLength = 6
 
     /*
      *   Option: are we currently using a past tense narrative?  By
      *   default, we aren't.
      *
      *   This property can be reset at any time during the game in order to
      *   switch between the past and present tenses.  The macro
      *   setPastTense can be used for this purpose: it just provides a
      *   shorthand for setting gameMain.usePastTense directly.
      *
      *   Authors who want their game to start in the past tense can achieve
      *   this by overriding this property on their gameMain object and
      *   giving it a value of true.
      */
     usePastTense = nil
 ;
 
 
 /* ------------------------------------------------------------------------ */
 /*
  *   Language-specific modifications for ThingState.
  */
 modify ThingState
     /*
      *   Our state-specific tokens.  This is a list of vocabulary words
      *   that are state-specific: that is, if a word is in this list, the
      *   word can ONLY refer to this object if the object is in a state
      *   with that word in its list.
      *   
      *   The idea is that you set up the object's "static" vocabulary with
      *   the *complete* list of words for all of its possible states.  For
      *   example:
      *   
      *.     + Matchstick 'lit unlit match';
      *   
      *   Then, you define the states: in the "lit" state, the word 'lit' is
      *   in the stateTokens list; in the "unlit" state, the word 'unlit' is
      *   in the list.  By putting the words in the state lists, you
      *   "reserve" the words to their respective states.  When the player
      *   enters a command, the parser will limit object matches so that the
      *   reserved state-specific words can only refer to objects in the
      *   corresponding states.  Hence, if the player refers to a "lit
      *   match", the word 'lit' will only match an object in the "lit"
      *   state, because 'lit' is a reserved state-specific word associated
      *   with the "lit" state.
      *   
      *   You can re-use a word in multiple states.  For example, you could
      *   have a "red painted" state and a "blue painted" state, along with
      *   an "unpainted" state.
      */
     stateTokens = []
 
     /*
      *   Match the name of an object in this state.  We'll check the token
      *   list for any words that apply only to *other* states the object
      *   can assume; if we find any, we'll reject the match, since the
      *   phrase must be referring to an object in a different state.
      */
     matchName(obj, origTokens, adjustedTokens, states)
     {
         /* scan each word in our adjusted token list */
         for (local i = 1, local len = adjustedTokens.length() ;
              i <= len ; i += 2)
         {
             /* get the current token */
             local cur = adjustedTokens[i];
 
             /*
              *   If this token is in our own state-specific token list,
              *   it's acceptable as a match to this object.  (It doesn't
              *   matter whether or not it's in any other state's token list
              *   if it's in our own, because its presence in our own makes
              *   it an acceptable matching word when we're in this state.) 
              */
             if (stateTokens.indexWhich({t: t == cur}) != nil)
                 continue;
 
             /*
              *   It's not in our own state-specific token list.  Check to
              *   see if the word appears in ANOTHER state's token list: if
              *   it does, then this word CAN'T match an object in this
              *   state, because the token is special to that other state
              *   and thus can't refer to an object in a state without the
              *   token. 
              */
             if (states.indexWhich(
                 {s: s.stateTokens.indexOf(cur) != nil}) != nil)
                 return nil;
         }
 
         /* we didn't find any objection, so we can match this phrase */
         return obj;
     }
 
     /*
      *   Check a token list for any tokens matching any of our
      *   state-specific words.  Returns true if we find any such words,
      *   nil if not.
      *
      *   'toks' is the *adjusted* token list used in matchName().
      */
     findStateToken(toks)
     {
         /*
          *   Scan the token list for a match to any of our state-specific
          *   words.  Since we're using the adjusted token list, every
          *   other entry is a part of speech, so work through the list in
          *   pairs.
          */
         for (local i = 1, local len = toks.length() ; i <= len ; i += 2)
         {
             /*
              *   if this token matches any of our state tokens, indicate
              *   that we found a match
              */
             if (stateTokens.indexWhich({x: x == toks[i]}) != nil)
                 return true;
         }
 
         /* we didn't find a match */
         return nil;
     }
 
     /* get our name */
     listName(lst) { return listName_; }
 
     /*
      *   our list name setting - we define this so that we can be easily
      *   initialized with a template (we can't initialize listName()
      *   directly in this manner because it's a method, but we define the
      *   listName() method to simply return this property value, which we
      *   can initialize with a template)
      */
     listName_ = nil
 ;
 
 /* ------------------------------------------------------------------------ */
 /*
  *   Language-specific modifications for VocabObject.
  */
 modify VocabObject
     /*
      *   The vocabulary initializer string for the object - this string
      *   can be initialized (most conveniently via a template) to a string
      *   of this format:
      *
      *   'adj adj adj noun/noun/noun*plural plural plural'
      *
      *   The noun part of the string can be a hyphen, '-', in which case
      *   it means that the string doesn't specify a noun or plural at all.
      *   This can be useful when nouns and plurals are all inherited from
      *   base classes, and only adjectives are to be specified.  (In fact,
      *   any word that consists of a single hyphen will be ignored, but
      *   this is generally only useful for the adjective-only case.)
      *
      *   During preinitialization, we'll parse this string and generate
      *   dictionary entries and individual vocabulary properties for the
      *   parts of speech we find.
      *
      *   Note that the format described above is specific to the English
      *   version of the library.  Non-English versions will probably want
      *   to use different formats to conveniently encode appropriate
      *   language-specific information in the initializer string.  See the
      *   comments for initializeVocabWith() for more details.
      *
      *   You can use the special wildcard # to match any numeric
      *   adjective.  This only works as a wildcard when it stands alone,
      *   so a string like "7#" is matched as that literal string, not as a
      *   wildcard.  If you want to use a pound sign as a literal
      *   adjective, just put it in double quotes.
      *
      *   You can use the special wildcard "\u0001" (include the double
      *   quotes within the string) to match any literal adjective.  This
      *   is the literal adjective equivalent of the pound sign.  We use
      *   this funny character value because it is unlikely ever to be
      *   interesting in user input.
      *
      *   If you want to match any string for a noun and/or adjective, you
      *   can't do it with this property.  Instead, just add the property
      *   value noun='*' to the object.
      */
     vocabWords = ''
 
     /*
      *   On dynamic construction, initialize our vocabulary words and add
      *   them to the dictionary.
      */
     construct()
     {
         /* initialize our vocabulary words from vocabWords */
         initializeVocab();
 
         /* add our vocabulary words to the dictionary */
         addToDictionary(&noun);
         addToDictionary(&adjective);
         addToDictionary(&plural);
         addToDictionary(&adjApostS);
         addToDictionary(&literalAdjective);
     }
 
     /* add the words from a dictionary property to the global dictionary */
     addToDictionary(prop)
     {
         /* if we have any words defined, add them to the dictionary */
         if (self.(prop) != nil)
             cmdDict.addWord(self, self.(prop), prop);
     }
 
     /* initialize the vocabulary from vocabWords */
     initializeVocab()
     {
         /* inherit vocabulary from this class and its superclasses */
         inheritVocab(self, new Vector(10));
     }
 
     /*
      *   Inherit vocabulary from this class and its superclasses, adding
      *   the words to the given target object.  'target' is the object to
      *   which we add our vocabulary words, and 'done' is a vector of
      *   classes that have been visited so far.
      *
      *   Since a class can be inherited more than once in an inheritance
      *   tree (for example, a class can have multiple superclasses, each
      *   of which have a common base class), we keep a vector of all of
      *   the classes we've visited.  If we're already in the vector, we'll
      *   skip adding vocabulary for this class or its superclasses, since
      *   we must have already traversed this branch of the tree from
      *   another subclass.
      */
     inheritVocab(target, done)
     {
         /*
          *   if we're in the list of classes handled already, don't bother
          *   visiting me again
          */
         if (done.indexOf(self) != nil)
             return;
 
         /* add myself to the list of classes handled already */
         done.append(self);
 
         /* 
          *   add words from our own vocabWords to the target object (but
          *   only if it's our own - not if it's only inherited, as we'll
          *   pick up the inherited ones explicitly in a bit) 
          */
         if (propDefined(&vocabWords, PropDefDirectly))
             target.initializeVocabWith(vocabWords);
 
         /* add vocabulary from each of our superclasses */
         foreach (local sc in getSuperclassList())
             sc.inheritVocab(target, done);
     }
 
     /*
      *   Initialize our vocabulary from the given string.  This parses the
      *   given vocabulary initializer string and adds the words defined in
      *   the string to the dictionary.
      *
      *   Note that this parsing is intentionally located in the
      *   English-specific part of the library, because it is expected that
      *   other languages will want to define their own vocabulary
      *   initialization string formats.  For example, a language with
      *   gendered nouns might want to use gendered articles in the
      *   initializer string as an author-friendly way of defining noun
      *   gender; languages with inflected (declined) nouns and/or
      *   adjectives might want to encode inflected forms in the
      *   initializer.  Non-English language implementations are free to
      *   completely redefine the format - there's no need to follow the
      *   conventions of the English format in other languages where
      *   different formats would be more convenient.
      */
     initializeVocabWith(str)
     {
         local sectPart;
         local modList = [];
 
         /* start off in the adjective section */
         sectPart = &adjective;
 
         /* scan the string until we run out of text */
         while (str != '')
         {
             local len;
             local cur;
 
             /*
              *   if it starts with a quote, find the close quote;
              *   otherwise, find the end of the current token by seeking
              *   the next delimiter
              */
             if (str.startsWith('"'))
             {
                 /* find the close quote */
                 len = str.find('"', 2);
             }
             else
             {
                 /* no quotes - find the next delimiter */
                 len = rexMatch('<^space|star|/>*', str);
             }
 
             /* if there's no match, use the whole rest of the string */
             if (len == nil)
                 len = str.length();
 
             /* if there's anything before the delimiter, extract it */
             if (len != 0)
             {
                 /* extract the part up to but not including the delimiter */
                 cur = str.substr(1, len);
 
                 /*
                  *   if we're in the adjectives, and either this is the
                  *   last token or the next delimiter is not a space, this
                  *   is implicitly a noun
                  */
                 if (sectPart == &adjective
                     && (len == str.length()
                         || str.substr(len + 1, 1) != ' '))
                 {
                     /* move to the noun section */
                     sectPart = &noun;
                 }
 
                 /*
                  *   if the word isn't a single hyphen (in which case it's
                  *   a null word placeholder, not an actual vocabulary
                  *   word), add it to our own appropriate part-of-speech
                  *   property and to the dictionary
                  */
                 if (cur != '-')
                 {
                     /*
                      *   by default, use the part of speech of the current
                      *   string section as the part of speech for this
                      *   word
                      */
                     local wordPart = sectPart;
 
                     /*
                      *   Check for parentheses, which indicate that the
                      *   token is "weak."  This doesn't affect anything
                      *   about the token or its part of speech except that
                      *   we must include the token in our list of weak
                      *   tokens.
                      */
                     if (cur.startsWith('(') && cur.endsWith(')'))
                     {
                         /* it's a weak token - remove the parens */
                         cur = cur.substr(2, cur.length() - 2);
 
                         /*
                          *   if we don't have a weak token list yet,
                          *   create the list
                          */
                         if (weakTokens == nil)
                             weakTokens = [];
 
                         /* add the token to the weak list */
                         weakTokens += cur;
                     }
 
                     /*
                      *   Check for special formats: quoted strings,
                      *   apostrophe-S words.  These formats are mutually
                      *   exclusive.
                      */
                     if (cur.startsWith('"'))
                     {
                         /*
                          *   It's a quoted string, so it's a literal
                          *   adjective.
                          */
 
                         /* remove the quote(s) */
                         if (cur.endsWith('"'))
                             cur = cur.substr(2, cur.length() - 2);
                         else
                             cur = cur.substr(2);
 
                         /* change the part of speech to 'literal adjective' */
                         wordPart = &literalAdjective;
                     }
                     else if (cur.endsWith('\'s'))
                     {
                         /*
                          *   It's an apostrophe-s word.  Remove the "'s"
                          *   suffix and add the root word using adjApostS
                          *   as the part of speech.  The grammar rules are
                          *   defined to allow this part of speech to be
                          *   used exclusively with "'s" suffixes in input.
                          *   Since the tokenizer always pulls the "'s"
                          *   suffix off of a word in the input, we have to
                          *   store any vocabulary words with "'s" suffixes
                          *   the same way, with the "'s" suffixes removed.
                          */
 
                         /* change the part of speech to adjApostS */
                         wordPart = &adjApostS;
 
                         /* remove the "'s" suffix from the string */
                         cur = cur.substr(1, cur.length() - 2);
                     }
 
                     /* add the word to our own list for this part of speech */
                     if (self.(wordPart) == nil)
                         self.(wordPart) = [cur];
                     else
                         self.(wordPart) += cur;
 
                     /* add it to the dictionary */
                     cmdDict.addWord(self, cur, wordPart);
 
                     if (cur.endsWith('.'))
                     {
                         local abbr;
 
                         /*
                          *   It ends with a period, so this is an
                          *   abbreviated word.  Enter the abbreviation
                          *   both with and without the period.  The normal
                          *   handling will enter it with the period, so we
                          *   only need to enter it specifically without.
                          */
                         abbr = cur.substr(1, cur.length() - 1);
                         self.(wordPart) += abbr;
                         cmdDict.addWord(self, abbr, wordPart);
                     }
 
                     /* note that we added to this list */
                     if (modList.indexOf(wordPart) == nil)
                         modList += wordPart;
                 }
             }
 
             /* if we have a delimiter, see what we have */
             if (len + 1 < str.length())
             {
                 /* check the delimiter */
                 switch(str.substr(len + 1, 1))
                 {
                 case ' ':
                     /* stick with the current part */
                     break;
 
                 case '*':
                     /* start plurals */
                     sectPart = &plural;
                     break;
 
                 case '/':
                     /* start alternative nouns */
                     sectPart = &noun;
                     break;
                 }
 
                 /* remove the part up to and including the delimiter */
                 str = str.substr(len + 2);
 
                 /* skip any additional spaces following the delimiter */
                 if ((len = rexMatch('<space>+', str)) != nil)
                     str = str.substr(len + 1);
             }
             else
             {
                 /* we've exhausted the string - we're done */
                 break;
             }
         }
 
         /* uniquify each word list we updated */
         foreach (local p in modList)
             self.(p) = self.(p).getUnique();
     }
 ;
 
 /* ------------------------------------------------------------------------ */
 /*
  *   Language-specific modifications for Thing.  This class contains the
  *   methods and properties of Thing that need to be replaced when the
  *   library is translated to another language.
  *   
  *   The properties and methods defined here should generally never be used
  *   by language-independent library code, because everything defined here
  *   is specific to English.  Translators are thus free to change the
  *   entire scheme defined here.  For example, the notions of number and
  *   gender are confined to the English part of the library; other language
  *   implementations can completely replace these attributes, so they're
  *   not constrained to emulate their own number and gender systems with
  *   the English system.  
  */
 modify Thing
     /*
      *   Flag that this object's name is rendered as a plural (this
      *   applies to both a singular noun with plural usage, such as
      *   "pants" or "scissors," and an object used in the world model to
      *   represent a collection of real-world objects, such as "shrubs").
+     *
+     *   V češtině jsou to podstatná jména pomnožná, tedy jména, která mají
+     *   pouze tvar množného čísla. Např. ústa, dveře, nůžky.
      */
     isPlural = nil
 
     /*
      *   Flag that this is object's name is a "mass noun" - that is, a
      *   noun denoting a continuous (effectively infinitely divisible)
      *   substance or material, such as water, wood, or popcorn; and
      *   certain abstract concepts, such as knowledge or beauty.  Mass
      *   nouns are never rendered in the plural, and use different
      *   determiners than ordinary ("count") nouns: "some popcorn" vs "a
      *   kernel", for example.
+     *
+     *   V češtině jsou to jména, která mají pouze nebo převážně tvary čísla
+     *   jednotného, tj. abstraktní jména, jména látková a hromadná. Např.
+     *   lidstvo, voda, písek.
      */
     isMassNoun = nil
 
     /*
      *   Flags indicating that the object should be referred to with
      *   gendered pronouns (such as 'he' or 'she' rather than 'it').
      *
      *   Note that these flags aren't mutually exclusive, so it's legal
      *   for the object to have both masculine and feminine usage.  This
      *   can be useful when creating collective objects that represent
      *   more than one individual, for example.
+     *
+     *   Čeština rozlišuje rod mužský (životný a neživotný), ženský
+     *   a střední. Postupně nahradíme původní isHim/isHer českým rodem.
+     *   Vlastnost gender bude kódována číslem (abychom případně mohli
+     *   číslo použít jako index do nějaké tabulky) následovně:
+     *
+     *   1 - mužský životný
+     *   2 - mužský neživotný
+     *   3 - ženský
+     *   4 - střední
+     *
+     *   Jako výchozí hodnotu zvolíme střední rod, protože zkrátka nějakou
+     *   výchozí hodnotu potřebujeme a žádný lepší klíč nemáme.
      */
-    isHim = nil
-    isHer = nil
-
-    /*
-     *   Flag indicating that the object can be referred to with a neuter
-     *   pronoun ('it').  By default, this is true if the object has
-     *   neither masculine nor feminine gender, but it can be overridden
-     *   so that an object has both gendered and ungendered usage.  This
-     *   can be useful for collective objects, as well as for cases where
-     *   gendered usage varies by speaker or situation, such as animals.
-     */
-    isIt
-    {
-        /* by default, we're an 'it' if we're not a 'him' or a 'her' */
-        return !(isHim || isHer);
-    }
+    gender = 4
 
     /*
      *   Test to see if we can match the pronouns 'him', 'her', 'it', and
      *   'them'.  By default, these simply test the corresponding isXxx
      *   flags (except 'canMatchThem', which tests 'isPlural' to see if the
      *   name has plural usage).
      */
-    canMatchHim = (isHim)
-    canMatchHer = (isHer)
-    canMatchIt = (isIt)
+    canMatchHim = (gender == 1 || gender == 2 ? true : nil)
+    canMatchHer = (gender == 3 ? true : nil)
+    canMatchIt = (gender == 4 ? true : nil)
     canMatchThem = (isPlural)
 
     /* can we match the given PronounXxx pronoun type specifier? */
     canMatchPronounType(typ)
     {
         /* check the type, and return the appropriate indicator property */
         switch (typ)
         {
         case PronounHim:
             return canMatchHim;
 
         case PronounHer:
             return canMatchHer;
 
         case PronounIt:
             return canMatchIt;
 
         case PronounThem:
             return canMatchThem;
 
         default:
             return nil;
         }
     }
 
     /*
      *   The grammatical cardinality of this item when it appears in a
      *   list.  This is used to ensure verb agreement when mentioning the
      *   item in a list of items.  ("Cardinality" is a fancy word for "how
      *   many items does this look like").
      *
      *   English only distinguishes two degrees of cardinality in its
      *   grammar: one, or many.  That is, when constructing a sentence, the
      *   only thing the grammar cares about is whether an object is
      *   singular or plural: IT IS on the table, THEY ARE on the table.
      *   Since English only distinguishes these two degrees, two is the
      *   same as a hundred is the same as a million for grammatical
      *   purposes, so we'll consider our cardinality to be 2 if we're
      *   plural, 1 otherwise.
      *
      *   Some languages don't express cardinality at all in their grammar,
      *   and others distinguish cardinality in greater detail than just
      *   singular-vs-plural, which is why this method has to be in the
      *   language-specific part of the library.
      */
     listCardinality(lister) { return isPlural ? 2 : 1; }
 
     /*
-     *   Proper name flag.  This indicates that the 'name' property is the
-     *   name of a person or place.  We consider proper names to be fully
-     *   qualified, so we don't add articles for variations on the name
-     *   such as 'theName'.
-     */
-    isProperName = nil
-
-    /*
-     *   Qualified name flag.  This indicates that the object name, as
-     *   given by the 'name' property, is already fully qualified, so
-     *   doesn't need qualification by an article like "the" or "a" when
-     *   it appears in a sentence.  By default, a name is considered
-     *   qualified if it's a proper name, but this can be overridden to
-     *   mark a non-proper name as qualified when needed.
-     */
-    isQualifiedName = (isProperName)
-
-    /*
      *   The name of the object - this is a string giving the object's
      *   short description, for constructing sentences that refer to the
      *   object by name.  Each instance should override this to define the
      *   name of the object.  This string should not contain any articles;
      *   we use this string as the root to generate various forms of the
      *   object's name for use in different places in sentences.
+     *
+     *   V češtině samozřejmě potřebujeme název objektu v mnoha pádech pro
+     *   použití v různých situacích. Proto přidáme vlastnosti pokrývající
+     *   další pády a jako výchozí hodnotu do nich vložíme první pád
+     *   z vlastnosti name.
      */
     name = ''
+    nameKohoCeho = (name)
+    nameKomuCemu = (name)
+    nameKohoCo = (name)
+    nameKomCem = (name)
+    nameKymCim = (name)
 
     /*
      *   The name of the object, for the purposes of disambiguation
      *   prompts.  This should almost always be the object's ordinary
      *   name, so we return self.name by default.
      *
      *   In rare cases, it might be desirable to override this.  In
      *   particular, if a game has two objects that are NOT defined as
      *   basic equivalents of one another (which means that the parser
      *   will always ask for disambiguation when the two are ambiguous
      *   with one another), but the two nonetheless have identical 'name'
      *   properties, this property should be overridden for one or both
      *   objects to give them different names.  This will ensure that we
      *   avoid asking questions of the form "which do you mean, the coin,
      *   or the coin?".  In most cases, non-equivalent objects will have
      *   distinct 'name' properties to begin with, so this is not usually
      *   an issue.
      *
      *   When overriding this method, take care to override
      *   theDisambigName, aDisambigName, countDisambigName, and/or
      *   pluralDisambigName as needed.  Those routines must be overridden
      *   only when the default algorithms for determining articles and
      *   plurals fail to work properly for the disambigName (for example,
      *   the indefinite article algorithm fails with silent-h words like
      *   "hour", so if disambigName is "hour", aDisambigName must be
      *   overridden).  In most cases, the automatic algorithms will
      *   produce acceptable results, so the default implementations of
      *   these other routines can be used without customization.
+     *
+     *   Při řešení nejasností se ptáme na objekt čtvrtým pádem.
+     *   (Koho/co máš na mysli? Nejprve bereš koho/co?)
      */
-    disambigName = (name)
+    disambigName = (nameKohoCo)
 
     /*
      *   The "equivalence key" is the value we use to group equivalent
      *   objects.  Note that we can only treat objects as equivalent when
      *   they're explicitly marked with isEquivalent=true, so the
      *   equivalence key is irrelevant for objects not so marked.
      *   
      *   Since the main point of equivalence is to allow creation of groups
      *   of like-named objects that are interchangeable in listings and in
      *   command input, we use the basic disambiguation name as the
      *   equivalence key.  
      */
     equivalenceKey = (disambigName)
 
     /*
-     *   The definite-article name for disambiguation prompts.
-     *
-     *   By default, if the disambiguation name is identical to the
-     *   regular name (i.e, the string returned by self.disambigName is
-     *   the same as the string returned by self.name), then we simply
-     *   return self.theName.  Since the base name is the same in either
-     *   case, presumably the definite article names should be the same as
-     *   well.  This way, if the object overrides theName to do something
-     *   special, then we'll use the same definite-article name for
-     *   disambiguation prompts.
-     *
-     *   If the disambigName isn't the same as the regular name, then
-     *   we'll apply the same algorithm to the base disambigName that we
-     *   normally do to the regular name to produce the theName.  This
-     *   way, if the disambigName is overridden, we'll use the overridden
-     *   disambigName to produce the definite-article version, using the
-     *   standard definite-article algorithm.
-     *
-     *   Note that there's an aspect of this conditional approach that
-     *   might not be obvious.  It might look as though the test is
-     *   redundant: if name == disambigName, after all, and the default
-     *   theName returns theNameFrom(name), then this ought to be
-     *   identical to returning theNameFrom(disambigName).  The subtlety
-     *   is that theName could be overridden to produce a custom result,
-     *   in which case returning theNameFrom(disambigName) would return
-     *   something different, which probably wouldn't be correct: the
-     *   whole reason theName would be overridden is that the algorithmic
-     *   determination (theNameFrom) gets it wrong.  So, by calling
-     *   theName directly when disambigName is the same as name, we are
-     *   assured that we pick up any override in theName.
-     *
-     *   Note that in rare cases, neither of these default approaches will
-     *   produce the right result; this will happen if the object uses a
-     *   custom disambigName, but that name doesn't fit the normal
-     *   algorithmic pattern for applying a definite article.  In these
-     *   cases, the object should simply override this method to specify
-     *   the custom name.
-     */
-    theDisambigName = (name == disambigName
-                       ? theName : theNameFrom(disambigName))
-
-    /*
-     *   The indefinite-article name for disambiguation prompts.  We use
-     *   the same logic here as in theDisambigName.
-     */
-    aDisambigName = (name == disambigName ? aName : aNameFrom(disambigName))
-
-    /*
      *   The counted name for disambiguation prompts.  We use the same
      *   logic here as in theDisambigName.
      */
     countDisambigName(cnt)
     {
         return (name == disambigName && pluralName == pluralDisambigName
                 ? countName(cnt)
                 : countNameFrom(cnt, disambigName, pluralDisambigName));
     }
 
     /*
      *   The plural name for disambiguation prompts.  We use the same
      *   logic here as in theDisambigName.
+     *
+     *   V češtině nemůžeme nagenerovat plurál automaticky, takže použijeme
+     *   pluralName a autor musí předefinovat stejně, jako u disambigName.
+     *
+     *   TODO: Mělo by tu být spíš pluralNameKohoCo, ale ty asi zatim vubec
+     *   nepouzivam? A k čemu dalšímu se pluralName vůbec používá?
      */
-    pluralDisambigName = (name == disambigName
-                          ? pluralName : pluralNameFrom(disambigName))
+    pluralDisambigName = (pluralName)
 
     /*
      *   The name of the object, for the purposes of disambiguation prompts
      *   to disambiguation among this object and basic equivalents of this
      *   object (i.e., objects of the same class marked with
      *   isEquivalent=true).
      *
      *   This is used in disambiguation prompts in place of the actual text
      *   typed by the user.  For example, suppose the user types ">take
      *   coin", then we ask for help disambiguating, and the player types
      *   ">gold".  This narrows things down to, say, three gold coins, but
      *   they're in different locations so we need to ask for further
      *   disambiguation.  Normally, we ask "which gold do you mean",
      *   because the player typed "gold" in the input.  Once we're down to
      *   equivalents, we don't have to rely on the input text any more,
      *   which is good because the input text could be fragmentary (as in
      *   our present example).  Since we have only equivalents, we can use
      *   the actual name of the objects (they're all the same, after all).
      *   This property gives the name we use.
      *
      *   For English, this is simply the object's ordinary disambiguation
      *   name.  This property is separate from 'name' and 'disambigName'
      *   for the sake of languages that need to use an inflected form in
      *   this context.
      */
     disambigEquivName = (disambigName)
 
     /*
      *   Single-item listing description.  This is used to display the
      *   item when it appears as a single (non-grouped) item in a list.
      *   By default, we just show the indefinite article description.
-     */
-    listName = (aName)
+     *
+     *   Ve vetsine seznamu je vhodny 4. pad ("U sebe mas koho/co", "vidis
+     *   tu koho/co". Jenze "Na povrchu je kdo/co." a "Kroužek na klíče
+     *   s navlečeným kým/čím."
+     */
+    listName = (name)
+    listNameKohoCo = (nameKohoCo)
+    listNameKomuCemu = (nameKomuCemu)
+    listNameKymCim = (nameKymCim)
 
     /*
      *   Return a string giving the "counted name" of the object - that is,
      *   a phrase describing the given number of the object.  For example,
      *   for a red book, and a count of 5, we might return "five red
      *   books".  By default, we use countNameFrom() to construct a phrase
      *   from the count and either our regular (singular) 'name' property
      *   or our 'pluralName' property, according to whether count is 1 or
      *   more than 1.  
      */
     countName(count) { return countNameFrom(count, name, pluralName); }
 
     /*
      *   Returns a string giving a count applied to the name string.  The
      *   name must be given in both singular and plural forms.
      */
     countNameFrom(count, singularStr, pluralStr)
     {
         /* if the count is one, use 'one' plus the singular name */
-        if (count == 1)
-            return 'one ' + singularStr;
+        if(count == 1) return ['jeden', 'jeden', 'jedna', 'jedno'][gender]
+            + ' ' + singularStr;
 
         /*
          *   Get the number followed by a space - spell out numbers below
          *   100, but use numerals to denote larger numbers.  Append the
          *   plural name to the number and return the result.
          */
-        return spellIntBelowExt(count, 100, 0, DigitFormatGroupSep)
+        return spellIntBelowExt(count, gender, 100, 0, DigitFormatGroupSep)
             + ' ' + pluralStr;
     }
 
     /*
      *   Get the 'pronoun selector' for the various pronoun methods.  This
      *   returns:
      *   
      *.  - singular neuter = 1
      *.  - singular masculine = 2
      *.  - singular feminine = 3
      *.  - plural = 4
+     *
+     *   Přeházíme na logičtější mužský = 1, ženský = 2, střední = 3, plurál = 4
      */
-    pronounSelector = (isPlural ? 4 : isHer ? 3 : isHim ? 2 : 1)
+    pronounSelector = (isPlural ? 4 : gender == 3 ? 2 : gender == 4 ? 3 : 1)
 
     /*
-     *   get a string with the appropriate pronoun for the object for the
-     *   nominative case, objective case, possessive adjective, possessive
-     *   noun
+     *   Pravidelná slovesa
+     *
+     *   Mají pět slovesných tříd, podle kterých je ovlivněna koncovka slovesa
+     *   a tak můžeme poskytnout substituční parametr. U Actora jsou tyto funkce
+     *   přetížené a rozlišují ještě referralPerson, ale na neživé objekty se
+     *   odkazujeme výhradně ve třetí osobě.
      */
-    itNom { return ['it', 'he', 'she', 'they'][pronounSelector]; }
-    itObj { return ['it', 'him', 'her', 'them'][pronounSelector]; }
-    itPossAdj { return ['its', 'his', 'her', 'their'][pronounSelector]; }
-    itPossNoun { return ['its', 'his', 'hers', 'theirs'][pronounSelector]; }
+    slovesoEs { return isPlural ? 'ou' : 'e'; }
+    slovesoNes { return isPlural ? 'nou' : 'ne'; }
+    slovesoJes { return isPlural ? 'jí' : 'je'; }
+    slovesoIs { return isPlural ? 'í' : 'í'; }
+    slovesoAs { return isPlural ? 'ají' : 'á'; }
 
-    /* get the object reflexive pronoun (itself, etc) */
-    itReflexive
+    /*
+     *   Koncovka slovesa v minulém čase
+     *
+     *   U slovesa v minulém čase je situace jednodušší, na slovesné třídě vůbec
+     *   nezáleží a rozhoduje jen číslo a rod.
+     */
+    slovesoMin
     {
-        return ['itself', 'himself', 'herself', 'themselves']
-               [pronounSelector];
+        return (isPlural ? ['i', 'y', 'y', 'a'][gender] : ['', '', 'a', 'o'][gender]);
     }
 
-    /* demonstrative pronouns ('that' or 'those') */
-    thatNom { return ['that', 'he', 'she', 'those'][pronounSelector]; }
-    thatIsContraction
+    /* Několik nepravidelných sloves */
+    slovesoJe
     {
-        return thatNom + tSel(isPlural ? ' are' : '&rsquo;s', ' ' + verbToBe);
+        return tSel(isPlural ? 'jsou' : 'je', ['byl', 'byl', 'byla', 'bylo',
+            'byli', 'byly', 'byly', 'byla'][gender + (isPlural ? 4 : 0)]);
     }
-    thatObj { return ['that', 'him', 'her', 'those'][pronounSelector]; }
 
-    /*
-     *   get a string with the appropriate pronoun for the object plus the
-     *   correct conjugation of 'to be'
-     */
-    itIs { return itNom + ' ' + verbToBe; }
-
-    /* get a pronoun plus a 'to be' contraction */
-    itIsContraction
+    slovesoNeni
     {
-        return itNom
-            + tSel(isPlural ? '&rsquo;re' : '&rsquo;s', ' ' + verbToBe);
+        return tSel(isPlural ? 'nejsou' : 'není',
+            ['nebyl', 'nebyl', 'nebyla', 'nebylo', 'nebyli', 'nebyly',
+            'nebyly', 'nebyla'][gender + (isPlural ? 4 : 0)]);
     }
 
-    /*
-     *   get a string with the appropriate pronoun for the object plus the
-     *   correct conjugation of the given regular verb for the appropriate
-     *   person
-     */
-    itVerb(verb)
+    /* tohle prijde odstehovat do actora, ale zjistit, zda tu nepotrebuju zjednodusene verze */
+    slovesoBytProMinulyCas
+    {
+        return (referralPerson == FirstPerson ? (isPlural ? 'jsme' : 'jsem') : '')
+            + (referralPerson == SecondPerson ? (isPlural ? 'jste' : 'jsi') : '')
+            + (referralPerson == ThirdPerson ? (isPlural ? '' : '') : '');
+    }
+    slovesoByt
+    {
+        return (referralPerson == FirstPerson ? (isPlural ? 'jsme' : 'jsem') : '')
+            + (referralPerson == SecondPerson ? (isPlural ? 'jste' : 'jsi') : '')
+            + (referralPerson == ThirdPerson ? (isPlural ? 'jsou' : 'je') : '');
+    }
+    slovesoNebyt
+    {
+        return (referralPerson == FirstPerson ? (isPlural ? 'nejsme' : 'nejsem') : '')
+            + (referralPerson == SecondPerson ? (isPlural ? 'nejste' : 'nejsi') : '')
+            + (referralPerson == ThirdPerson ? (isPlural ? 'nejsou' : 'není') : '');
+    }
+    slovesoBytPodmin
+    {
+        return (referralPerson == FirstPerson ? (isPlural ? 'bychom' : 'bych') : '')
+            + (referralPerson == SecondPerson ? (isPlural ? 'byste' : 'bys') : '')
+            + (referralPerson == ThirdPerson ? 'by' : '');
+    }
+    slovesoChces
+    {
+        return (referralPerson == FirstPerson ? (isPlural ? 'chceme' : 'chci') : '')
+            + (referralPerson == SecondPerson ? (isPlural ? 'chcete' : 'chceš') : '')
+            + (referralPerson == ThirdPerson ? (isPlural ? 'chtějí' : 'chce') : '');
+    }
+    slovesoSel
     {
-        return itNom + ' ' + conjugateRegularVerb(verb);
+        return isPlural ? 'šl' + ['i', 'y', 'y', 'a'][gender]
+            : ['šel', 'šel', 'šla', 'šlo'][gender];
     }
 
     /*
-     *   Conjugate a regular verb in the present or past tense for our
-     *   person and number.
-     *
-     *   In the present tense, this is pretty easy: we add an 's' for the
-     *   third person singular, and leave the verb unchanged for plural (it
-     *   asks, they ask).  The only complication is that we must check some
-     *   special cases to add the -s suffix: -y -> -ies (it carries), -o ->
-     *   -oes (it goes).
+     *   Přídavná jména:
      *
-     *   In the past tense, we can equally easily figure out when to use
-     *   -d, -ed, or -ied.  However, we have a more serious problem: for
-     *   some verbs, the last consonant of the verb stem should be repeated
-     *   (as in deter -> deterred), and for others it shouldn't (as in
-     *   gather -> gathered).  To figure out which rule applies, we would
-     *   sometimes need to know whether the last syllable is stressed, and
-     *   unfortunately there is no easy way to determine that
-     *   programmatically.
+     *   1. pád - pridavneJmenoMlady
+     *   3. pád - pridavneJmenoMlademu
+     *   6. pád - pridavneJmenoMladem
+     *   7. pád - pridavneJmenoMladym
      *
-     *   Therefore, we do *not* handle the case where the last consonant is
-     *   repeated in the past tense.  You shouldn't use this method for
-     *   this case; instead, treat it as you would handle an irregular
-     *   verb, by explicitly specifying the correct past tense form via the
-     *   tSel macro.  For example, to generate the properly conjugated form
-     *   of the verb "deter" for an object named "thing", you could use an
-     *   expression such as:
-     *
-     *   'deter' + tSel(thing.verbEndingS, 'red')
-     *
-     *   This would correctly generate "deter", "deters", or "deterred"
-     *   depending on the number of the object named "thing" and on the
-     *   current narrative tense.
+     *   http://cs.wikipedia.org/wiki/%C4%8Cesk%C3%A1_p%C5%99%C3%ADdavn%C3%A1_jm%C3%A9na
      */
-    conjugateRegularVerb(verb)
+    pridavneJmenoMlady
     {
-        /*
-         *   Which tense are we currently using?
-         */
-        if (gameMain.usePastTense)
-        {
-            /*
-             *   We want the past tense form.
-             *
-             *   If the last letter is 'e', simply add 'd'.
-             */
-            if (verb.endsWith('e')) return verb + 'd';
-
-            /*
-             *   Otherwise, if the verb ending would become 'ies' in the
-             *   third-person singular present, then it becomes 'ied' in
-             *   the past.
-             */
-            else if (rexMatch(iesEndingPat, verb))
-                    return verb.substr(1, verb.length() - 1) + 'ied';
-
-            /*
-             *   Otherwise, use 'ed' as the ending.  Don't try to determine
-             *   if the last consonant should be repeated: that's too
-             *   complicated.  We'll just ignore the possibility.
-             */
-            else return verb + 'ed';
-        }
-        else
-        {
-            /*
-             *   We want the present tense form.
-             *
-             *   Check our number and person.
-             */
-            if (isPlural)
-            {
-                /*
-                 *   We're plural, so simply use the base verb form ("they
-                 *   ask").
-                 */
-                return verb;
-            }
-            else
-            {
-                /*
-                 *   Third-person singular, so we must add the -s suffix.
-                 *   Check for special spelling cases:
-                 *
-                 *   '-y' changes to '-ies', unless the 'y' is preceded by
-                 *   a vowel
-                 *
-                 *   '-sh', '-ch', and '-o' endings add suffix '-es'
-                 */
-                if (rexMatch(iesEndingPat, verb))
-                    return verb.substr(1, verb.length() - 1) + 'ies';
-                else if (rexMatch(esEndingPat, verb))
-                    return verb + 'es';
-                else
-                    return verb + 's';
-            }
-        }
+        return ['ý', 'ý', 'á', 'é', 'í', 'é', 'é', 'á'][gender + (isPlural ? 4
+            : 0)];
+    }
+    pridavneJmenoMlademu
+    {
+        return ['ému', 'ému', 'é', 'ému', 'ým', 'ým', 'ým', 'ým'][gender +
+            (isPlural ? 4 : 0)];
+    }
+    pridavneJmenoMladem
+    {
+        return ['ém', 'ém', 'é', 'ém', 'ých', 'ých', 'ých', 'ých'][gender +
+            (isPlural ? 4 : 0)];
+    }
+    pridavneJmenoMladym
+    {
+        return ['ým', 'ým', 'ou', 'ým', 'ými', 'ými', 'ými', 'ými'][gender +
+            (isPlural ? 4 : 0)];
     }
-
-    /* verb-ending patterns for figuring out which '-s' ending to add */
-    iesEndingPat = static new RexPattern('.*[^aeiou]y$')
-    esEndingPat = static new RexPattern('.*(o|ch|sh)$')
-
-    /*
-     *   Get the name with a definite article ("the box").  By default, we
-     *   use our standard definite article algorithm to apply an article
-     *   to self.name.
-     *
-     *   The name returned must be in the nominative case (which makes no
-     *   difference unless the name is a pronoun, since in English
-     *   ordinary nouns don't vary according to how they're used in a
-     *   sentence).
-     */
-    theName = (theNameFrom(name))
-
-    /*
-     *   theName in objective case.  In most cases, this is identical to
-     *   the normal theName, so we use that by default.  This must be
-     *   overridden if theName is a pronoun (which is usually only the
-     *   case for player character actors; see our language-specific Actor
-     *   modifications for information on that case).
-     */
-    theNameObj { return theName; }
-
-    /*
-     *   Generate the definite-article name from the given name string.
-     *   If my name is already qualified, don't add an article; otherwise,
-     *   add a 'the' as the prefixed definite article.
-     */
-    theNameFrom(str) { return (isQualifiedName ? '' : 'the ') + str; }
 
     /*
-     *   theName as a possessive adjective (Bob's book, your book).  If the
-     *   name's usage is singular (i.e., isPlural is nil), we'll simply add
-     *   an apostrophe-S.  If the name is plural, and it ends in an "s",
-     *   we'll just add an apostrophe (no S).  If it's plural and doesn't
-     *   end in "s", we'll add an apostrophe-S.
-     *
-     *   Note that some people disagree about the proper usage for
-     *   singular-usage words (especially proper names) that end in 's'.
-     *   Some people like to use a bare apostrophe for any name that ends
-     *   in 's' (so Chris -> Chris'); other people use apostrophe-s for
-     *   singular words that end in an "s" sound and a bare apostrophe for
-     *   words that end in an "s" that sounds like a "z" (so Charles
-     *   Dickens -> Charles Dickens').  However, most usage experts agree
-     *   that proper names take an apostrophe-S in almost all cases, even
-     *   when ending with an "s": "Chris's", "Charles Dickens's".  That's
-     *   what we do here.
+     *   Osobní zájmena:
      *
-     *   Note that this algorithm doesn't catch all of the special
-     *   exceptions in conventional English usage.  For example, Greek
-     *   names ending with "-es" are usually written with the bare
-     *   apostrophe, but we don't have a property that tells us whether the
-     *   name is Greek or not, so we can't catch this case.  Likewise, some
-     *   authors like to possessive-ize words that end with an "s" sound
-     *   with a bare apostrophe, as in "for appearance' sake", and we don't
-     *   attempt to catch these either.  For any of these exceptions, you
-     *   must override this method for the individual object.
+     *   1. pád - zajmenoTy
+     *   2. pád - zajmenoTebe2J/N, zajmenoTe2J/N
+     *   3. pád - zajmenoTobe3J/N, zajmenoTiJ/N
+     *   4. pád - zajmenoTebe4J/N, zajmenoTe4J/N, zajmenoJej4J/N
+     *   6. pád - zajmenoTobe6
+     *   7. pád - zajmenoTebouJ/N
      */
-    theNamePossAdj
+    zajmenoTy
     {
-        /* add apostrophe-S, unless it's a plural ending with 's' */
-        return theName
-            + (isPlural && theName.endsWith('s') ? '&rsquo;' : '&rsquo;s');
+        return isPlural && gender == 3 ? 'ony'
+            : isPlural && gender == 4 ? 'ona'
+            : ['on', 'ona', 'ono', 'oni'][pronounSelector];
     }
+    zajmenoTebe2J { return ['jeho', 'jí', 'jeho', 'jich'][pronounSelector]; }
+    zajmenoTebe2N { return ['něho', 'ní', 'něho', 'nich'][pronounSelector]; }
+    zajmenoTe2J { return ['ho', 'jí', 'ho', 'jich'][pronounSelector]; }
+    zajmenoTe2N { return ['ho', 'ní', 'ho', 'nich'][pronounSelector]; }
+    zajmenoTobe3J { return ['jemu', 'jí', 'jemu', 'jim'][pronounSelector]; }
+    zajmenoTobe3N { return ['němu', 'ní', 'němu', 'nim'][pronounSelector]; }
+    zajmenoTiJ { return ['mu', 'jí', 'mu', 'jim'][pronounSelector]; }
+    zajmenoTiN { return ['mu', 'ní', 'mu', 'nim'][pronounSelector]; }
+    zajmenoTebe4J { return ['jeho', 'ji', 'jej', 'je'][pronounSelector]; }
+    zajmenoTebe4N { return ['něho', 'ni', 'něj', 'ně'][pronounSelector]; }
+    zajmenoTe4J { return ['ho', 'ji', 'ho', 'je'][pronounSelector]; }
+    zajmenoTe4N { return ['ho', 'ni', 'ho', 'ně'][pronounSelector]; }
+    zajmenoJej4J { return ['jej', 'ji', 'jej', 'je'][pronounSelector]; }
+    zajmenoJej4N { return ['něj', 'ni', 'něj', 'ně'][pronounSelector]; }
+    zajmenoTobe6 { return ['něm', 'ní', 'něm', 'nich'][pronounSelector]; }
+    zajmenoTebouJ { return ['jím', 'jí', 'jím', 'jimi'][pronounSelector]; }
+    zajmenoTebouN { return ['ním', 'ní', 'ním', 'nimi'][pronounSelector]; }
 
-    /*
-     *   TheName as a possessive noun (that is Bob's, that is yours).  We
-     *   simply return the possessive adjective name, since the two forms
-     *   are usually identical in English (except for pronouns, where they
-     *   sometimes differ: "her" for the adjective vs "hers" for the noun).
-     */
-    theNamePossNoun = (theNamePossAdj)
+    /* ukazovací zájmena */
+    zajmenoSam
+    {
+        return ['sám', 'sám', 'sama', 'samo', 'sami', 'samy', 'samy', 'sama']
+            [gender + (isPlural ? 4 : 0)];
+    }
 
     /*
      *   theName with my nominal owner explicitly stated, if we have a
      *   nominal owner: "your backpack," "Bob's flashlight."  If we have
      *   no nominal owner, this is simply my theName.
      */
-    theNameWithOwner()
+    nameWithOwner()
     {
         local owner;
 
         /*
          *   if we have a nominal owner, show with our owner name;
          *   otherwise, just show our regular theName
+         *
+         *   TODO: Else vrací "Červený bonbón na *zemi*" Je potřeba vymyslet
+         *   jinak, tohle nedává smysl.
          */
         if ((owner = getNominalOwner()) != nil)
-            return owner.theNamePossAdj + ' ' + name;
+            return owner.nameKohoCeho + ' ' + name;
         else
-            return theName;
+            return nameKomCem;
     }
 
     /*
      *   Default preposition to use when an object is in/on this object.
      *   By default, we use 'in' as the preposition; subclasses can
      *   override to use others (such as 'on' for a surface).
-     */
-    objInPrep = 'in'
-
-    /*
+     *
      *   Default preposition to use when an actor is in/on this object (as
      *   a nested location), and full prepositional phrase, with no article
      *   and with an indefinite article.  By default, we use the objInPrep
      *   for actors as well.
+     *
+     *   Důležité je si uvědomit, že objInPrep nemá konkrétně znamenat jen "v",
+     *   ale i "na", "pod", "za" apod. Vyjadřuje přítomnost jiného objektu
+     *   v tomto, ať už je to kontejner, surface apod.
+     *
+     *   Vyjádření vhodného pádu provedeme novou vlastností. V anglické verzi
+     *   to není potřeba, protože se přizpůsobuje jen objIn/OutOf/IntoName,
+     *   ale v češtině se hodí k ovlivnění pádu zájmena "který" (např. ve kterém
+     *   vs. pod kterým).
      */
-    actorInPrep = (objInPrep)
+    objInPrep = 'v'
+    objInPad = 6
 
     /* preposition to use when an actor is being removed from this location */
-    actorOutOfPrep = 'out of'
+    objOutOfPrep = 'ven z'
 
     /* preposition to use when an actor is being moved into this location */
-    actorIntoPrep
+    objIntoPrep
     {
-        if (actorInPrep is in ('in', 'on'))
-            return actorInPrep + 'to';
+        if (objInPrep is in ('v', 've'))
+            return 'do';
         else
-            return actorInPrep;
+            return objInPrep;
     }
+    objIntoPad = 2
 
     /*
      *   describe an actor as being in/being removed from/being moved into
      *   this location
      */
-    actorInName = (actorInPrep + ' ' + theNameObj)
-    actorInAName = (actorInPrep + ' ' + aNameObj)
-    actorOutOfName = (actorOutOfPrep + ' ' + theNameObj)
-    actorIntoName = (actorIntoPrep + ' ' + theNameObj)
+    objInName = (objInPrep + ' ' + (objInPad == 6 ? nameKomCem : objInPad == 7 ? nameKymCim : ''))
+    objOutOfName = (objOutOfPrep + ' ' + nameKohoCeho)
+    objIntoName = (objIntoPrep + ' ' + (objIntoPad == 2 ? nameKohoCeho : objIntoPad == 4 ? nameKohoCo : ''))
 
     /*
      *   A prepositional phrase that can be used to describe things that
      *   are in this room as seen from a remote point of view.  This
      *   should be something along the lines of "in the airlock", "at the
      *   end of the alley", or "on the lawn".
      *
      *   'pov' is the point of view from which we're seeing this room;
      *   this might be
      *
      *   We use this phrase in cases where we need to describe things in
      *   this room when viewed from a point of view outside of the room
      *   (i.e., in a different top-level room).  By default, we'll use our
-     *   actorInName.
+     *   objInName.
      */
-    inRoomName(pov) { return actorInName; }
+    inRoomName(pov) { return objInName; }
 
     /*
      *   Provide the prepositional phrase for an object being put into me.
      *   For a container, for example, this would say "into the box"; for
      *   a surface, it would say "onto the table."  By default, we return
      *   our library message given by our putDestMessage property; this
      *   default is suitable for most cases, but individual objects can
      *   customize as needed.  When customizing this, be sure to make the
      *   phrase suitable for use in sentences like "You put the book
      *   <<putInName>>" and "The book falls <<putInName>>" - the phrase
      *   should be suitable for a verb indicating active motion by the
      *   object being received.
      */
     putInName() { return gLibMessages.(putDestMessage)(self); }
 
     /*
      *   Get a description of an object within this object, describing the
      *   object's location as this object.  By default, we'll append "in
      *   <theName>" to the given object name.
      */
     childInName(childName)
-        { return childInNameGen(childName, theName); }
+        { return childInNameGen(childName, name); }
 
     /*
      *   Get a description of an object within this object, showing the
      *   owner of this object.  This is similar to childInName, but
      *   explicitly shows the owner of the containing object, if any: "the
      *   flashlight in bob's backpack".
+     *
+     *   "Který červený bonbón máš na mysli: *červený bonbón na zemi*, nebo
+     *   tvůj červený bonbón?" a nameWithOwner je právě to "zemi" a zřejmě
+     *   může pojmenovávat i vlastníka.
      */
     childInNameWithOwner(childName)
-        { return childInNameGen(childName, theNameWithOwner); }
+        { return childInNameGen(childName, nameWithOwner); }
 
     /*
      *   get a description of an object within this object, as seen from a
      *   remote location
      */
     childInRemoteName(childName, pov)
         { return childInNameGen(childName, inRoomName(pov)); }
 
     /*
      *   Base routine for generating childInName and related names.  Takes
      *   the name to use for the child and the name to use for me, and
      *   combines them appropriately.
      *
      *   In most cases, this is the only one of the various childInName
      *   methods that needs to be overridden per subclass, since the others
      *   are defined in terms of this one.  Note also that if the only
      *   thing you need to do is change the preposition from 'in' to
      *   something else, you can just override objInPrep instead.
      */
     childInNameGen(childName, myName)
         { return childName + ' ' + objInPrep + ' ' + myName; }
 
     /*
      *   Get my name (in various forms) distinguished by my owner or
      *   location.
      *
      *   If the object has an owner, and either we're giving priority to
      *   the owner or our immediate location is the same as the owner,
      *   we'll show using a possessive form with the owner ("bob's
      *   flashlight").  Otherwise, we'll show the name distinguished by
      *   our immediate container ("the flashlight in the backpack").
      *
      *   These are used by the ownership and location distinguishers to
      *   list objects according to owners in disambiguation lists.  The
      *   ownership distinguisher gives priority to naming by ownership,
      *   regardless of the containment relationship between owner and
      *   self; the location distinguisher gives priority to naming by
      *   location, showing the owner only if the owner is the same as the
      *   location.
      *
      *   We will presume that objects with proper names are never
      *   indistinguishable from other objects with proper names, so we
      *   won't worry about cases like "Bob's Bill".  This leaves us free
      *   to use appropriate articles in all cases.
      */
-    aNameOwnerLoc(ownerPriority)
+    nameOwnerLoc(ownerPriority)
     {
         local owner;
 
         /* show in owner or location format, as appropriate */
         if ((owner = getNominalOwner()) != nil
             && (ownerPriority || isDirectlyIn(owner)))
         {
-            local ret;
-
             /*
              *   we have an owner - show as "one of Bob's items" (or just
              *   "Bob's items" if this is a mass noun or a proper name)
+             *
+             *   Tohle bylo v aNameOwnerLoc, jinak stejne jako theNameOwnerLoc
+             *
+             *   ret = owner.nameKohoCeho + ' ' + pluralName;
+             *   if (!isMassNoun && !isPlural)
+             *       ret = 'one of ' + ret;
              */
-            ret = owner.theNamePossAdj + ' ' + pluralName;
-            if (!isMassNoun && !isPlural)
-                ret = 'one of ' + ret;
-
-            /* return the result */
-            return ret;
-        }
-        else
-        {
-            /* we have no owner - show as "an item in the location" */
-            return location.childInNameWithOwner(aName);
-        }
-    }
-    theNameOwnerLoc(ownerPriority)
-    {
-        local owner;
-
-        /* show in owner or location format, as appropriate */
-        if ((owner = getNominalOwner()) != nil
-            && (ownerPriority || isDirectlyIn(owner)))
-        {
-            /* we have an owner - show as "Bob's item" */
-            return owner.theNamePossAdj + ' ' + name;
+            /*
+             *   we have an owner - show as "Bob's item"
+             *
+             *   "A který zelený bonbón má na mysli? Zelený bonbón na zemi,
+             *   nebo *její zelený bonbón*?"
+             *
+             *   Rozlišujeme rod cílového objektu - tvůj hrad, tvoje růže.
+             */
+            return (gender <= 2 ? owner.zajmenoTvuj : owner.zajmenoTvoje) + ' '
+                + name;
         }
         else
         {
-            /* we have no owner - show as "the item in the location" */
-            return location.childInNameWithOwner(theName);
+            /*
+             *   we have no owner - show as "the item in the location"
+             *
+             *   "A který zelený bonbón má na mysli? *Zelený bonbón na zemi*,
+             *   nebo she’s zelený bonbón?"
+             */
+            return location.childInNameWithOwner(name);
         }
     }
     countNameOwnerLoc(cnt, ownerPriority)
     {
         local owner;
 
         /* show in owner or location format, as appropriate */
         if ((owner = getNominalOwner()) != nil
             && (ownerPriority || isDirectlyIn(owner)))
         {
             /* we have an owner - show as "Bob's five items" */
-            return owner.theNamePossAdj + ' ' + countName(cnt);
+            /* TODO: Tohle je špatně postavený fragment, má být přídavné jméno? */
+            return owner.nameKohoCeho + ' ' + countName(cnt);
         }
         else
         {
             /* we have no owner - show as "the five items in the location" */
-            return location.childInNameWithOwner('the ' + countName(cnt));
+            return location.childInNameWithOwner(countName(cnt));
         }
     }
 
     /*
      *   Note that I'm being used in a disambiguation prompt by
      *   owner/location.  If we're showing the owner, we'll set the
      *   antecedent for the owner's pronoun, if the owner is a 'him' or
      *   'her'; this allows the player to refer back to our prompt text
      *   with appropriate pronouns.
      */
     notePromptByOwnerLoc(ownerPriority)
     {
         local owner;
 
         /* show in owner or location format, as appropriate */
         if ((owner = getNominalOwner()) != nil
             && (ownerPriority || isDirectlyIn(owner)))
         {
             /* we are showing by owner - let the owner know about it */
             owner.notePromptByPossAdj();
         }
     }
 
     /*
      *   Note that we're being used in a prompt question with our
      *   possessive adjective.  If we're a 'him' or a 'her', set our
      *   pronoun antecedent so that the player's response to the prompt
      *   question can refer back to the prompt text by pronoun.
      */
     notePromptByPossAdj()
     {
-        if (isHim)
+        if (gender == 1 || gender == 2)
             gPlayerChar.setHim(self);
-        if (isHer)
+        if (gender == 3)
             gPlayerChar.setHer(self);
     }
 
     /*
-     *   My name with an indefinite article.  By default, we figure out
-     *   which article to use (a, an, some) automatically.
-     *
-     *   In rare cases, the automatic determination might get it wrong,
-     *   since some English spellings defy all of the standard
-     *   orthographic rules and must simply be handled as special cases;
-     *   for example, the algorithmic determination doesn't know about
-     *   silent-h words like "hour".  When the automatic determination
-     *   gets it wrong, simply override this routine to specify the
-     *   correct article explicitly.
-     */
-    aName = (aNameFrom(name))
-
-    /* the indefinite-article name in the objective case */
-    aNameObj { return aName; }
-
-    /*
-     *   Apply an indefinite article ("a box", "an orange", "some lint")
-     *   to the given name.  We'll try to figure out which indefinite
-     *   article to use based on what kind of noun phrase we use for our
-     *   name (singular, plural, or a "mass noun" like "lint"), and our
-     *   spelling.
-     *
-     *   By default, we'll use the article "a" if the name starts with a
-     *   consonant, or "an" if it starts with a vowel.
-     *
-     *   If the name starts with a "y", we'll look at the second letter;
-     *   if it's a consonant, we'll use "an", otherwise "a" (hence "an
-     *   yttrium block" but "a yellow brick").
-     *
-     *   If the object is marked as having plural usage, we will use
-     *   "some" as the article ("some pants" or "some shrubs").
-     *
-     *   Some objects will want to override the default behavior, because
-     *   the lexical rules about when to use "a" and "an" are not without
-     *   exception.  For example, silent-"h" words ("honor") are written
-     *   with "an", and "h" words with a pronounced but weakly stressed
-     *   initial "h" are sometimes used with "an" ("an historian").  Also,
-     *   some 'y' words might not follow the generic 'y' rule.
-     *
-     *   'U' words are especially likely not to follow any lexical rule -
-     *   any 'u' word that sounds like it starts with 'y' should use 'a'
-     *   rather than 'an', but there's no good way to figure that out just
-     *   looking at the spelling (consider "a universal symbol" and "an
-     *   unimportant word", or "a unanimous decision" and "an unassuming
-     *   man").  We simply always use 'an' for a word starting with 'u',
-     *   but this will have to be overridden when the 'u' sounds like 'y'.
-     */
-    aNameFrom(str)
-    {
-        /* remember the original source string */
-        local inStr = str;
-
-        /*
-         *   The complete list of unaccented, accented, and ligaturized
-         *   Latin vowels from the Unicode character set.  (The Unicode
-         *   database doesn't classify characters as vowels or the like,
-         *   so it seems the only way we can come up with this list is
-         *   simply to enumerate the vowels.)
-         *
-         *   These are all lower-case letters; all of these are either
-         *   exclusively lower-case or have upper-case equivalents that
-         *   map to these lower-case letters.
-         *
-         *   (Note an implementation detail: the compiler will append all
-         *   of these strings together at compile time, so we don't have
-         *   to perform all of this concatenation work each time we
-         *   execute this method.)
-         *
-         *   Note that we consider any word starting with an '8' to start
-         *   with a vowel, since 'eight' and 'eighty' both take 'an'.
-         */
-        local vowels = '8aeiou\u00E0\u00E1\u00E2\u00E3\u00E4\u00E5\u00E6'
-                       + '\u00E8\u00E9\u00EA\u00EB\u00EC\u00ED\u00EE\u00EF'
-                       + '\u00F2\u00F3\u00F4\u00F5\u00F6\u00F8\u00F9\u00FA'
-                       + '\u00FB\u00FC\u0101\u0103\u0105\u0113\u0115\u0117'
-                       + '\u0119\u011B\u0129\u012B\u012D\u012F\u014D\u014F'
-                       + '\u0151\u0169\u016B\u016D\u016F\u0171\u0173\u01A1'
-                       + '\u01A3\u01B0\u01CE\u01D0\u01D2\u01D4\u01D6\u01D8'
-                       + '\u01DA\u01DC\u01DF\u01E1\u01E3\u01EB\u01ED\u01FB'
-                       + '\u01FD\u01FF\u0201\u0203\u0205\u0207\u0209\u020B'
-                       + '\u020D\u020F\u0215\u0217\u0254\u025B\u0268\u0289'
-                       + '\u1E01\u1E15\u1E17\u1E19\u1E1B\u1E1D\u1E2D\u1E2F'
-                       + '\u1E4D\u1E4F\u1E51\u1E53\u1E73\u1E75\u1E77\u1E79'
-                       + '\u1E7B\u1E9A\u1EA1\u1EA3\u1EA5\u1EA7\u1EA9\u1EAB'
-                       + '\u1EAD\u1EAF\u1EB1\u1EB3\u1EB5\u1EB7\u1EB9\u1EBB'
-                       + '\u1EBD\u1EBF\u1EC1\u1EC3\u1EC5\u1EC7\u1EC9\u1ECB'
-                       + '\u1ECD\u1ECF\u1ED1\u1ED3\u1ED5\u1ED7\u1ED9\u1EDB'
-                       + '\u1EDD\u1EDF\u1EE1\u1EE3\u1EE5\u1EE7\u1EE9\u1EEB'
-                       + '\u1EED\u1EEF\u1EF1\uFF41\uFF4F\uFF55';
-
-        /*
-         *   A few upper-case vowels in unicode don't have lower-case
-         *   mappings - consider them separately.
-         */
-        local vowelsUpperOnly = '\u0130\u019f';
-
-        /*
-         *   the various accented forms of the letter 'y' - these are all
-         *   lower-case versions; the upper-case versions all map to these
-         */
-        local ys = 'y\u00FD\u00FF\u0177\u01B4\u1E8F\u1E99\u1EF3'
-                   + '\u1EF5\u1EF7\u1EF9\u24B4\uFF59';
-
-        /* if the name is already qualified, don't add an article at all */
-        if (isQualifiedName)
-            return str;
-
-        /* if it's plural or a mass noun, use "some" as the article */
-        if (isPlural || isMassNoun)
-        {
-            /* use "some" as the article */
-            return 'some ' + str;
-        }
-        else
-        {
-            local firstChar;
-            local firstCharLower;
-
-            /* if it's empty, just use "a" */
-            if (inStr == '')
-                return 'a';
-
-            /* get the first character of the name */
-            firstChar = inStr.substr(1, 1);
-
-            /* skip any leading HTML tags */
-            if (rexMatch(patTagOrQuoteChar, firstChar) != nil)
-            {
-                /*
-                 *   Scan for tags.  Note that this pattern isn't quite
-                 *   perfect, as it won't properly ignore close-brackets
-                 *   that are inside quoted material, but it should be good
-                 *   enough for nearly all cases in practice.  In cases too
-                 *   complex for this pattern, the object will simply have
-                 *   to override aDesc.
-                 */
-                local len = rexMatch(patLeadingTagOrQuote, inStr);
-
-                /* if we got a match, strip out the leading tags */
-                if (len != nil)
-                {
-                    /* strip off the leading tags */
-                    inStr = inStr.substr(len + 1);
-
-                    /* re-fetch the first character */
-                    firstChar = inStr.substr(1, 1);
-                }
-            }
-
-            /* get the lower-case version of the first character */
-            firstCharLower = firstChar.toLower();
-
-            /*
-             *   if the first word of the name is only one letter long,
-             *   treat it specially
-             */
-            if (rexMatch(patOneLetterWord, inStr) != nil)
-            {
-                /*
-                 *   We have a one-letter first word, such as "I-beam" or
-                 *   "M-ray sensor", or just "A".  Choose the article based
-                 *   on the pronunciation of the letter as a letter.
-                 */
-                return (rexMatch(patOneLetterAnWord, inStr) != nil
-                        ? 'an ' : 'a ') + str;
-            }
-
-            /*
-             *   look for the first character in the lower-case and
-             *   upper-case-only vowel lists - if we find it, it takes
-             *   'an'
-             */
-            if (vowels.find(firstCharLower) != nil
-                || vowelsUpperOnly.find(firstChar) != nil)
-            {
-                /* it starts with a vowel */
-                return 'an ' + str;
-            }
-            else if (ys.find(firstCharLower) != nil)
-            {
-                local secondChar;
-
-                /* get the second character, if there is one */
-                secondChar = inStr.substr(2, 1);
-
-                /*
-                 *   It starts with 'y' - if the second letter is a
-                 *   consonant, assume the 'y' is a vowel sound, hence we
-                 *   should use 'an'; otherwise assume the 'y' is a
-                 *   diphthong 'ei' sound, which means we should use 'a'.
-                 *   If there's no second character at all, or the second
-                 *   character isn't alphabetic, use 'a' - "a Y" or "a
-                 *   Y-connector".
-                 */
-                if (secondChar == ''
-                    || rexMatch(patIsAlpha, secondChar) == nil
-                    || vowels.find(secondChar.toLower()) != nil
-                    || vowelsUpperOnly.find(secondChar) != nil)
-                {
-                    /*
-                     *   it's just one character, or the second character
-                     *   is non-alphabetic, or the second character is a
-                     *   vowel - in any of these cases, use 'a'
-                     */
-                    return 'a ' + str;
-                }
-                else
-                {
-                    /* the second character is a consonant - use 'an' */
-                    return 'an ' + str;
-                }
-            }
-            else if (rexMatch(patElevenEighteen, inStr) != nil)
-            {
-                /*
-                 *   it starts with '11' or '18', so it takes 'an' ('an
-                 *   11th-hour appeal', 'an 18-hole golf course')
-                 */
-                return 'an ' + str;
-            }
-            else
-            {
-                /* it starts with a consonant */
-                return 'a ' + str;
-            }
-        }
-    }
-
-    /* pre-compile some regular expressions for aName */
-    patTagOrQuoteChar = static new RexPattern('[<"\']')
-    patLeadingTagOrQuote = static new RexPattern(
-        '(<langle><^rangle>+<rangle>|"|\')+')
-    patOneLetterWord = static new RexPattern('<alpha>(<^alpha>|$)')
-    patOneLetterAnWord = static new RexPattern('<nocase>[aefhilmnorsx]')
-    patIsAlpha = static new RexPattern('<alpha>')
-    patElevenEighteen = static new RexPattern('1[18](<^digit>|$)')
-
-    /*
      *   Get the default plural name.  By default, we'll use the
      *   algorithmic plural determination, which is based on the spelling
      *   of the name.
      *
      *   The algorithm won't always get it right, since some English
      *   plurals are irregular ("men", "children", "Attorneys General").
      *   When the name doesn't fit the regular spelling patterns for
      *   plurals, the object should simply override this routine to return
      *   the correct plural name string.
-     */
-    pluralName = (pluralNameFrom(name))
-
-    /*
-     *   Get the plural form of the given name string.  If the name ends in
-     *   anything other than 'y', we'll add an 's'; otherwise we'll replace
-     *   the 'y' with 'ies'.  We also handle abbreviations and individual
-     *   letters specially.
-     *
-     *   This can only deal with simple adjective-noun forms.  For more
-     *   complicated forms, particularly for compound words, it must be
-     *   overridden (e.g., "Attorney General" -> "Attorneys General",
-     *   "man-of-war" -> "men-of-war").  Likewise, names with irregular
-     *   plurals ('child' -> 'children', 'man' -> 'men') must be handled
-     *   with overrides.
-     */
-    pluralNameFrom(str)
-    {
-        local len;
-        local lastChar;
-        local lastPair;
-
-        /*
-         *   if it's marked as having plural usage, just use the ordinary
-         *   name, since it's already plural
-         */
-        if (isPlural)
-            return str;
-
-        /* check for a 'phrase of phrase' format */
-        if (rexMatch(patOfPhrase, str) != nil)
-        {
-            local ofSuffix;
-
-            /*
-             *   Pull out the two parts - the part up to the 'of' is the
-             *   part we'll actually pluralize, and the rest is a suffix
-             *   we'll stick on the end of the pluralized part.
-             */
-            str = rexGroup(1)[3];
-            ofSuffix = rexGroup(2)[3];
-
-            /*
-             *   now pluralize the part up to the 'of' using the normal
-             *   rules, then add the rest back in at the end
-             */
-            return pluralNameFrom(str) + ofSuffix;
-        }
-
-        /* if there's no short description, return an empty string */
-        len = str.length();
-        if (len == 0)
-            return '';
-
-        /*
-         *   If it's only one character long, handle it specially.  If it's
-         *   a lower-case letter, add an apostrophe-S.  If it's a capital
-         *   A, E, I, M, U, or V, we'll add apostrophe-S (because these
-         *   could be confused with words or common abbreviations if we
-         *   just added "s": As, Es, Is, Ms, Us, Vs).  If it's anything
-         *   else (any other capital letter, or any non-letter character),
-         *   we'll just add an "s".
-         */
-        if (len == 1)
-        {
-            if (rexMatch(patSingleApostropheS, str) != nil)
-                return str + '&rsquo;s';
-            else
-                return str + 's';
-        }
-
-        /* get the last character of the name, and the last pair of chars */
-        lastChar = str.substr(len, 1);
-        lastPair = (len == 1 ? lastChar : str.substr(len - 1, 2));
-
-        /*
-         *   If the last letter is a capital letter, assume it's an
-         *   abbreviation without embedded periods (CPA, PC), in which case
-         *   we just add an "s" (CPAs, PCs).  Likewise, if it's a number,
-         *   just add "s": "the 1940s", "the low 20s".
-         */
-        if (rexMatch(patUpperOrDigit, lastChar) != nil)
-            return str + 's';
-
-        /*
-         *   If the last character is a period, it must be an abbreviation
-         *   with embedded periods (B.A., B.S., Ph.D.).  In these cases,
-         *   add an apostrophe-S.
-         */
-        if (lastChar == '.')
-            return str + '&rsquo;s';
-
-        /*
-         *   If it ends in a non-vowel followed by 'y', change -y to -ies.
-         *   (This doesn't apply if a vowel precedes a terminal 'y'; in
-         *   such cases, we'll use the normal '-s' ending instead: "survey"
-         *   -> "surveys", "essay" -> "essays", "day" -> "days".)
-         */
-        if (rexMatch(patVowelY, lastPair) != nil)
-            return str.substr(1, len - 1) + 'ies';
-
-        /* if it ends in s, x, z, or h, add -es */
-        if ('sxzh'.find(lastChar) != nil)
-            return str + 'es';
-
-        /* for anything else, just add -s */
-        return str + 's';
-    }
-
-    /* some pre-compiled patterns for pluralName */
-    patSingleApostropheS = static new RexPattern('<case><lower|A|E|I|M|U|V>')
-    patUpperOrDigit = static new RexPattern('<upper|digit>')
-    patVowelY = static new RexPattern('[^aeoiu]y')
-    patOfPhrase = static new RexPattern(
-        '<nocase>(.+?)(<space>+of<space>+.+)')
-
-    /* get my name plus a being verb ("the box is") */
-    nameIs { return theName + ' ' + verbToBe; }
-
-    /* get my name plus a negative being verb ("the box isn't") */
-    nameIsnt { return nameIs + 'n&rsquo;t'; }
-
-    /*
-     *   My name with the given regular verb in agreement: in the present
-     *   tense, if my name has singular usage, we'll add 's' to the verb,
-     *   otherwise we won't.  In the past tense, we'll add 'd' (or 'ed').
-     *   This can't be used with irregular verbs, or with regular verbs
-     *   that have the last consonant repeated before the past -ed ending,
-     *   such as "deter".
-     */
-    nameVerb(verb) { return theName + ' ' + conjugateRegularVerb(verb); }
-
-    /* being verb agreeing with this object as subject */
-    verbToBe
-    {
-        return tSel(isPlural ? 'are' : 'is', isPlural ? 'were' : 'was');
-    }
-
-    /* past tense being verb agreeing with object as subject */
-    verbWas { return tSel(isPlural ? 'were' : 'was', 'had been'); }
-
-    /* 'have' verb agreeing with this object as subject */
-    verbToHave { return tSel(isPlural ? 'have' : 'has', 'had'); }
-
-    /*
-     *   A few common irregular verbs and name-plus-verb constructs,
-     *   defined for convenience.
-     */
-    verbToDo = (tSel('do' + verbEndingEs, 'did'))
-    nameDoes = (theName + ' ' + verbToDo)
-    verbToGo = (tSel('go' + verbEndingEs, 'went'))
-    verbToCome = (tSel('come' + verbEndingS, 'came'))
-    verbToLeave = (tSel('leave' + verbEndingS, 'left'))
-    verbToSee = (tSel('see' + verbEndingS, 'saw'))
-    nameSees = (theName + ' ' + verbToSee)
-    verbToSay = (tSel('say' + verbEndingS, 'said'))
-    nameSays = (theName + ' ' + verbToSay)
-    verbMust = (tSel('must', 'had to'))
-    verbCan = (tSel('can', 'could'))
-    verbCannot = (tSel('cannot', 'could not'))
-    verbCant = (tSel('can&rsquo;t', 'couldn&rsquo;t'))
-    verbWill = (tSel('will', 'would'))
-    verbWont = (tSel('won&rsquo;t', 'wouldn&rsquo;t'))
-
-    /*
-     *   Verb endings for regular '-s' verbs, agreeing with this object as
-     *   the subject.  We define several methods each of which handles the
-     *   past tense differently.
-     *
-     *   verbEndingS doesn't try to handle the past tense at all - use it
-     *   only in places where you know for certain that you'll never need
-     *   the past tense form, or in expressions constructed with the tSel
-     *   macro: use verbEndingS as the macro's first argument, and specify
-     *   the past tense ending explicitly as the second argument.  For
-     *   example, you could generate the correctly conjugated form of the
-     *   verb "to fit" for an object named "key" with an expression such
-     *   as:
      *
-     *   'fit' + tSel(key.verbEndingS, 'ted')
-     *
-     *   This would generate 'fit', 'fits', or 'fitted' according to number
-     *   and tense.
-     *
-     *   verbEndingSD and verbEndingSEd return 'd' and 'ed' respectively in
-     *   the past tense.
-     *
-     *   verbEndingSMessageBuilder_ is for internal use only: it assumes
-     *   that the correct ending to be displayed in the past tense is
-     *   stored in langMessageBuilder.pastEnding_.  It is used as part of
-     *   the string parameter substitution mechanism.
+     *   V češtině se množné číslo nedá nagenerovat automaticky, takže
+     *   použijeme jednotné a autoři si musí správný tvar explicitně
+     *   zadat, pokud se ve hře vyskytuje objekt vícekrát. Viz též
+     *   pluralDisambigName.
+     *
+     *   Také k pluralu přibývá paucal, tj. tvar pro počet 2-4. Tenhle
+     *   název asi není moc jednoznačný a v češtině používaný, ale lepší
+     *   pojmenování jevu jsem nenačel.
      */
-    verbEndingS { return isPlural ? '' : 's'; }
-    verbEndingSD = (tSel(verbEndingS, 'd'))
-    verbEndingSEd = (tSel(verbEndingS, 'ed'))
-    verbEndingSMessageBuilder_ =
-        (tSel(verbEndingS, langMessageBuilder.pastEnding_))
-
-    /*
-     *   Verb endings (present or past) for regular '-es/-ed' and
-     *   '-y/-ies/-ied' verbs, agreeing with this object as the subject.
-     */
-    verbEndingEs { return tSel(isPlural ? '' : 'es', 'ed'); }
-    verbEndingIes { return tSel(isPlural ? 'y' : 'ies', 'ied'); }
+    paucalName = (name)
+    pluralName = (name)
 
     /*
      *   Dummy name - this simply displays nothing; it's used for cases
      *   where messageBuilder substitutions want to refer to an object (for
      *   internal bookkeeping) without actually showing the name of the
      *   object in the output text.  This should always simply return an
      *   empty string.
      */
     dummyName = ''
 
     /*
      *   Invoke a property (with an optional argument list) on this object
      *   while temporarily switching to the present tense, and return the
      *   result.
      */
     propWithPresent(prop, [args])
     {
         return withPresent({: self.(prop)(args...)});
     }
 
     /*
      *   Method for internal use only: invoke on this object the property
      *   stored in langMessageBuilder.fixedTenseProp_ while temporarily
      *   switching to the present tense, and return the result.  This is
      *   used as part of the string parameter substitution mechanism.
      */
     propWithPresentMessageBuilder_
     {
         return propWithPresent(langMessageBuilder.fixedTenseProp_);
     }
 
     /*
      *   For the most part, "strike" has the same meaning as "hit", so
      *   define this as a synonym for "attack" most objects.  There are a
      *   few English idioms where "strike" means something different, as
      *   in "strike match" or "strike tent."
      */
     dobjFor(Strike) asDobjFor(Attack)
+
+    showListItemGen(options, pov, infoTab, stateNameProp)
+    {
+        local info;
+        local st;
+        local stName;
+
+        /* get my visual information from the point of view */
+        info = infoTab[self];
+
+        /* show the item's list name */
+        /*
+         *   Zde si vybereme správný pád k zobrazení položky seznamu. Dostaneme
+         *   ho prostřednictvím vlajky z Listeru.
+         */
+        if(options & ListKdoCo) say(withVisualSenseInfo(pov, info, &listName));
+        else if(options & ListKomuCemu) say(withVisualSenseInfo(pov, info, &listNameKomuCemu));
+        else if(options & ListKymCim) say(withVisualSenseInfo(pov, info, &listNameKymCim));
+        else say(withVisualSenseInfo(pov, info, &listNameKohoCo));
+
+        /* 
+         *   If we have a list state with a name, show it.  Note that to
+         *   obtain the state name, we have to pass a list of the objects
+         *   being listed to the stateNameProp method of the state object;
+         *   we're the only object we're showing for this particular
+         *   display list element, so we simply pass a single-element list
+         *   containing 'self'.  
+         */
+        if ((st = getStateWithInfo(info, pov)) != nil
+            && (stName = st.(stateNameProp)([self])) != nil)
+        {
+            /* we have a state with a name - show it */
+            gLibMessages.showListState(stName);
+        }
+    }
+
+
+;
+
+modify ThingState
+    inventoryNameKohoCo(lst) { return listNameKohoCo(lst); }
 ;
 
 /* ------------------------------------------------------------------------ */
 /*
  *   An object that uses the same name as another object.  This maps all of
  *   the properties involved in supplying the object's name, number, and
  *   other usage information from this object to a given target object, so
  *   that all messages involving this object use the same name as the
  *   target object.  This is a mix-in class that can be used with any other
  *   class.
  *   
  *   Note that we map only the *reported* name for the object.  We do NOT
  *   give this object any vocabulary from the other object; in other words,
  *   we don't enter this object into the dictionary with the other object's
  *   vocabulary words.  
  */
 class NameAsOther: object
     /* the target object - we'll use the same name as this object */
     targetObj = nil
 
     /* map our naming and usage properties to the target object */
     isPlural = (targetObj.isPlural)
     isMassNoun = (targetObj.isMassNoun)
-    isHim = (targetObj.isHim)
-    isHer = (targetObj.isHer)
-    isIt = (targetObj.isIt)
-    isProperName = (targetObj.isProperName)
-    isQualifiedName = (targetObj.isQualifiedName)
+    gender = (targetObj.gender)
     name = (targetObj.name)
+    nameKohoCeho = (targetObj.nameKohoCeho)
+    nameKomuCemu = (targetObj.nameKomuCemu)
+    nameKohoCo = (targetObj.nameKohoCo)
+    nameKomCem = (targetObj.nameKomCem)
+    nameKymCim = (targetObj.nameKymCim)
 
     /* map the derived name properties as well, in case any are overridden */
     disambigName = (targetObj.disambigName)
-    theDisambigName = (targetObj.theDisambigName)
-    aDisambigName = (targetObj.aDisambigName)
     countDisambigName(cnt) { return targetObj.countDisambigName(cnt); }
     disambigEquivName = (targetObj.disambigEquivName)
     listName = (targetObj.listName)
+    listNameKomuCemu = (targetObj.listNameKomuCemu)
+    listNameKohoCo = (targetObj.listNameKohoCo)
+    listNameKymCim = (targetObj.listNameKymCim)
     countName(cnt) { return targetObj.countName(cnt); }
 
     /* map the pronoun properites, in case any are overridden */
-    itNom = (targetObj.itNom)
-    itObj = (targetObj.itObj)
-    itPossAdj = (targetObj.itPossAdj)
-    itPossNoun = (targetObj.itPossNoun)
-    itReflexive = (targetObj.itReflexive)
-    thatNom = (targetObj.thatNom)
-    thatObj = (targetObj.thatObj)
-    thatIsContraction = (targetObj.thatIsContraction)
-    itIs = (targetObj.itIs)
-    itIsContraction = (targetObj.itIsContraction)
-    itVerb(verb) { return targetObj.itVerb(verb); }
-    conjugateRegularVerb(verb)
-        { return targetObj.conjugateRegularVerb(verb); }
-    theName = (targetObj.theName)
-    theNameObj = (targetObj.theNameObj)
-    theNamePossAdj = (targetObj.theNamePossAdj)
-    theNamePossNoun = (targetObj.theNamePossNoun)
-    theNameWithOwner = (targetObj.theNameWithOwner)
-    aNameOwnerLoc(ownerPri)
-        { return targetObj.aNameOwnerLoc(ownerPri); }
-    theNameOwnerLoc(ownerPri)
-        { return targetObj.theNameOwnerLoc(ownerPri); }
+    zajmenoSam = (targetObj.zajmenoSam)
+    zajmenoTy = (targetObj.zajmenoTy) // TODO: Přidat ostatní zájmena
+
+    nameWithOwner = (targetObj.nameWithOwner)
+    nameOwnerLoc(ownerPri)
+        { return targetObj.nameOwnerLoc(ownerPri); }
     countNameOwnerLoc(cnt, ownerPri)
         { return targetObj.countNameOwnerLoc(cnt, ownerPri); }
     notePromptByOwnerLoc(ownerPri)
         { targetObj.notePromptByOwnerLoc(ownerPri); }
     notePromptByPossAdj()
         { targetObj.notePromptByPossAdj(); }
-    aName = (targetObj.aName)
-    aNameObj = (targetObj.aNameObj)
     pluralName = (targetObj.pluralName)
-    nameIs = (targetObj.nameIs)
-    nameIsnt = (targetObj.nameIsnt)
-    nameVerb(verb) { return targetObj.nameVerb(verb); }
-    verbToBe = (targetObj.verbToBe)
-    verbWas = (targetObj.verbWas)
-    verbToHave = (targetObj.verbToHave)
-    verbToDo = (targetObj.verbToDo)
-    nameDoes = (targetObj.nameDoes)
-    verbToGo = (targetObj.verbToGo)
-    verbToCome = (targetObj.verbToCome)
-    verbToLeave = (targetObj.verbToLeave)
-    verbToSee = (targetObj.verbToSee)
-    nameSees = (targetObj.nameSees)
-    verbToSay = (targetObj.verbToSay)
-    nameSays = (targetObj.nameSays)
-    verbMust = (targetObj.verbMust)
-    verbCan = (targetObj.verbCan)
-    verbCannot = (targetObj.verbCannot)
-    verbCant = (targetObj.verbCant)
-    verbWill = (targetObj.verbWill)
-    verbWont = (targetObj.verbWont)
-
-    verbEndingS = (targetObj.verbEndingS)
-    verbEndingSD = (targetObj.verbEndingSD)
-    verbEndingSEd = (targetObj.verbEndingSEd)
-    verbEndingEs = (targetObj.verbEndingEs)
-    verbEndingIes = (targetObj.verbEndingIes)
+    slovesoJe = (targetObj.slovesoJe)
 ;
 
 /*
  *   Name as Parent - this is a special case of NameAsOther that uses the
  *   lexical parent of a nested object as the target object.  (The lexical
  *   parent is the enclosing object in a nested object definition; in other
  *   words, it's the object in which the nested object is embedded.)  
  */
 class NameAsParent: NameAsOther
     targetObj = (lexicalParent)
 ;
 
 /*
  *   ChildNameAsOther is a mix-in class that can be used with NameAsOther
  *   to add the various childInXxx naming to the mapped properties.  The
  *   childInXxx names are the names generated when another object is
  *   described as located within this object; by mapping these properties
  *   to our target object, we ensure that we use exactly the same phrasing
  *   as we would if the contained object were actually contained by our
  *   target rather than by us.
  *   
  *   Note that this should always be used in combination with NameAsOther:
  *   
  *   myObj: NameAsOther, ChildNameAsOther, Thing ...
  *   
  *   You can also use it the same way in combination with a subclass of
  *   NameAsOther, such as NameAsParent.  
  */
 class ChildNameAsOther: object
     objInPrep = (targetObj.objInPrep)
-    actorInPrep = (targetObj.actorInPrep)
-    actorOutOfPrep = (targetObj.actorOutOfPrep)
-    actorIntoPrep = (targetObj.actorIntoPrep)
+    objInPad = (targetObj.objInPad)
+    objOutOfPrep = (targetObj.objOutOfPrep)
+    objIntoPrep = (targetObj.objIntoPrep)
+    objIntoPad = (targetObj.objIntoPad)
     childInName(childName) { return targetObj.childInName(childName); }
     childInNameWithOwner(childName)
         { return targetObj.childInNameWithOwner(childName); }
     childInNameGen(childName, myName)
         { return targetObj.childInNameGen(childName, myName); }
-    actorInName = (targetObj.actorInName)
-    actorOutOfName = (targetObj.actorOutOfName)
-    actorIntoName = (targetObj.actorIntoName)
-    actorInAName = (targetObj.actorInAName)
+    objInName = (targetObj.objInName)
+    objOutOfName = (targetObj.objOutOfName)
+    objIntoName = (targetObj.objIntoName)
 ;
 
 
 /* ------------------------------------------------------------------------ */
 /*
  *   Language modifications for the specialized container types
  */
 modify Surface
     /*
      *   objects contained in a Surface are described as being on the
      *   Surface
      */
-    objInPrep = 'on'
-    actorInPrep = 'on'
-    actorOutOfPrep = 'off of'
+    objInPrep = 'na'
+    objOutOfPrep = 'z'
 ;
 
 modify Underside
-    objInPrep = 'under'
-    actorInPrep = 'under'
-    actorOutOfPrep = 'from under'
+    objInPrep = 'pod'
+    objInPad = 7
+    objOutOfPrep = 'z pod'
 ;
 
 modify RearContainer
-    objInPrep = 'behind'
-    actorInPrep = 'behind'
-    actorOutOfPrep = 'from behind'
+    objInPrep = 'za'
+    objInPad = 7
+    objOutOfPrep = 'z poza'
 ;
 
 /* ------------------------------------------------------------------------ */
 /*
  *   Language modifications for Actor.
  *   
  *   An Actor has a "referral person" setting, which determines how we
  *   refer to the actor; this is almost exclusively for the use of the
  *   player character.  The typical convention is that we refer to the
  *   player character in the second person, but a game can override this on
  *   an actor-by-actor basis.  
  */
 modify Actor
     /* by default, use my pronoun for my name */
-    name = (itNom)
+    /*
+     *   Tyhle výchozí jména se typicky vztahují jen k postavě hráče. Z nich
+     *   jsou pak nagenerovány věty "Nedovolíš Sally ho mít." vs. "Nedovolí
+     *   *ti* ho mít" ze šablony "Nedovol{[íš holder]|il[a holder]
+     *   [jsi holder]} {komučemu} {ho/ji obj} mít. "
+     */
+    name = (zajmenoTy)
+    nameKomuCemu = (zajmenoTiJ)
+    nameKohoCo = (zajmenoTe4J)
+    nameKymCim = (zajmenoTebouJ)
 
     /*
      *   Pronoun selector.  This returns an index for selecting pronouns
      *   or other words based on number and gender, taking into account
      *   person, number, and gender.  The value returned is the sum of the
      *   following components:
      *
      *   number/gender:
      *.  - singular neuter = 1
      *.  - singular masculine = 2
      *.  - singular feminine = 3
      *.  - plural = 4
      *
      *   person:
      *.  - first person = 0
      *.  - second person = 4
      *.  - third person = 8
      *
      *   The result can be used as a list selector as follows (1=first
      *   person, etc; s=singular, p=plural; n=neuter, m=masculine,
      *   f=feminine):
      *
      *   [1/s/n, 1/s/m, 1/s/f, 1/p, 2/s/n, 2/s/m, 2/s/f, 2/p,
      *.  3/s/n, 3/s/m, 3/s/f, 3/p]
+     *
+     *   Přeházíme na logičtější mužský = 1, ženský = 2, střední = 3, plurál = 4
      */
     pronounSelector
     {
-        return ((referralPerson - FirstPerson)*4
-                + (isPlural ? 4 : isHim ? 2 : isHer ? 3 : 1));
+        return ((referralPerson - FirstPerson) * 4
+                + (isPlural ? 4 : gender == 3 ? 2 : gender == 4 ? 3 : 1));
     }
 
     /*
-     *   get the verb form selector index for the person and number:
+     *   Osobní zájmena:
      *
-     *   [1/s, 2/s, 3/s, 1/p, 2/p, 3/p]
+     *   1. pád - zajmenoTy
+     *   2. pád - zajmenoTebe2J/N, zajmenoTe2J/N
+     *   3. pád - zajmenoTobe3J/N, zajmenoTiJ/N
+     *   4. pád - zajmenoTebe4J/N, zajmenoTe4J/N
+     *   6. pád - zajmenoTobe6
+     *   7. pád - zajmenoTebouJ/N
      */
-    conjugationSelector
+    zajmenoTy
     {
-        return (referralPerson + (isPlural ? 3 : 0));
+        return isPlural && referralPerson == ThirdPerson && gender == 3 ? 'ony'
+            : isPlural && referralPerson == ThirdPerson && gender == 4 ? 'ona'
+            : ['já', 'já', 'já', 'my',
+               'ty', 'ty', 'ty', 'vy',
+               'on', 'ona', 'ono', 'oni'][pronounSelector];
     }
-
-    /*
-     *   get an appropriate pronoun for the object in the appropriate
-     *   person for the nominative case, objective case, possessive
-     *   adjective, possessive noun, and objective reflexive
-     */
-    itNom
+    zajmenoTebe2J
     {
-        return ['I', 'I', 'I', 'we',
-               'you', 'you', 'you', 'you',
-               'it', 'he', 'she', 'they'][pronounSelector];
+        return ['mne', 'mne', 'mne', 'nás',
+                'tebe', 'tebe', 'tebe', 'vás',
+                'jeho', 'jí', 'jeho', 'jich'][pronounSelector];
     }
-    itObj
+    zajmenoTebe2N
     {
-        return ['me', 'me', 'me', 'us',
-               'you', 'you', 'you', 'you',
-               'it', 'him', 'her', 'them'][pronounSelector];
+        return ['mne', 'mne', 'mne', 'nás',
+                'tebe', 'tebe', 'tebe', 'vás',
+                'něho', 'ní', 'něho', 'nich'][pronounSelector];
     }
-    itPossAdj
+    zajmenoTe2J
     {
-        return ['my', 'my', 'my', 'our',
-               'your', 'your', 'your', 'your',
-               'its', 'his', 'her', 'their'][pronounSelector];
+        return ['mě', 'mě', 'mě', 'nás',
+                'tě', 'tě', 'tě', 'vás',
+                'ho', 'jí', 'ho', 'jich'][pronounSelector];
     }
-    itPossNoun
+    zajmenoTe2N
     {
-        return ['mine', 'mine', 'mine', 'ours',
-               'yours', 'yours', 'yours', 'yours',
-               'its', 'his', 'hers', 'theirs'][pronounSelector];
+        return ['mě', 'mě', 'mě', 'nás',
+                'tě', 'tě', 'tě', 'vás',
+                'ho', 'ní', 'ho', 'nich'][pronounSelector];
     }
-    itReflexive
+    zajmenoTobe3J
     {
-        return ['myself', 'myself', 'myself', 'ourselves',
-               'yourself', 'yourself', 'yourself', 'yourselves',
-               'itself', 'himself', 'herself', 'themselves'][pronounSelector];
+        return ['mně', 'mně', 'mně', 'nám',
+                'tobě', 'tobě', 'tobě', 'vám',
+                'jemu', 'jí', 'jemu', 'jim'][pronounSelector];
     }
-
-    /*
-     *   Demonstrative pronoun, nominative case.  We'll use personal a
-     *   personal pronoun if we have a gender or we're in the first or
-     *   second person, otherwise we'll use 'that' or 'those' as we would
-     *   for an inanimate object.
-     */
-    thatNom
+    zajmenoTobe3N
     {
-        return ['I', 'I', 'I', 'we',
-               'you', 'you', 'you', 'you',
-               'that', 'he', 'she', 'those'][pronounSelector];
+        return ['mně', 'mně', 'mně', 'nám',
+                'tobě', 'tobě', 'tobě', 'vám',
+                'němu', 'ní', 'němu', 'nim'][pronounSelector];
     }
-
-    /* demonstrative pronoun, objective case */
-    thatObj
+    zajmenoTiJ
     {
-        return ['me', 'me', 'me', 'us',
-               'you', 'you', 'you', 'you',
-               'that', 'him', 'her', 'those'][pronounSelector];
+        return ['mi', 'mi', 'mi', 'nám',
+                'ti', 'ti', 'ti', 'vám',
+                'mu', 'jí', 'mu', 'jim'][pronounSelector];
     }
-
-    /* demonstrative pronoun, nominative case with 'is' contraction */
-    thatIsContraction
+    zajmenoTiN
     {
-        return thatNom
-            + tSel(['&rsquo;m', '&rsquo;re', '&rsquo;s',
-                    '&rsquo;re', '&rsquo;re', ' are'][conjugationSelector],
-                   ' ' + verbToBe);
+        return ['mi', 'mi', 'mi', 'nám',
+                'ti', 'ti', 'ti', 'vám',
+                'mu', 'ní', 'mu', 'nim'][pronounSelector];
     }
-
-    /*
-     *   We don't need to override itIs: the base class handling works for
-     *   actors too.
-     */
-
-    /* get my pronoun with a being verb contraction ("the box's") */
-    itIsContraction
+    zajmenoTebe4J
     {
-        return itNom + tSel(
-            '&rsquo;'
-            + ['m', 're', 's', 're', 're', 're'][conjugationSelector],
-            ' ' + verbToBe);
+        return ['mne', 'mne', 'mne', 'nás',
+                'tebe', 'tebe', 'tebe', 'vás',
+                'jeho', 'ji', 'jej', 'je'][pronounSelector];
+    }
+    zajmenoTebe4N
+    {
+        return ['mne', 'mne', 'mne', 'nás',
+                'tebe', 'tebe', 'tebe', 'vás',
+                'něho', 'ni', 'něj', 'ně'][pronounSelector];
+    }
+    zajmenoTe4J
+    {
+        return ['mě', 'mě', 'mě', 'nás',
+                'tě', 'tě', 'tě', 'vás',
+                'ho', 'ji', 'ho', 'je'][pronounSelector];
+    }
+    zajmenoTe4N
+    {
+        return ['mě', 'mě', 'mě', 'nás',
+                'tě', 'tě', 'tě', 'vás',
+                'ho', 'ni', 'ho', 'ně'][pronounSelector];
+    }
+    zajmenoTobe6
+    {
+        return ['mně', 'mně', 'mně', 'nás',
+                'tobě', 'tobě', 'tobě', 'vás',
+                'něm', 'ní', 'něm', 'nich'][pronounSelector];
+    }
+    zajmenoTebouJ
+    {
+        return ['mnou', 'mnou', 'mnou', 'námi',
+                'tebou', 'tebou', 'tebou', 'vámi',
+                'jím', 'jí', 'jím', 'jimi'][pronounSelector];
+    }
+    zajmenoTebouN
+    {
+        return ['mnou', 'mnou', 'mnou', 'námi',
+                'tebou', 'tebou', 'tebou', 'vámi',
+                'ním', 'ní', 'ním', 'nimi'][pronounSelector];
     }
 
     /*
-     *   Conjugate a regular verb in the present or past tense for our
-     *   person and number.
-     *
-     *   In the present tense, this is pretty easy: we add an 's' for the
-     *   third person singular, and leave the verb unchanged for every
-     *   other case.  The only complication is that we must check some
-     *   special cases to add the -s suffix: -y -> -ies, -o -> -oes.
+     *   Přivlastňovací zájmena
      *
-     *   In the past tense, we use the inherited handling since the past
-     *   tense ending doesn't vary with person.
+     *   1. pád - zajmenoTvuj (m), zajmenoTvoje (ž, s), TODO: tvá (ž), tvé (s)
+     *   4. pád - zajmenoTvoji (ž)
      */
-    conjugateRegularVerb(verb)
+    zajmenoTvuj
     {
-        /*
-         *   If we're in the third person or if we use the past tense,
-         *   inherit the default handling; otherwise, use the base verb
-         *   form regardless of number (regular verbs use the same
-         *   conjugated forms for every case but third person singular: I
-         *   ask, you ask, we ask, they ask).
-         */
-        if (referralPerson != ThirdPerson && !gameMain.usePastTense)
-        {
-            /*
-             *   we're not using the third-person or the past tense, so the
-             *   conjugation is the same as the base verb form
-             */
-            return verb;
-        }
-        else
-        {
-            /*
-             *   we're using the third person or the past tense, so inherit
-             *   the base class handling, which conjugates these forms
-             */
-            return inherited(verb);
-        }
+        return ['můj', 'můj', 'můj', 'náš',
+                'tvůj', 'tvůj', 'tvůj', 'váš',
+                'jeho', 'její', 'jeho', 'jejich'][pronounSelector];
+    }
+    zajmenoTvoje
+    {
+        return ['moje', 'moje', 'moje', 'naše',
+                'tvoje', 'tvoje', 'tvoje', 'vaše',
+                'jeho', 'její', 'jeho', 'jejich'][pronounSelector];
     }
 
-    /*
-     *   Get the name with a definite article ("the box").  If the
-     *   narrator refers to us in the first or second person, use a
-     *   pronoun rather than the short description.
-     */
-    theName
-        { return (referralPerson == ThirdPerson ? inherited : itNom); }
-
-    /* theName in objective case */
-    theNameObj
-        { return (referralPerson == ThirdPerson ? inherited : itObj); }
-
-    /* theName as a possessive adjective */
-    theNamePossAdj
-        { return (referralPerson == ThirdPerson ? inherited : itPossAdj); }
-
-    /* theName as a possessive noun */
-    theNamePossNoun
-    { return (referralPerson == ThirdPerson ? inherited : itPossNoun); }
+    zajmenoTvoji
+    {
+        return ['moji', 'moji', 'moji', 'naši',
+                'tvoji', 'tvoji', 'tvoji', 'vaši',
+                'jeho', 'její', 'jeho', 'jejich'][pronounSelector];
+    }
 
     /*
-     *   Get the name with an indefinite article.  Use the same rules of
-     *   referral person as for definite articles.
+     *   Pravidelná slovesa
+     *
+     *   Mají pět slovesných tříd, podle kterých je ovlivněna koncovka slovesa
+     *   a tak můžeme poskytnout substituční parametr. Přetížíme tyto funkce
+     *   ze třídy Thing, kde jsou všechny jen ve třetí os. pro neživé objekty.
      */
-    aName { return (referralPerson == ThirdPerson ? inherited : itNom); }
-
-    /* aName in objective case */
-    aNameObj { return (referralPerson == ThirdPerson ? inherited : itObj); }
-
-    /* being verb agreeing with this object as subject */
-    verbToBe
+    slovesoEs
     {
-        return tSel(['am', 'are', 'is', 'are', 'are', 'are'],
-                    ['was', 'were', 'was', 'were', 'were', 'were'])
-               [conjugationSelector];
+        return (referralPerson == FirstPerson ? (isPlural ? 'eme' : 'u') : '')
+            + (referralPerson == SecondPerson ? (isPlural ? 'ete' : 'eš') : '')
+            + (referralPerson == ThirdPerson ? (isPlural ? 'ou' : 'e') : '');
     }
-
-    /* past tense being verb agreeing with this object as subject */
-    verbWas
+    slovesoNes
     {
-        return tSel(['was', 'were', 'was', 'were', 'were', 'were']
-                    [conjugationSelector], 'had been');
+        return (referralPerson == FirstPerson ? (isPlural ? 'neme' : 'nu') : '')
+            + (referralPerson == SecondPerson ? (isPlural ? 'nete' : 'neš') : '')
+            + (referralPerson == ThirdPerson ? (isPlural ? 'nou' : 'ne') : '');
     }
-
-    /* 'have' verb agreeing with this object as subject */
-    verbToHave
+    slovesoJes
+    {
+        return (referralPerson == FirstPerson ? (isPlural ? 'jeme' : 'ji') : '')
+            + (referralPerson == SecondPerson ? (isPlural ? 'jete' : 'ješ') : '')
+            + (referralPerson == ThirdPerson ? (isPlural ? 'jí' : 'je') : '');
+    }
+    slovesoIs
     {
-        return tSel(['have', 'have', 'has', 'have', 'have', 'have']
-                    [conjugationSelector], 'had');
+        return (referralPerson == FirstPerson ? (isPlural ? 'íme' : 'ím') : '')
+            + (referralPerson == SecondPerson ? (isPlural ? 'íete' : 'íš') : '')
+            + (referralPerson == ThirdPerson ? (isPlural ? 'í' : 'í') : '');
+    }
+    slovesoAs
+    {
+        return (referralPerson == FirstPerson ? (isPlural ? 'áme' : 'ám') : '')
+            + (referralPerson == SecondPerson ? (isPlural ? 'áte' : 'áš') : '')
+            + (referralPerson == ThirdPerson ? (isPlural ? 'ají' : 'á') : '');
     }
 
     /*
-     *   verb endings for regular '-s' and '-es' verbs, agreeing with this
-     *   object as the subject
+     *   Spojení slovesa být a zvratného zájmena
      */
-    verbEndingS
-    {
-        return ['', '', 's', '', '', ''][conjugationSelector];
-    }
-    verbEndingEs
+    spojeniSis
     {
-        return tSel(['', '', 'es', '', '', ''][conjugationSelector], 'ed');
+        return (referralPerson == FirstPerson ? (isPlural ? 'jsme si' : 'jsem si') : '')
+            + (referralPerson == SecondPerson ? (isPlural ? 'jste si' : 'sis') : '')
+            + (referralPerson == ThirdPerson ? 'si' : '');
     }
-    verbEndingIes
+    spojeniSes
     {
-        return tSel(['y', 'y', 'ies', 'y', 'y', 'y'][conjugationSelector],
-                    'ied');
+        return (referralPerson == FirstPerson ? (isPlural ? 'jsme se' : 'jsem se') : '')
+            + (referralPerson == SecondPerson ? (isPlural ? 'jste se' : 'ses') : '')
+            + (referralPerson == ThirdPerson ? 'se' : '');
     }
 
-    /* "I'm not" doesn't fit the regular "+n't" rule */
-    nameIsnt
+    /* being verb agreeing with this object as subject */
+    slovesoJe
     {
-        return conjugationSelector == 1 && !gameMain.usePastTense
-            ? 'I&rsquo;m not' : inherited;
+        return tSel(['jsem', 'jsi', 'je', 'jsme', 'jste', 'jsou'][referralPerson
+            + (isPlural ? 3 : 0)], ['byl', 'byl', 'byla', 'bylo', 'byli',
+            'byly', 'byly', 'byla'][gender + (isPlural ? 4 : 0)]);
     }
 
     /*
      *   Show my name for an arrival/departure message.  If we've been seen
      *   before by the player character, we'll show our definite name,
      *   otherwise our indefinite name.
+     *
+     *   V češtině nepotřebujeme rozlišovat člen, takže zobrazíme prosté name.
+     *   Úplně zlikvidovat nejde, protože některé třídy, např. vozidlo, vypisují
+     *   své cestující.
      */
     travelerName(arriving)
-        { say(gPlayerChar.hasSeen(self) ? theName : aName); }
+        { say(name); }
 
     /*
      *   Test to see if we can match the third-person pronouns.  We'll
      *   match these if our inherited test says we match them AND we can
      *   be referred to in the third person.
      */
     canMatchHim = (inherited && canMatch3rdPerson)
     canMatchHer = (inherited && canMatch3rdPerson)
     canMatchIt = (inherited && canMatch3rdPerson)
     canMatchThem = (inherited && canMatch3rdPerson)
 
     /*
      *   Test to see if we can match a third-person pronoun ('it', 'him',
      *   'her', 'them').  We can unless we're the player character and the
      *   player character is referred to in the first or second person.
      */
     canMatch3rdPerson = (!isPlayerChar || referralPerson == ThirdPerson)
 
     /*
      *   Set a pronoun antecedent to the given list of ResolveInfo objects.
      *   Pronoun handling is language-specific, so this implementation is
      *   part of the English library, not the generic library.
      *
      *   If only one object is present, we'll set the object to be the
      *   antecedent of 'it', 'him', or 'her', according to the object's
      *   gender.  We'll also set the object as the single antecedent for
      *   'them'.
      *
      *   If we have multiple objects present, we'll set the list to be the
      *   antecedent of 'them', and we'll forget about any antecedent for
      *   'it'.
      *
      *   Note that the input is a list of ResolveInfo objects, so we must
      *   pull out the underlying game objects when setting the antecedents.
+     *
+     *   TODO: Vyzkoušet, jak je to s reagováním na "ho" apod. v případě,
+     *   že tím může být myšlena postava i neživý objekt. Myslím, že když
+     *   jsem zkoušel "zeptej se ho na něco", tak že to směrovalo na neživý
+     *   objekt.
      */
     setPronoun(lst)
     {
         /* if the list is empty, ignore it */
         if (lst == [])
             return;
 
         /*
          *   if we have multiple objects, the entire list is the antecedent
          *   for 'them'; otherwise, it's a singular antecedent which
          *   depends on its gender
          */
         if (lst.length() > 1)
         {
             local objs = lst.mapAll({x: x.obj_});
 
             /* it's 'them' */
             setThem(objs);
 
             /* forget any 'it' */
             setIt(nil);
         }
         else if (lst.length() == 1)
         {
             /*
              *   We have only one object, so set it as an antecedent
              *   according to its gender.
              */
             setPronounObj(lst[1].obj_);
         }
     }
 
     /*
      *   Set a pronoun to refer to multiple potential antecedents.  This is
      *   used when the verb has multiple noun slots - UNLOCK DOOR WITH KEY.
      *   For verbs like this, we have no way of knowing in advance whether
      *   a future pronoun will refer back to the direct object or the
      *   indirect object (etc) - we could just assume that 'it' will refer
      *   to the direct object, but this won't always be what the player
      *   intended.  In natural English, pronoun antecedents must often be
      *   inferred from context at the time of use - so we use the same
      *   approach.
      *
      *   Pass an argument list consisting of ResolveInfo lists - that is,
      *   pass one argument per noun slot in the verb, and make each
      *   argument a list of ResolveInfo objects.  In other words, you call
      *   this just as you would setPronoun(), except you can pass more than
      *   one list argument.
      *
      *   We'll store the multiple objects as antecedents.  When we need to
      *   resolve a future singular pronoun, we'll figure out which of the
      *   multiple antecedents is the most logical choice in the context of
      *   the pronoun's usage.
      */
     setPronounMulti([args])
     {
         local lst, subLst;
         local gotThem;
 
         /*
          *   If there's a plural list, it's 'them'.  Arbitrarily use only
          *   the first plural list if there's more than one.
          */
         if ((lst = args.valWhich({x: x.length() > 1})) != nil)
         {
             /* set 'them' to the plural list */
             setPronoun(lst);
 
             /* note that we had a clear 'them' */
             gotThem = true;
         }
 
         /* from now on, consider only the sublists with exactly one item */
         args = args.subset({x: x.length() == 1});
 
         /* get a list of the singular items from the lists */
         lst = args.mapAll({x: x[1].obj_});
 
         /*
          *   Set 'it' to all of the items that can match 'it'; do likewise
          *   with 'him' and 'her'.  If there are no objects that can match
          *   a given pronoun, leave that pronoun unchanged.  
          */
         if ((subLst = lst.subset({x: x.canMatchIt})).length() > 0)
             setIt(subLst);
         if ((subLst = lst.subset({x: x.canMatchHim})).length() > 0)
             setHim(subLst);
         if ((subLst = lst.subset({x: x.canMatchHer})).length() > 0)
             setHer(subLst);
 
         /*
          *   set 'them' to the potential 'them' matches, if we didn't
          *   already find a clear plural list
          */
         if (!gotThem
             && (subLst = lst.subset({x: x.canMatchThem})).length() > 0)
             setThem(subLst);
     }
 
     /*
      *   Set a pronoun antecedent to the given ResolveInfo list, for the
      *   specified type of pronoun.  We don't have to worry about setting
      *   other types of pronouns to this antecedent - we specifically want
      *   to set the given pronoun type.  This is language-dependent
      *   because we still have to figure out the number (i.e. singular or
      *   plural) of the pronoun type.
      */
     setPronounByType(typ, lst)
     {
         /* check for singular or plural pronouns */
         if (typ == PronounThem)
         {
             /* it's plural - set a list antecedent */
             setPronounAntecedent(typ, lst.mapAll({x: x.obj_}));
         }
         else
         {
             /* it's singular - set an individual antecedent */
             setPronounAntecedent(typ, lst[1].obj_);
         }
     }
 
     /*
      *   Set a pronoun antecedent to the given simulation object (usually
      *   an object descended from Thing).
      */
     setPronounObj(obj)
     {
         /*
          *   Actually use the object's "identity object" as the antecedent
          *   rather than the object itself.  In some cases, we use multiple
          *   program objects to represent what appears to be a single
          *   object in the game; in these cases, the internal program
          *   objects all point to the "real" object as their identity
          *   object.  Whenever we're manipulating one of these internal
          *   program objects, we want to make sure that its the
          *   player-visible object - the identity object - that appears as
          *   the antecedent for subsequent references.
          */
         obj = obj.getIdentityObject();
 
         /*
          *   Set the appropriate pronoun antecedent, depending on the
          *   object's gender.
          *
          *   Note that we'll set an object to be the antecedent for both
          *   'him' and 'her' if the object has both masculine and feminine
          *   usage.
          */
 
         /* check for masculine usage */
         if (obj.canMatchHim)
             setHim(obj);
 
         /* check for feminine usage */
         if (obj.canMatchHer)
             setHer(obj);
 
         /* check for neuter usage */
         if (obj.canMatchIt)
             setIt(obj);
 
         /* check for third-person plural usage */
         if (obj.canMatchThem)
             setThem([obj]);
     }
 
     /* set a possessive anaphor */
     setPossAnaphorObj(obj)
     {
         /* check for each type of usage */
         if (obj.canMatchHim)
             possAnaphorTable[PronounHim] = obj;
         if (obj.canMatchHer)
             possAnaphorTable[PronounHer] = obj;
         if (obj.canMatchIt)
             possAnaphorTable[PronounIt] = obj;
         if (obj.canMatchThem)
             possAnaphorTable[PronounThem] = [obj];
     }
 ;
 
 /* ------------------------------------------------------------------------ */
 /*
  *   Give the postures some additional attributes
  */
 
 modify Posture
 
     /*
      *   Intransitive and transitive forms of the verb, for use in library
      *   messages.  Each of these methods simply calls one of the two
      *   corresponding fixed-tense properties, depending on the current
      *   tense.
      */
     msgVerbI = (tSel(msgVerbIPresent, msgVerbIPast))
     msgVerbT = (tSel(msgVerbTPresent, msgVerbTPast))
 
     /*
      *   Fixed-tense versions of the above properties, to be defined
      *   individually by each instance of the Posture class.
      */
 
     /* our present-tense intransitive form ("he stands up") */
     // msgVerbIPresent = 'stand{s} up'
 
     /* our past-tense intransitive form ("he stood up") */
     // msgVerbIPast = 'stood up'
 
     /* our present-tense transitive form ("he stands on the chair") */
     // msgVerbTPresent = 'stand{s}'
 
     /* our past-tense transitive form ("he stood on the chair") */
     // msgVerbTPast = 'stood'
 
     /* our participle form */
     // participle = 'standing'
 ;
 
+/*
+ *   Intransitivní použití je bez objektu: "Vstal".
+ *   Transitivní použití je takové, které má objekt "Stoupnul na židli".
+ */
 modify standing
-    msgVerbIPresent = 'stand{s} up'
-    msgVerbIPast = 'stood up'
-    msgVerbTPresent = 'stand{s}'
-    msgVerbTPast = 'stood'
-    participle = 'standing'
+    msgVerbIPresent = 'vstává'
+    msgVerbIPast = 'vstal{a}'
+    msgVerbTPresent = 'stoupá'
+    msgVerbTPast = 'stoupl{a}'
+    participle = '{stoj[íš poser]|stál[a poser]}'
 ;
 
 modify sitting
-    msgVerbIPresent = 'sit{s} down'
-    msgVerbIPast = 'sat down'
-    msgVerbTPresent = 'sit{s}'
-    msgVerbTPast = 'sat'
-    participle = 'sitting'
+    msgVerbIPresent = 'sedá'
+    msgVerbIPast = 'sedl{a}'
+    msgVerbTPresent = 'sedá'
+    msgVerbTPast = 'sedl{a}'
+    participle = '{sed[íš poser]|seděl[a poser]}'
 ;
 
 modify lying
-    msgVerbIPresent = 'lie{s} down'
-    msgVerbIPast = 'lay down'
-    msgVerbTPresent = 'lie{s}'
-    msgVerbTPast = 'lay'
-    participle = 'lying'
+    msgVerbIPresent = 'ulehá'
+    msgVerbIPast = 'ulehl{a}'
+    msgVerbTPresent = 'ulehá'
+    msgVerbTPast = 'ulehl{a}'
+    participle = '{lež[íš poser]|ležel[a poser]}'
 ;
 
 /* ------------------------------------------------------------------------ */
 /*
  *   For our various topic suggestion types, we can infer the full name
  *   from the short name fairly easily.
  */
+modify SuggestedTopic
+    nameKohoCo = name
+    nameKomCem = name
+;
+
 modify SuggestedAskTopic
-    fullName = ('ask {it targetActor/him} about ' + name)
+    fullName = ('se {tě/jí targetActor} zeptat na ' + nameKohoCo)
 ;
 
 modify SuggestedTellTopic
-    fullName = ('tell {it targetActor/him} about ' + name)
+    fullName = ('{ti/jí targetActor} říci o ' + nameKomCem)
 ;
 
 modify SuggestedAskForTopic
-    fullName = ('ask {it targetActor/him} for ' + name)
+    fullName = ('{tě/jí targetActor} požádat o ' + nameKohoCo)
 ;
 
 modify SuggestedGiveTopic
-    fullName = ('give {it targetActor/him} ' + name)
+    fullName = ('{ti/jí targetActor} dát ' + nameKohoCo)
 ;
 
 modify SuggestedShowTopic
-    fullName = ('show {it targetActor/him} ' + name)
+    fullName = ('{ti/jí targetActor} ukázat ' + nameKohoCo)
 ;
 
 modify SuggestedYesTopic
-    name = 'yes'
-    fullName = 'say yes'
+    name = 'ano'
+    fullName = 'řekni ano'
 ;
 
 modify SuggestedNoTopic
-    name = 'no'
-    fullName = 'say no'
+    name = 'ne'
+    fullName = 'řekni ne'
 ;
 
 /* ------------------------------------------------------------------------ */
 /*
  *   Provide custom processing of the player input for matching
  *   SpecialTopic patterns.  When we're trying to match a player's command
  *   to a set of active special topics, we'll run the input through this
  *   processing to produce the string that we actually match against the
  *   special topics.
  *
  *   First, we'll remove any punctuation marks.  This ensures that we'll
  *   still match a special topic, for example, if the player puts a period
  *   or a question mark at the end of the command.
  *
  *   Second, if the user's input starts with "A" or "T" (the super-short
  *   forms of the ASK ABOUT and TELL ABOUT commands), remove the "A" or "T"
  *   and keep the rest of the input.  Some users might think that special
  *   topic suggestions are meant as ask/tell topics, so they might
  *   instinctively try these as A/T commands.
  *
  *   Users *probably* won't be tempted to do the same thing with the full
  *   forms of the commands (e.g., ASK BOB ABOUT APOLOGIZE, TELL BOB ABOUT
  *   EXPLAIN).  It's more a matter of habit of using A or T for interaction
  *   that would tempt a user to phrase a special topic this way; once
  *   you're typing out the full form of the command, it generally won't be
  *   grammatical, as special topics generally contain the sense of a verb
  *   in their phrasing.
  */
 modify specialTopicPreParser
     processInputStr(str)
     {
         /*
          *   remove most punctuation from the string - we generally want to
          *   ignore these, as we mostly just want to match keywords
          */
         str = rexReplace(punctPat, str, '', ReplaceAll);
 
         /* if it starts with "A" or "T", strip off the leading verb */
         if (rexMatch(aOrTPat, str) != nil)
             str = rexGroup(1)[3];
 
         /* return the processed result */
         return str;
     }
 
     /* pattern for string starting with "A" or "T" verbs */
     aOrTPat = static new RexPattern(
-        '<nocase><space>*[at]<space>+(<^space>.*)$')
+        '<nocase><space>*(zep|řek)<space>+(<^space>.*)$')
 
     /* pattern to eliminate punctuation marks from the string */
     punctPat = static new RexPattern('[.?!,;:]');
 ;
 
 /*
  *   For SpecialTopic matches, treat some strings as "weak": if the user's
  *   input consists of just one of these weak strings and nothing else,
  *   don't match the topic.
  */
 modify SpecialTopic
     matchPreParse(str, procStr)
     {
         /* if it's one of our 'weak' strings, don't match */
         if (rexMatch(weakPat, str) != nil)
             return nil;
 
         /* it's not a weak string, so match as usual */
         return inherited(str, procStr);
     }
 
     /*
      *   Our "weak" strings - 'i', 'l', 'look': these are weak because a
      *   user typing one of these strings by itself is probably actually
      *   trying to enter the command of the same name, rather than entering
      *   a special topic.  These come up in cases where the special topic
      *   is something like "say I don't know" or "tell him you'll look into
      *   it".
      */
     weakPat = static new RexPattern('<nocase><space>*(i|l|look)<space>*$')
 ;
 
 /* ------------------------------------------------------------------------ */
 /*
  *   English-specific Traveler changes
  */
 modify Traveler
     /*
      *   Get my location's name, from the PC's perspective, for describing
      *   my arrival to or departure from my current location.  We'll
      *   simply return our location's destName, or "the area" if it
      *   doesn't have one.
      */
     travelerLocName()
     {
         /* get our location's name from the PC's perspective */
         local nm = location.getDestName(gPlayerChar, gPlayerChar.location);
 
         /* if there's a name, return it; otherwise, use "the area" */
-        return (nm != nil ? nm : 'the area');
+        return (nm != nil ? nm : 'do prostoru');
     }
 
     /*
      *   Get my "remote" location name, from the PC's perspective.  This
      *   returns my location name, but only if my location is remote from
      *   the PC's perspective - that is, my location has to be outside of
      *   the PC's top-level room.  If we're within the PC's top-level
      *   room, we'll simply return an empty string.
+     *
+     *   Používá se ve větě: "Sally odešla *z náměstí* po Široké ulici."
+     *   ale i při příchodu "Sally přišla *na náměstí* po Široké ulici."
+     *
+     *   TODO: vyřešit tvary a přeložky.
      */
     travelerRemoteLocName()
     {
         /*
          *   if my location is outside of the PC's outermost room, we're
          *   remote, so return my location name; otherwise, we're local,
          *   so we don't need a remote name at all
          */
         if (isIn(gPlayerChar.getOutermostRoom()))
             return '';
         else
-            return travelerLocName;
+            return 'z/na' + travelerLocName;
     }
 ;
 
 /* ------------------------------------------------------------------------ */
 /*
  *   English-specific Vehicle changes
  */
 modify Vehicle
     /*
      *   Display the name of the traveler, for use in an arrival or
      *   departure message.
      */
     travelerName(arriving)
     {
         /*
          *   By default, start with the indefinite name if we're arriving,
          *   or the definite name if we're leaving.
          *
          *   If we're leaving, presumably they've seen us before, since we
          *   were already in the room to start with.  Since we've been
          *   seen before, the definite is appropriate.
          *
          *   If we're arriving, even if we're not being seen for the first
          *   time, we haven't been seen yet in this place around this
          *   time, so the indefinite is appropriate.
          */
-        say(arriving ? aName : theName);
+        say(name);
 
         /* show the list of actors aboard */
         aboardVehicleListerObj.showList(
             libGlobal.playerChar, nil, allContents(), 0, 0,
             libGlobal.playerChar.visibleInfoTable(), nil);
     }
 ;
 
 /* ------------------------------------------------------------------------ */
 /*
  *   English-specific PushTraveler changes
  */
 modify PushTraveler
     /*
      *   When an actor is pushing an object from one room to another, show
      *   its name with an additional clause indicating the object being
      *   moved along with us.
      */
     travelerName(arriving)
     {
-        "<<gPlayerChar.hasSeen(self) ? theName : aName>>,
-        pushing <<obj_.theNameObj>>,";
+        "<<name>>,
+        {tlač[íš]|tlačil[a]} <<obj_.nameKohoCo>>,";
     }
 ;
 
 
 /* ------------------------------------------------------------------------ */
 /*
  *   English-specific travel connector changes
  */
 
 modify PathPassage
     /* treat "take path" the same as "enter path" or "go through path" */
     dobjFor(Take) maybeRemapTo(
         gAction.getEnteredVerbPhrase() == 'take (dobj)', TravelVia, self)
 
     dobjFor(Enter)
     {
         verify() { logicalRank(50, 'enter path'); }
     }
     dobjFor(GoThrough)
     {
         verify() { logicalRank(50, 'enter path'); }
     }
 ;
 
 modify AskConnector
     /*
      *   This is the noun phrase we'll use when asking disambiguation
      *   questions for this travel connector: "Which *one* do you want to
      *   enter..."
      */
     travelObjsPhrase = 'one'
 ;
 
 /* ------------------------------------------------------------------------ */
 /*
  *   English-specific changes for various nested room types.
+ *
+ *   ">ven (z dřevěné prkno)"
  */
 modify BasicChair
     /* by default, one sits *on* a chair */
-    objInPrep = 'on'
-    actorInPrep = 'on'
-    actorOutOfPrep = 'off of'
+    objInPrep = 'na'
+    objOutOfPrep = 'z'
+    objIntoPad = 4
 ;
 
 modify BasicPlatform
     /* by default, one stands *on* a platform */
-    objInPrep = 'on'
-    actorInPrep = 'on'
-    actorOutOfPrep = 'off of'
+    objInPrep = 'na'
+    objOutOfPrep = 'z'
+    objIntoPad = 4
 ;
 
 modify Booth
     /* by default, one is *in* a booth */
-    objInPrep = 'in'
-    actorInPrep = 'in'
-    actorOutOfPrep = 'out of'
+    objInPrep = 'v'
+    objOutOfPrep = 'z'
 ;
 
 /* ------------------------------------------------------------------------ */
 /*
  *   Language modifications for Matchstick
  */
 modify Matchstick
     /* "strike match" means "light match" */
     dobjFor(Strike) asDobjFor(Burn)
 
     /* "light match" means "burn match" */
     dobjFor(Light) asDobjFor(Burn)
 ;
 
+/* ------------------------------------------------------------------------ */
+/*
+ *   Jazyková modifikace pro Keyring
+ */
+modify Keyring
+    /* Kroužek na klíče je pravděpodobně mužský životný, tak změníme výchozí */
+    gender = 1
+;
+
 /*
  *   Match state objects.  We show "lit" as the state for a lit match,
  *   nothing for an unlit match.
  */
 matchStateLit: ThingState 'lit'
     stateTokens = ['lit']
 ;
 matchStateUnlit: ThingState
     stateTokens = ['unlit']
 ;
 
 
 /* ------------------------------------------------------------------------ */
 /*
  *   English-specific modifications for Room.
  */
 modify Room
     /*
      *   The ordinary 'name' property is used the same way it's used for
      *   any other object, to refer to the room when it shows up in
      *   library messages and the like: "You can't take the hallway."
      *
      *   By default, we derive the name from the roomName by converting
      *   the roomName to lower case.  Virtually every room will need a
      *   custom room name setting, since the room name is used mostly as a
      *   title for the room, and good titles are hard to generate
      *   mechanically.  Many times, converting the roomName to lower case
      *   will produce a decent name to use in messages: "Ice Cave" gives
      *   us "You can't eat the ice cave."  However, games will want to
      *   customize the ordinary name separately in many cases, because the
      *   elliptical, title-like format of the room name doesn't always
      *   translate well to an object name: "West of Statue" gives us the
      *   unworkable "You can't eat the west of statue"; better to make the
      *   ordinary name something like "plaza".  Note also that some rooms
      *   have proper names that want to preserve their capitalization in
      *   the ordinary name: "You can't eat the Hall of the Ancient Kings."
      *   These cases need to be customized as well.
      */
     name = (roomName.toLower())
 
     /*
      *   The "destination name" of the room.  This is primarily intended
      *   for use in showing exit listings, to describe the destination of
      *   a travel connector leading away from our current location, if the
      *   destination is known to the player character.  We also use this
      *   as the default source of the name in similar contexts, such as
      *   when we can see this room from another room connected by a sense
      *   connector.
      *
      *   The destination name usually mirrors the room name, but we use
      *   the name in prepositional phrases involving the room ("east, to
      *   the alley"), so this name should include a leading article
      *   (usually definite - "the") unless the name is proper ("east, to
      *   Dinsley Plaza").  So, by default, we simply use the "theName" of
      *   the room.  In many cases, it's better to specify a custom
      *   destName, because this name is used when the PC is outside of the
      *   room, and thus can benefit from a more detailed description than
      *   we'd normally use for the basic name.  For example, the ordinary
      *   name might simply be something like "hallway", but since we want
      *   to be clear about exactly which hallway we're talking about when
      *   we're elsewhere, we might want to use a destName like "the
      *   basement hallway" or "the hallway outside the operating room".
+     *
+     *   Název místnosti má odpovídat na otázku "kam?". Výchozí hodnota je jen
+     *   nuozovka, nebude většinou znít dobře a tak musí být u každé místnosti
+     *   zadáno.
      */
-    destName = (theName)
+    destName = (name)
 
     /*
      *   For top-level rooms, describe an object as being in the room by
      *   describing it as being in the room's nominal drop destination,
      *   since that's the nominal location for the objects directly in the
      *   room.  (In most cases, the nominal drop destination for a room is
      *   its floor.)
      *
      *   If the player character isn't in the same outermost room as this
      *   container, use our remote name instead of the nominal drop
      *   destination.  The nominal drop destination is usually something
      *   like the floor or the ground, so it's only suitable when we're in
      *   the same location as what we're describing.
      */
     childInName(childName)
     {
         /* if the PC isn't inside us, we're viewing this remotely */
         if (!gPlayerChar.isIn(self))
             return childInRemoteName(childName, gPlayerChar);
         else
             return getNominalDropDestination().childInName(childName);
     }
     childInNameWithOwner(chiName)
     {
         /* if the PC isn't inside us, we're viewing this remotely */
         if (!gPlayerChar.isIn(self))
             return inherited(chiName);
         else
             return getNominalDropDestination().childInNameWithOwner(chiName);
     }
 ;
 
 /* ------------------------------------------------------------------------ */
 /*
  *   English-specific modifications for the default room parts.
  */
 
 modify Floor
-    childInNameGen(childName, myName) { return childName + ' on ' + myName; }
-    objInPrep = 'on'
-    actorInPrep = 'on'
-    actorOutOfPrep = 'off of'
+    childInNameGen(childName, myName) { return childName + ' na ' + myName; }
+    objInPrep = 'na'
+    objOutOfPrep = 'z'
+    objIntoPad = 4
+    gender = 3 /* podlaha i zem jsou rodu ženského */
 ;
 
 modify defaultFloor
-    noun = 'floor' 'ground'
-    name = 'floor'
+    noun = 'podlahu' 'podlahy' 'podlaze' 'zem' 'země' 'zemi'
+    name = 'podlaha'
+    nameKohoCeho = 'podlahy'
+    nameKohoCo = 'podlahu'
+    nameKomCem = 'podlaze'
 ;
 
 modify defaultGround
-    noun = 'ground' 'floor'
-    name = 'ground'
+    noun = 'zem' 'země' 'zemi' 'podlahu' 'podlahy' 'podlaze'
+    name = 'zem'
+    nameKohoCeho = 'země'
+    nameKohoCo = 'zem'
+    nameKomCem = 'zemi'
+    objOutOfPrep = 'ze'
 ;
 
-modify DefaultWall noun='wall' plural='walls' name='wall';
-modify defaultCeiling noun='ceiling' 'roof' name='ceiling';
-modify defaultNorthWall adjective='n' 'north' name='north wall';
-modify defaultSouthWall adjective='s' 'south' name='south wall';
-modify defaultEastWall adjective='e' 'east' name='east wall';
-modify defaultWestWall adjective='w' 'west' name='west wall';
-modify defaultSky noun='sky' name='sky';
+modify DefaultWall noun='zeď' plural='zdi' name='zeď' gender=3;
+modify defaultCeiling noun='strop' name='strop' gender=2;
+modify defaultNorthWall adjective='s' 'severní' name='severní zeď';
+modify defaultSouthWall adjective='j' 'jižní' name='jižní zeď';
+modify defaultEastWall adjective='v' 'východní' name='východní zeď';
+modify defaultWestWall adjective='z' 'západní' name='západní zeď';
+modify defaultSky noun='obloha' 'nebe' 'nebesa' name='obloha' gender=3;
 
 
 /* ------------------------------------------------------------------------ */
 /*
  *   The English-specific modifications for directions.
  */
 modify Direction
     /* describe a traveler arriving from this direction */
     sayArriving(traveler)
     {
         /* show the generic arrival message */
         gLibMessages.sayArriving(traveler);
     }
 
     /* describe a traveler departing in this direction */
     sayDeparting(traveler)
     {
         /* show the generic departure message */
         gLibMessages.sayDeparting(traveler);
     }
 ;
 
 /*
  *   The English-specific modifications for compass directions.
  */
 modify CompassDirection
+    dirFromName = name
     /* describe a traveler arriving from this direction */
     sayArriving(traveler)
     {
         /* show the generic compass direction description */
-        gLibMessages.sayArrivingDir(traveler, name);
+        gLibMessages.sayArrivingDir(traveler, nameFrom);
     }
 
     /* describe a traveler departing in this direction */
     sayDeparting(traveler)
     {
         /* show the generic compass direction description */
         gLibMessages.sayDepartingDir(traveler, name);
     }
 ;
 
 /*
  *   The English-specific definitions for the compass direction objects.
  *   In addition to modifying the direction objects to define the name of
  *   the direction, we add a 'directionName' grammar rule.
+ *
+ *   Tady pro češtinu musíme přidat nový druhý sloupeček, ve kterém bude
+ *   znění směru pro vylistování východů, např. "Zřetelné východy vedou
+ *   na východ, na severozápad a dovnitř." Původně se totiž název směru
+ *   odvozoval z anglického názvu směru, který je zároveň identifikátorem
+ *   směru v programu. Otázkou je, co by se všechno muselo změnit, abych
+ *   mohl psát směry ve zdrojáku česky, tj. i s diakritikou. Asi to nemá
+ *   cenu řešit.
  */
-#define DefineLangDir(root, dirNames, backPre) \
+#define DefineLangDir(root, dirName, dirFromName, dirNames, backPre) \
 grammar directionName(root): dirNames: DirectionProd \
    dir = root##Direction \
 ; \
 \
 modify root##Direction \
-   name = #@root \
+   name = dirName \
+   nameFrom = dirFromName \
    backToPrefix = backPre
 
-DefineLangDir(north, 'north' | 'n', 'back to the');
-DefineLangDir(south, 'south' | 's', 'back to the');
-DefineLangDir(east, 'east' | 'e', 'back to the');
-DefineLangDir(west, 'west' | 'w', 'back to the');
-DefineLangDir(northeast, 'northeast' | 'ne', 'back to the');
-DefineLangDir(northwest, 'northwest' | 'nw', 'back to the');
-DefineLangDir(southeast, 'southeast' | 'se', 'back to the');
-DefineLangDir(southwest, 'southwest' | 'sw', 'back to the');
-DefineLangDir(up, 'up' | 'u', 'back');
-DefineLangDir(down, 'down' | 'd', 'back');
-DefineLangDir(in, 'in', 'back');
-DefineLangDir(out, 'out', 'back');
+DefineLangDir(north, 'na sever', 'ze severu', 'sever' | 'severně' | 's', 'back to the');
+DefineLangDir(south, 'na jih', 'z jihu', 'jih' | 'jižně' | 'j', 'back to the');
+DefineLangDir(east, 'na východ', 'z východu', 'východ' | 'východně' | 'v', 'back to the');
+DefineLangDir(west, 'na západ', 'ze západu', 'západ' | 'západně' | 'z', 'back to the');
+DefineLangDir(northeast, 'na severovýchod', 'ze severovýchodu', 'severovýchod' | 'severovýchodně' | 'sv', 'zpátky na');
+DefineLangDir(northwest, 'na severozápad', 'ze severozápadu', 'severozápad' | 'severozápadně' | 'sz', 'zpátky na');
+DefineLangDir(southeast, 'na jihovýchod', 'z jihovýchodu', 'jihovýchod' | 'jihovýchodně' | 'jv', 'zpátky na');
+DefineLangDir(southwest, 'na jihozápad', 'z jihozápadu', 'jihozápad' | 'jihozápadně' | 'jz', 'zpátky na');
+DefineLangDir(up, 'nahoru', 'ze shora', 'nahoru' | 'n', 'zpátky');
+DefineLangDir(down, 'dolů', 'ze zdola', 'dolu' | 'dolů' | 'd', 'zpátky');
+DefineLangDir(in, 'dovnitř', 'zevnitř', 'dovnitř' | 'dov', 'zpátky');
+DefineLangDir(out, 'ven', 'zvenku', 'ven', 'zpátky');
 
 /*
  *   The English-specific shipboard direction modifications.  Certain of
  *   the ship directions have no natural descriptions for arrival and/or
  *   departure; for example, there's no good way to say "arriving from
  *   fore."  Others don't fit any regular pattern: "he goes aft" rather
  *   than "he departs to aft."  As a result, these are a bit irregular
  *   compared to the compass directions and so are individually defined
  *   below.
  */
 
-DefineLangDir(port, 'port' | 'p', 'back to')
+DefineLangDir(port, 'na levobok', 'z levoboku', 'levobok' | 'lb', 'zpátky na')
     sayArriving(trav)
         { gLibMessages.sayArrivingShipDir(trav, 'the port direction'); }
     sayDeparting(trav)
         { gLibMessages.sayDepartingShipDir(trav, 'port'); }
 ;
 
-DefineLangDir(starboard, 'starboard' | 'sb', 'back to')
+DefineLangDir(starboard, 'na pravobok', 'z pravoboku', 'pravobok' | 'pb', 'zpátky na')
     sayArriving(trav)
         { gLibMessages.sayArrivingShipDir(trav, 'starboard'); }
     sayDeparting(trav)
         { gLibMessages.sayDepartingShipDir(trav, 'starboard'); }
 ;
 
-DefineLangDir(aft, 'aft' | 'a', 'back to')
+DefineLangDir(aft, 'na záď', 'ze zádi', 'záď' | 'zá' | 'zd', 'zpátky na')
     sayArriving(trav) { gLibMessages.sayArrivingShipDir(trav, 'aft'); }
     sayDeparting(trav) { gLibMessages.sayDepartingAft(trav); }
 ;
 
-DefineLangDir(fore, 'fore' | 'forward' | 'f', 'back to')
+DefineLangDir(fore, 'na příď', 'z přídi', 'příď' | 'dopředu' | 'př' | 'pr' | 'pd', 'zpátky na')
     sayArriving(trav) { gLibMessages.sayArrivingShipDir(trav, 'forward'); }
     sayDeparting(trav) { gLibMessages.sayDepartingFore(trav); }
 ;
 
 /* ------------------------------------------------------------------------ */
 /*
  *   Some helper routines for the library messages.
  */
 class MessageHelper: object
     /*
      *   Show a list of objects for a disambiguation query.  If
      *   'showIndefCounts' is true, we'll show the number of equivalent
      *   items for each equivalent item; otherwise, we'll just show an
      *   indefinite noun phrase for each equivalent item.
      */
     askDisambigList(matchList, fullMatchList, showIndefCounts, dist)
     {
         /* show each item */
         for (local i = 1, local len = matchList.length() ; i <= len ; ++i)
         {
             local equivCnt;
             local obj;
 
             /* get the current object */
             obj = matchList[i].obj_;
 
             /*
              *   if this isn't the first, add a comma; if this is the
              *   last, add an "or" as well
               */
             if (i == len)
-                ", or ";
+                ", nebo ";
             else if (i != 1)
                 ", ";
 
             /*
              *   Check to see if more than one equivalent of this item
              *   appears in the full list.
              */
             for (equivCnt = 0, local j = 1,
                  local fullLen = fullMatchList.length() ; j <= fullLen ; ++j)
             {
                 /*
                  *   if this item is equivalent for the purposes of the
                  *   current distinguisher, count it
                  */
                 if (!dist.canDistinguish(obj, fullMatchList[j].obj_))
                 {
                     /* it's equivalent - count it */
                     ++equivCnt;
                 }
             }
 
-            /* show this item with the appropriate article */
-            if (equivCnt > 1)
+            /*
+             *   we have multiple equivalents - show either with or without
+             *   a count, depending on the flags the caller provided
+             *
+             *   Bylo zjednodušeno o rozhodování určitého a neurčitého členu.
+             */
+            if (equivCnt > 1 && showIndefCounts)
             {
-                /*
-                 *   we have multiple equivalents - show either with an
-                 *   indefinite article or with a count, depending on the
-                 *   flags the caller provided
-                 */
-                if (showIndefCounts)
-                {
-                    /* a count is desired for each equivalent group */
-                    say(dist.countName(obj, equivCnt));
-                }
-                else
-                {
-                    /* no counts desired - show with an indefinite article */
-                    say(dist.aName(obj));
-                }
+                /* a count is desired for each equivalent group */
+                say(dist.countName(obj, equivCnt));
             }
             else
             {
-                /* there's only one - show with a definite article */
-                say(dist.theName(obj));
+                /* there's only one */
+                say(dist.name(obj));
             }
         }
     }
 
     /*
      *   For a TAction result, select the short-form or long-form message,
      *   according to the disambiguation status of the action.  This is for
      *   the ultra-terse default messages, such as "Taken" or "Dropped",
      *   that sometimes need more descriptive variations.
      *   
      *   If there was no disambiguation involved, we'll use the short
      *   version of the message.
      *   
      *   If there was unclear disambiguation involved (meaning that there
      *   was more than one logical object matching a noun phrase, but the
      *   parser was able to decide based on likelihood rankings), we'll
      *   still use the short version, because we assume that the parser
      *   will have generated a parenthetical announcement to point out its
      *   choice.
      *   
      *   If there was clear disambiguation involved (meaning that more than
      *   one in-scope object matched a noun phrase, but there was only one
      *   choice that passed the logicalness tests), AND the announcement
      *   mode (in gameMain.ambigAnnounceMode) is DescribeClear, we'll
      *   choose the long-form message.  
      */
     shortTMsg(short, long)
     {
         /* check the disambiguation flags and the announcement mode */
         if ((gAction.getDobjFlags() & (ClearDisambig | AlwaysAnnounce))
             == ClearDisambig
             && gAction.getDobjCount() == 1
             && gameMain.ambigAnnounceMode == DescribeClear)
         {
             /* clear disambig and DescribeClear mode - use the long message */
             return long;
         }
         else
         {
             /* in other cases, use the short message */
             return short;
         }
     }
 
     /*
      *   For a TIAction result, select the short-form or long-form message.
      *   This works just like shortTIMsg(), but takes into account both the
      *   direct and indirect objects. 
      */
     shortTIMsg(short, long)
     {
         /* check the disambiguation flags and the announcement mode */
         if (((gAction.getDobjFlags() & (ClearDisambig | AlwaysAnnounce))
              == ClearDisambig
              || (gAction.getIobjFlags() & (ClearDisambig | AlwaysAnnounce))
              == ClearDisambig)
             && gAction.getDobjCount() == 1
             && gAction.getIobjCount() == 1
             && gameMain.ambigAnnounceMode == DescribeClear)
         {
             /* clear disambig and DescribeClear mode - use the long message */
             return long;
         }
         else
         {
             /* in other cases, use the short message */
             return short;
         }
     }
 ;
 
 /* ------------------------------------------------------------------------ */
 /*
  *   Custom base resolver
  */
 modify Resolver
     /*
      *   Get the default in-scope object list for a given pronoun.  We'll
      *   look for a unique object in scope that matches the desired
      *   pronoun, and return a ResolveInfo list if we find one.  If there
      *   aren't any objects in scope that match the pronoun, or multiple
      *   objects are in scope, there's no default.
      */
     getPronounDefault(typ, np)
     {
         local map = [PronounHim, &canMatchHim,
                      PronounHer, &canMatchHer,
                      PronounIt, &canMatchIt];
         local idx = map.indexOf(typ);
         local filterProp = (idx != nil ? map[idx + 1] : nil);
         local lst;
 
         /* if we couldn't find a filter for the pronoun, ignore it */
         if (filterProp == nil)
             return [];
 
         /*
          *   filter the list of all possible defaults to those that match
          *   the given pronoun
          */
         lst = getAllDefaults.subset({x: x.obj_.(filterProp)});
 
         /*
          *   if the list contains exactly one element, then there's a
          *   unique default; otherwise, there's either nothing here that
          *   matches the pronoun or the pronoun is ambiguous, so there's
          *   no default
          */
         if (lst.length() == 1)
         {
             /*
              *   we have a unique object, so they must be referring to it;
              *   because this is just a guess, though, mark it as vague
              */
             lst[1].flags_ |= UnclearDisambig;
 
             /* return the list */
             return lst;
         }
         else
         {
             /*
              *   the pronoun doesn't have a unique in-scope referent, so
              *   we can't guess what they mean
              */
             return [];
         }
     }
 ;
 
 /* ------------------------------------------------------------------------ */
 /*
  *   Custom interactive resolver.  This is used for responses to
  *   disambiguation questions and prompts for missing noun phrases.
  */
 modify InteractiveResolver
     /*
      *   Resolve a pronoun antecedent.  We'll resolve a third-person
      *   singular pronoun to the target actor if the target actor matches
      *   in gender, and the target actor isn't the PC.  This allows
      *   exchanges like this:
      *
      *.  >bob, examine
      *.  What do you want Bob to look at?
      *.
      *.  >his book
      *
      *   In the above exchange, we'll treat "his" as referring to Bob, the
      *   target actor of the action, because we have referred to Bob in
      *   the partial command (the "BOB, EXAMINE") that triggered the
      *   interactive question.
      */
     resolvePronounAntecedent(typ, np, results, poss)
     {
         local lst;
 
         /* try resolving with the target actor as the antecedent */
         if ((lst = resolvePronounAsTargetActor(typ)) != nil)
             return lst;
 
         /* use the inherited result */
         return inherited(typ, np, results, poss);
     }
 
     /*
      *   Get the reflexive third-person pronoun binding (himself, herself,
      *   itself, themselves).  If the target actor isn't the PC, and the
      *   gender of the pronoun matches, we'll consider this as referring
      *   to the target actor.  This allows exchanges of this form:
      *
      *.  >bob, examine
      *.  What do you want Bob to examine?
      *.
      *.  >himself
      */
     getReflexiveBinding(typ)
     {
         local lst;
 
         /* try resolving with the target actor as the antecedent */
         if ((lst = resolvePronounAsTargetActor(typ)) != nil)
             return lst;
 
         /* use the inherited result */
         return inherited(typ);
     }
 
     /*
      *   Try matching the given pronoun type to the target actor.  If it
      *   matches in gender, and the target actor isn't the PC, we'll
      *   return a resolve list consisting of the target actor.  If we
      *   don't have a match, we'll return nil.
      */
     resolvePronounAsTargetActor(typ)
     {
         /*
          *   if the target actor isn't the player character, and the
          *   target actor can match the given pronoun type, resolve the
          *   pronoun as the target actor
          */
         if (actor_.canMatchPronounType(typ) && !actor_.isPlayerChar())
         {
             /* the match is the target actor */
             return [new ResolveInfo(actor_, 0)];
         }
 
         /* we didn't match it */
         return nil;
     }
 ;
 
 /*
  *   Custom disambiguation resolver.
  */
 modify DisambigResolver
     /*
      *   Perform special resolution on pronouns used in interactive
      *   responses.  If the pronoun is HIM or HER, then look through the
      *   list of possible matches for a matching gendered object, and use
      *   it as the result if we find one.  If we find more than one, then
      *   use the default handling instead, treating the pronoun as
      *   referring back to the simple antecedent previously set.
      */
     resolvePronounAntecedent(typ, np, results, poss)
     {
         /* if it's a non-possessive HIM or HER, use our special handling */
         if (!poss && typ is in (PronounHim, PronounHer))
         {
             local prop;
             local sub;
 
             /* get the gender indicator property for the pronoun */
             prop = (typ == PronounHim ? &canMatchHim : &canMatchHer);
 
             /*
              *   Scan through the match list to find the objects that
              *   match the gender of the pronoun.  Note that if the player
              *   character isn't referred to in the third person, we'll
              *   ignore the player character for the purposes of matching
              *   this pronoun - if we're calling the PC 'you', then we
              *   wouldn't expect the player to refer to the PC as 'him' or
              *   'her'.
              */
             sub = matchList.subset({x: x.obj_.(prop)});
 
             /* if the list has a single entry, then use it as the match */
             if (sub.length() == 1)
                 return sub;
 
             /*
              *   if it has more than one entry, it's still ambiguous, but
              *   we might have narrowed it down, so throw a
              *   still-ambiguous exception and let the interactive
              *   disambiguation ask for further clarification
              */
             results.ambiguousNounPhrase(nil, ResolveAsker, 'one',
                                         sub, matchList, matchList,
                                         1, self);
             return [];
         }
 
         /*
          *   if we get this far, it means we didn't use our special
          *   handling, so use the inherited behavior
          */
         return inherited(typ, np, results, poss);
     }
 ;
 
 /* ------------------------------------------------------------------------ */
 /*
  *   Distinguisher customizations for English.
  *   
  *   Each distinguisher must provide a method that gets the name of an item
  *   for a disamgiguation query.  Since these are inherently
  *   language-specific, they're defined here.  
  */
 
 /*
  *   The null distinguisher tells objects apart based strictly on the name
  *   string.  When we list objects, we simply show the basic name - since
  *   we can tell apart our objects based on the base name, there's no need
  *   to resort to other names.  
+ *
+ *   TODO: Neměl bych pády dát do třídy Distinguisher místo jedné konrétní
+ *   instance?
  */
 modify nullDistinguisher
     /* we can tell objects apart if they have different base names */
     canDistinguish(a, b) { return a.name != b.name; }
 
     name(obj) { return obj.name; }
-    aName(obj) { return obj.aName; }
-    theName(obj) { return obj.theName; }
+    nameKohoCeho(obj) { return obj.nameKohoCeho; }
+    nameKomuCemu(obj) { return obj.nameKomuCemu; }
+    nameKohoCo(obj) { return obj.nameKohoCo; }
+    nameKomCem(obj) { return obj.nameKomCem; }
+    nameKymCim(obj) { return obj.nameKymCim; }
     countName(obj, cnt) { return obj.countName(cnt); }
 ;
 
 
 /*
  *   The basic distinguisher can tell apart objects that are not "basic
  *   equivalents" of one another.  Thus, we need make no distinctions when
  *   listing objects apart from showing their names.  
  */
 modify basicDistinguisher
     name(obj) { return obj.disambigName; }
-    aName(obj) { return obj.aDisambigName; }
-    theName(obj) { return obj.theDisambigName; }
     countName(obj, cnt) { return obj.countDisambigName(cnt); }
 ;
 
 /*
  *   The ownership distinguisher tells objects apart based on who "owns"
  *   them, so it shows the owner or location name when listing the object. 
  */
 modify ownershipDistinguisher
-    name(obj) { return obj.theNameOwnerLoc(true); }
-    aName(obj) { return obj.aNameOwnerLoc(true); }
-    theName(obj) { return obj.theNameOwnerLoc(true); }
+    name(obj) { return obj.nameOwnerLoc(true); }
     countName(obj, cnt) { return obj.countNameOwnerLoc(cnt, true); }
 
     /* note that we're prompting based on this distinguisher */
     notePrompt(lst)
     {
         /*
          *   notify each object that we're referring to it by
          *   owner/location in a disambiguation prompt
          */
         foreach (local cur in lst)
             cur.obj_.notePromptByOwnerLoc(true);
     }
 ;
 
 /*
  *   The location distinguisher tells objects apart based on their
  *   containers, so it shows the location name when listing the object. 
  */
 modify locationDistinguisher
-    name(obj) { return obj.theNameOwnerLoc(nil); }
-    aName(obj) { return obj.aNameOwnerLoc(nil); }
-    theName(obj) { return obj.theNameOwnerLoc(nil); }
+    name(obj) { return obj.nameOwnerLoc(nil); }
     countName(obj, cnt) { return obj.countNameOwnerLoc(cnt, nil); }
 
     /* note that we're prompting based on this distinguisher */
     notePrompt(lst)
     {
         /* notify the objects of their use in a disambiguation prompt */
         foreach (local cur in lst)
             cur.obj_.notePromptByOwnerLoc(nil);
     }
 ;
 
 /*
  *   The lit/unlit distinguisher tells apart objects based on whether
  *   they're lit or unlit, so we list objects as lit or unlit explicitly.  
  */
 modify litUnlitDistinguisher
     name(obj) { return obj.nameLit; }
-    aName(obj) { return obj.aNameLit; }
-    theName(obj) { return obj.theNameLit; }
     countName(obj, cnt) { return obj.pluralNameLit; }
 ;
 
 /* ------------------------------------------------------------------------ */
 /*
  *   Enligh-specific light source modifications
  */
 modify LightSource
     /* provide lit/unlit names for litUnlitDistinguisher */
     nameLit = ((isLit ? 'lit ' : 'unlit ') + name)
     aNameLit()
     {
         /*
          *   if this is a mass noun or a plural name, just use the name
          *   with lit/unlit; otherwise, add "a"
          */
         if (isPlural || isMassNoun)
             return (isLit ? 'lit ' : 'unlit ') + name;
         else
             return (isLit ? 'a lit ' : 'an unlit ') + name;
     }
-    theNameLit = ((isLit ? 'the lit ' : 'the unlit ') + name)
     pluralNameLit = ((isLit ? 'lit ' : 'unlit ') + pluralName)
 
     /*
      *   Allow 'lit' and 'unlit' as adjectives - but even though we define
      *   these as our adjectives in the dictionary, we'll only accept the
      *   one appropriate for our current state, thanks to our state
      *   objects.
      */
     adjective = 'lit' 'unlit'
 ;
 
 /*
  *   Light source list states.  An illuminated light source shows its
  *   status as "providing light"; an unlit light source shows no extra
  *   status.
+ *
+ *   TODO: přebírá rod z postavy, ne předmětu!
  */
-lightSourceStateOn: ThingState 'providing light'
+lightSourceStateOn: ThingState 'svít{í|il[a]}'
     stateTokens = ['lit']
 ;
-lightSourceStateOff: ThingState
-    stateTokens = ['unlit']
+lightSourceStateOff: ThingState
+    stateTokens = ['unlit']
+;
+
+/* ------------------------------------------------------------------------ */
+/*
+ *   Wearable states - a wearable item can be either worn or not worn.
+ */
+
+/* "worn" */
+wornState: ThingState 'na sobě'
+    /*
+     *   In listings of worn items, don't bother mentioning our 'worn'
+     *   status, as the entire list consists of items being worn - it
+     *   would be redundant to point out that the items in a list of items
+     *   being worn are being worn.
+     */
+    wornName(lst) { return nil; }
+;
+
+/*
+ *   "Unworn" state.  Don't bother mentioning the status of an unworn item,
+ *   since this is the default for everything.  
+ */
+unwornState: ThingState;
+
+/*
+ *   Lister musíme modifikovat kvůli funkci na vypisování seznamů. V této
+ *   funkci se volá showListPrefixWide, kde si potřebujeme předat první
+ *   objekt v následujícím seznamu, abychom mohli přizpůsobit rod slovesa
+ *   být. Např. "Na staré kredenci *byla* malá plechovka a bonbón." vs. 
+ *   "Na pultu *byl* mosazný zvonek a malá plechovka."
+ *
+ *   Další důležitá modifikace se týká zkracování zájmen. Protože v návrhu
+ *   témat k rozhovoru se skupina sestaví podle vzoru "se ho zeptat na x",
+ *   což správně funguje v případě "...nebo se ho zeptat na x". Jenže na
+ *   začátku věty to sestaví "Mohl bys se ho zeptat na oheň." A my právě
+ *   potřebujeme postprocesingem predělat "bys se" na "by ses", event.
+ *   ještě "bys si!" na "by sis", ale to normalne nevyuziju.
+ */
+modify Lister
+    /*
+     *   Show the list.  This is called after we've figured out which items
+     *   we intend to display, and after we've arranged the items into
+     *   groups.  In rare cases, listers might want to override this, to
+     *   customize the way the way the list is displayed based on the
+     *   internal arrangement of the list.  
+     */
+    showArrangedList(pov, parent, lst, options, indent, infoTab, itemCount,
+                     singles, groups, groupTab, origLst)
+    {
+        /*
+         *   We now know how many items we're listing (grammatically
+         *   speaking), so we're ready to display the list prefix.  If
+         *   we're displaying nothing at all, just display the "empty"
+         *   message, and we're done.  
+         */
+        if (itemCount == 0)
+        {
+            /* show the empty list */
+            showListEmpty(pov, parent);
+        }
+        else
+        {
+            local i;
+            local cnt;
+            local sublists;
+            local origOptions = options;
+            local itemOptions;
+            local groupOptions;
+            local listCount;
+            local dispCount;
+            local cur;
+            local selector;
+
+            /* 
+             *   Check to see if we have one or more group sublists - if
+             *   we do, we must use the "long" list format for our overall
+             *   list, otherwise we can use the normal "short" list
+             *   format.  The long list format uses semicolons to separate
+             *   items.  
+             */
+            for (i = 1, cnt = groups.length(), sublists = nil ;
+                 i <= cnt ; ++i)
+            {
+                /* 
+                 *   if this group's lister item displays a sublist, we
+                 *   must use the long format 
+                 */
+                if (groups[i].groupDisplaysSublist)
+                {
+                    /* note that we are using the long format */
+                    sublists = true;
+                    
+                    /* 
+                     *   one is enough to make us use the long format, so
+                     *   we need not look any further 
+                     */
+                    break;
+                }
+            }
+            
+            /* generate the prefix message if we're in a 'tall' listing */
+            if ((options & ListTall) != 0)
+            {
+                /* indent the prefix */
+                showListIndent(options, indent);
+                
+                /*
+                 *   Určíme selector pro výběr tvaru slovesa v minulém čase.
+                 *   Přísudek musí být ve shodě s podměty, tj. ve shodě s
+                 *   objekty seznamu. Protože listujeme objekty na výšku, tedy
+                 *   v seznamu, dáme přednost určení tvaru slovesa podle všech
+                 *   objektů, místo podle prvního. Viz bod 2. na
+                 *   http://prirucka.ujc.cas.cz/?id=601
+                 *
+                 *   jednotné číslo:
+                 *      1 = mužský rod - tvar bez koncovky (byl)
+                 *      2 = ženský rod - koncovka 'a' (byla)
+                 *      3 = střední rod - koncovka 'o' (bylo)
+                 *   množné číslo:
+                 *      4 = mužský životný rod - koncovka 'i' (byli)
+                 *      5 = mužský neživotný a ženský rod - koncovka 'y' (byly)
+                 *      6 = střední rod - koncovka 'a' (byla)
+                 */
+            	if(itemCount > 1 || lst[1].isPlural)
+            	{
+                    /* Přednost má mužský živ., potom neživotný a ženský */
+            	    local m = 0, n = 0;
+                    foreach(cur in lst)
+                    {
+        	        if(cur.gender == 1) m++;
+        	        if(cur.gender == 2 || cur.gender == 3) n++;
+                    }
+            	    selector = m ? 4 : (n ? 5 : 6);
+            	}
+            	else
+                {
+                    /* Pokud je v seznamu jediný objekt, určíme podle něj. */
+            	    selector = lst[1].gender == 1 || lst[1].gender == 2 ? 1
+            	        : (lst[1].gender == 3 ? 2 : 3);
+                }
+                
+                /* 
+                 *   Show the prefix.  If this is a contents listing, and
+                 *   it's not at the top level, show the contents prefix;
+                 *   otherwise show the full list prefix.  Note that we can
+                 *   have a contents listing at the top level, since some
+                 *   lists are broken out for separate listing.  
+                 */
+                if ((options & ListContents) != 0 && indent != 0)
+                    showListContentsPrefixTall(itemCount, pov, parent, selector);
+                else
+                    showListPrefixTall(itemCount, pov, parent, selector);
+                
+                /* go to a new line for the list contents */
+                "\n";
+                
+                /* indent the items one level now, since we showed a prefix */
+                ++indent;
+            }
+            else
+            {
+                /*
+                 *   Nagenerujeme selektor pro tvar slovesa v minulém čase ve
+                 *   shodě s prvním objektem v seznamu.
+                 */
+                if(itemCount > 1 || lst[1].isPlural)
+                    selector = lst[1].gender == 1 ? 4 : lst[1].gender == 2
+                    || lst[1].gender == 3 ? 5 : 6;
+                else
+            	    selector = lst[1].gender == 1 || lst[1].gender == 2 ? 1
+            	    : lst[1].gender == 3 ? 2 : 3;
+
+                /* show the prefix */
+                showListPrefixWide(itemCount, pov, parent, selector);
+            }
+            
+            /* 
+             *   regardless of whether we're adding long formatting to the
+             *   main list, display the group sublists with whatever
+             *   formatting we were originally using 
+             */
+            groupOptions = options;
+            
+            /* show each item with our current set of options */
+            itemOptions = options;
+            
+            /* 
+             *   if we're using sublists, show "long list" separators in
+             *   the main list 
+             */
+            if (sublists)
+                itemOptions |= ListLong;
+            
+            /* 
+             *   calculate the number of items we'll show in the list -
+             *   each group shows up as one list entry, so the total
+             *   number of list entries is the number of single items plus
+             *   the number of groups 
+             */
+            listCount = singles.length() + groups.length();
+
+            /*
+             *   Show the items.  Run through the (filtered) original
+             *   list, so that we show everything in the original sorting
+             *   order.  
+             */
+            dispCount = 0;
+            foreach (cur in lst)
+            {
+                local group;
+                local displayedCur;
+                
+                /* presume we'll display this item */
+                displayedCur = true;
+                
+                /*
+                 *   Figure out how to show this item: if it's in the
+                 *   singles list, show it as a single item; if it's in
+                 *   the group list, show its group; if it's in a group
+                 *   we've previously shown, show nothing, as we showed
+                 *   the item when we showed its group.  
+                 */
+                if (singles.indexOf(cur) != nil)
+                {
+                    /*
+                     *   It's in the singles list, so show it as a single
+                     *   item.
+                     *   
+                     *   If the item has contents that we'll display in
+                     *   'tall' mode, show the item with its contents - we
+                     *   don't need to show the item separately, since it
+                     *   will provide a 'tall' list prefix showing itself.
+                     *   Otherwise, show the item singly.  
+                     */
+                    if ((options & ListTall) != 0
+                        && (options & ListRecurse) != 0
+                        && contentsListed(cur)
+                        && getListedContents(cur, infoTab) != [])
+                    {
+                        /* show the item with its contents */
+                        showContentsList(pov, cur, origOptions | ListContents,
+                                         indent, infoTab);
+                    }
+                    else
+                    {
+                        /* show the list indent if necessary */
+                        showListIndent(itemOptions, indent);
+
+                        /* show the item */
+                        showListItem(cur, itemOptions, pov, infoTab);
+
+                        /* 
+                         *   if we're in wide recursive mode, show the
+                         *   item's contents as an in-line parenthetical 
+                         */
+                        if ((options & ListTall) == 0
+                            && (options & ListRecurse) != 0
+                            && contentsListed(cur)
+                            && !contentsListedSeparately(cur))
+                        {
+                            /* show the item's in-line contents */
+                            showInlineContentsList(pov, cur,
+                                origOptions | ListContents,
+                                indent + 1, infoTab);
+                        }
+                    }
+                }
+                else if ((group = groups.valWhich(
+                    {g: groupTab[g].indexOf(cur) != nil})) != nil)
+                {
+                    /* show the list indent if necessary */
+                    showListIndent(itemOptions, indent);
+
+                    /* we found the item in a group, so show its group */
+                    group.showGroupList(pov, self, groupTab[group],
+                                        groupOptions, indent, infoTab);
+
+                    /* 
+                     *   Forget this group - we only need to show each
+                     *   group once, since the group shows every item it
+                     *   contains.  Since we'll encounter the groups other
+                     *   members as we continue to scan the main list, we
+                     *   want to make sure we don't show the group again
+                     *   when we reach the other items.  
+                     */
+                    groups.removeElement(group);
+                }
+                else
+                {
+                    /* 
+                     *   We didn't find the item in the singles list or in
+                     *   a group - it must be part of a group that we
+                     *   already showed previously, so we don't need to
+                     *   show it again now.  Simply make a note that we
+                     *   didn't display it.  
+                     */
+                    displayedCur = nil;
+                }
+
+                /* if we displayed the item, show a suitable separator */
+                if (displayedCur)
+                {
+                    /* count another list entry displayed */
+                    ++dispCount;
+
+                    /* show an appropriate separator */
+                    showListSeparator(itemOptions, dispCount, listCount);
+                }
+            }
+
+            /* 
+             *   if we're in 'wide' mode, finish the listing (note that if
+             *   this is a 'tall' listing, we're already done, because a
+             *   tall listing format doesn't make provisions for anything
+             *   after the item list) 
+             */
+            if ((options & ListTall) == 0)
+            {
+                /*
+                 *   Určíme selector pro výběr tvaru slovesa v minulém čase.
+                 *   Přísudek musí být ve shodě s podměty, tj. ve shodě s
+                 *   objekty seznamu. Zde generujeme tento tvar pro objekty
+                 *   listované na šířku, tedy ve větě a to do suffixu, takže
+                 *   použijeme algoritmus pro přísudek za několikanásobným
+                 *   pomětem. Viz bod 1. na http://prirucka.ujc.cas.cz/?id=601
+                 *
+                 *   jednotné číslo:
+                 *      1 = mužský rod - tvar bez koncovky (byl)
+                 *      2 = ženský rod - koncovka 'a' (byla)
+                 *      3 = střední rod - koncovka 'o' (bylo)
+                 *   množné číslo:
+                 *      4 = muž. živ. rod, stř. j.č. - koncovka 'i' (byli)
+                 *      5 = mužský neživotný a ženský rod - koncovka 'y' (byly)
+                 *      6 = střední rod, vše množné č. - koncovka 'a' (byla)
+                 */
+            	if(itemCount > 1 || lst[1].isPlural)
+            	{
+                    /* Přednost má mužský živ., potom neživotný a ženský */
+            	    local m = 0, n = 0, o = 0;
+                    foreach(cur in lst)
+                    {
+        	        if(cur.gender == 1) m++;
+        	        if(cur.gender == 2 || cur.gender == 3) n++;
+        	        if(cur.gender == 4 && !cur.isPlural) o++;
+                    }
+            	    selector = m ? 4 : (n ? 5 : (o ? 5 : 6));
+            	}
+            	else
+                {
+                    /* Pokud je v seznamu jediný objekt, určíme podle něj. */
+            	    selector = lst[1].gender == 1 || lst[1].gender == 2 ? 1
+            	        : (lst[1].gender == 3 ? 2 : 3);
+                }
+
+                /* show the wide-mode list suffix */
+                showListSuffixWide(itemCount, pov, parent, selector);
+            }
+        }
+    }
+    /*
+     *   Kvůli změně parametrů předávaných funkcím pro výpis prefixů a postfixů
+     *   musíme upravit parametry funkce tady a v několika potomcích třídy
+     *   Lister, které jsou i s funkcemi explicitně přetížené v jazykově
+     *   nezávislé části knihovny.
+     */
+    showListPrefixWide(itemCount, pov, parent, selector) { }
+    showListPrefixTall(itemCount, pov, parent, selector) { }
+    showListSuffixWide(itemCount, pov, parent, selector) { }
+;
+
+modify plainLister
+    showListPrefixWide(itemCount, pov, parent, selector) { }
+    showListPrefixTall(itemCount, pov, parent, selector) { }
+    showListSuffixWide(itemCount, pov, parent, selector) { }
 ;
 
-/* ------------------------------------------------------------------------ */
-/*
- *   Wearable states - a wearable item can be either worn or not worn.
- */
+modify GroupSublister
+    showListPrefixWide(itemCount, pov, parent, selector) { }
+    showListPrefixTall(itemCount, pov, parent, selector) { }
+    showListSuffixWide(itemCount, pov, parent, selector) { }
+;
 
-/* "worn" */
-wornState: ThingState 'being worn'
-    /*
-     *   In listings of worn items, don't bother mentioning our 'worn'
-     *   status, as the entire list consists of items being worn - it
-     *   would be redundant to point out that the items in a list of items
-     *   being worn are being worn.
-     */
-    wornName(lst) { return nil; }
+modify ParagraphLister
+    showListPrefixWide(itemCount, pov, parent, selector) { "<.p>"; }
 ;
 
-/*
- *   "Unworn" state.  Don't bother mentioning the status of an unworn item,
- *   since this is the default for everything.  
- */
-unwornState: ThingState;
+modify InventorySublister
+    showListPrefixWide(itemCount, pov, parent, selector) { }
+    showListSuffixWide(itemCount, pov, parent, selector) { }
+;
+
+modify WearingSublister
+    showListPrefixWide(itemCount, pov, parent, selector) { }
+    showListSuffixWide(itemCount, pov, parent, selector) { }
+;
 
+modify fullScoreLister
+    showListPrefixTall(itemCount, pov, parent, selector)
+    {
+        /* showt he full score list intro message */
+        gLibMessages.showFullScorePrefix;
+    }
+;
 
 /* ------------------------------------------------------------------------ */
 /*
  *   Typographical effects output filter.  This filter looks for certain
  *   sequences in the text and converts them to typographical equivalents.
  *   Authors could simply write the HTML for the typographical markups in
  *   the first place, but it's easier to write the typewriter-like
  *   sequences and let this filter convert to HTML.
  *
  *   We perform the following conversions:
  *
  *   '---' -> &zwnbsp;&emdash;
  *.  '--' -> &zwnbsp;&endash;
  *.  sentence-ending punctuation -> same + &ensp;
  *
  *   Since this routine is called so frequently, we hard-code the
  *   replacement strings, rather than using properties, for slightly faster
  *   performance.  Since this routine is so simple, games that want to
  *   customize the replacement style should simply replace this entire
  *   routine with a new routine that applies the customizations.
  *
  *   Note that we define this filter in the English-specific part of the
  *   library, because it seems almost certain that each language will want
  *   to customize it for local conventions.
+ *
+ *   V češtině není english spacing používaný a celkově se od něj spíše
+ *   ustupuje, tak jsem ho vyhodil a zůstaly jen pomlčky.
  */
 typographicalOutputFilter: OutputFilter
     filterText(ostr, val)
     {
         /*
-         *   Look for sentence-ending punctuation, and put an 'en' space
-         *   after each occurrence.  Recognize ends of sentences even if we
-         *   have closing quotes, parentheses, or other grouping characters
-         *   following the punctuation.  Do this before the hyphen
-         *   substitutions so that we can look for ordinary hyphens rather
-         *   than all of the expanded versions.
-         */
-        val = rexReplace(eosPattern, val, '%1\u2002', ReplaceAll);
-
-        /* undo any abbreviations we mistook for sentence endings */
-        val = rexReplace(abbrevPat, val, '%1. ', ReplaceAll);
-
-        /*
          *   Replace dashes with typographical hyphens.  Note that we check
          *   for the three-hyphen sequence first, because if we did it the
          *   other way around, we'd incorrectly find the first two hyphens
          *   of each '---' sequence and replace them with an en-dash,
          *   causing us to miss the '---' sequences entirely.
          *
          *   We put a no-break marker (\uFEFF) just before each hyphen, and
          *   an okay-to-break marker (\u200B) just after, to ensure that we
          *   won't have a line break between the preceding text and the
          *   hyphen, and to indicate that a line break is specifically
          *   allowed if needed to the right of the hyphen.
          */
         val = val.findReplace('---', '\uFEFF&mdash;\u200B', ReplaceAll);
         val = val.findReplace('--',  '\uFEFF&ndash;\u200B', ReplaceAll);
+        val = rexReplace(innerQuotesPat, val, '%1‚%2‘%3', ReplaceAll);
+        val = val.findReplace('<q>',  '„', ReplaceAll);
+        val = val.findReplace('</q>',  '“', ReplaceAll);
+
+        /*
+         *   Šablona {jsi} ve třetí osobě minuého času negeneruje žádné slovo.
+         *   (Např. Mohl jsem udělat / Mohl jsi udělat / Mohl udělat) Tato
+         *   úprava odstraní vzniklou mezeru před tečkou, pokud se šablona byla
+         *   na konci věty.
+         */
+        val = val.findReplace(' . ',  '. ', ReplaceAll);
+        val = val.findReplace(' , ',  ', ', ReplaceAll);
+
+        val = val.findReplace('by jsem',  'bych', ReplaceAll);
+        val = val.findReplace('by jsi',  'bys', ReplaceAll);
+        val = val.findReplace('by jsme',  'bychom', ReplaceAll);
+        val = val.findReplace('by jste',  'byste', ReplaceAll);
+
+        val = rexReplace(bysSePat, val, 'by ses', ReplaceAll);
+        val = rexReplace(bysSiPat, val, 'by sis', ReplaceAll);
+        val = rexReplace(jsiSePat, val, 'ses', ReplaceAll);
+        val = rexReplace(jsiSiPat, val, 'sis', ReplaceAll);
+
+        /* vokalizace předložek */
+        val = val.findReplace('s mnou',  'se mnou', ReplaceAll);
+        val = val.findReplace('S mnou',  'Se mnou', ReplaceAll);
+        val = val.findReplace('k mně',  'ke mně', ReplaceAll);
+        val = val.findReplace('K mně',  'Ke mně', ReplaceAll);
 
         /* return the result */
         return val;
     }
-
-    /*
-     *   The end-of-sentence pattern.  This looks a bit complicated, but
-     *   all we're looking for is a period, exclamation point, or question
-     *   mark, optionally followed by any number of closing group marks
-     *   (right parentheses or square brackets, closing HTML tags, or
-     *   double or single quotes in either straight or curly styles), all
-     *   followed by an ordinary space.
-     *
-     *   If a lower-case letter follows the space, though, we won't
-     *   consider it a sentence ending.  This applies most commonly after
-     *   quoted passages ending with what would normally be sentence-ending
-     *   punctuation: "'Who are you?' he asked."  In these cases, the
-     *   enclosing sentence isn't ending, so we don't want the extra space.
-     *   We can tell the enclosing sentence isn't ending because a
-     *   non-capital letter follows.
-     *
-     *   Note that we specifically look only for ordinary spaces.  Any
-     *   sentence-ending punctuation that's followed by a quoted space or
-     *   any typographical space overrides this substitution.
-     */
-    eosPattern = static new RexPattern(
-        '<case>'
-        + '('
-        +   '[.!?]'
-        +   '('
-        +     '<rparen|rsquare|dquote|squote|\u2019|\u201D>'
-        +     '|<langle><^rangle>*<rangle>'
-        +   ')*'
-        + ')'
-        + ' +(?![-a-z])'
-        )
-
-    /* pattern for abbreviations that were mistaken for sentence endings */
-    abbrevPat = static new RexPattern(
-        '<nocase>%<(' + abbreviations + ')<dot>\u2002')
-
-    /* 
-     *   Common abbreviations.  These are excluded from being treated as
-     *   sentence endings when they appear with a trailing period.
-     *   
-     *   Note that abbrevPat must be rebuilt manually if you change this on
-     *   the fly - abbrevPat is static, so it picks up the initial value of
-     *   this property at start-up, and doesn't re-evaluate it while the
-     *   game is running.  
-     */
-    abbreviations = 'mr|mrs|ms|dr|prof'
+    innerQuotesPat = static new RexPattern('(<langle>q<rangle>[^<langle>'
+        + '<rangle>]*)<langle>q<rangle>([^<langle><rangle>]*)<langle>/q<rangle>'
+        + '([^<langle><rangle>]*<langle>/q<rangle>)')
+
+    bysSePat = static new RexPattern('%<(bys se)%>')
+    bysSiPat = static new RexPattern('%<(bys si)%>')
+    jsiSePat = static new RexPattern('%<(jsi se)%>')
+    jsiSiPat = static new RexPattern('%<(jsi si)%>')
 ;
 
 /* ------------------------------------------------------------------------ */
 /*
  *   The English-specific message builder.
  */
 langMessageBuilder: MessageBuilder
 
     /*
      *   The English message substitution parameter table.
      *
      *   Note that we specify two additional elements for each table entry
      *   beyond the standard language-independent complement:
      *
      *   info[4] = reflexive property - this is the property to invoke
      *   when the parameter is used reflexively (in other words, its
      *   target object is the same as the most recent target object used
      *   in the nominative case).  If this is nil, the parameter has no
      *   reflexive form.
      *
      *   info[5] = true if this is a nominative usage, nil if not.  We use
      *   this to determine which target objects are used in the nominative
      *   case, so that we can remember those objects for subsequent
      *   reflexive usages.
+     *
+     *   Pokud v rámci parametru není určen objekt, tak se podle třetího
+     *   parametru rozhoduje, zda se použije actor a nebo předchozí objekt.
+     *   '{Kdoco dobj} těžk{ý} {je|byl[a]} těžk{ý} pro {kohočeho} těžk{ý dobj}. '
+     *   "Hrad těžký (není zadán třetí parametr, zvtahuje se tedy k předchozímu
+     *   objektu) byla (parametr {a} se implicitne vaze k actoru) těžká
+     *   (v předchozím parametru se zapamatoval actor jako objekt) pro Sally
+     *   příliš těžký (explicitně jsem zvolil objekt) na zdvihnutí."
      */
     paramList_ =
     [
-        /* parameters that imply the actor as the target object */
-        ['you/he', &theName, 'actor', nil, true],
-        ['you/she', &theName, 'actor', nil, true],
-        ['you\'re/he\'s', &itIsContraction, 'actor', nil, true],
-        ['you\'re/she\'s', &itIsContraction, 'actor', nil, true],
-        ['you\'re', &itIsContraction, 'actor', nil, true],
-        ['you/him', &theNameObj, 'actor', &itReflexive, nil],
-        ['you/her', &theNameObj, 'actor', &itReflexive, nil],
-        ['your/her', &theNamePossAdj, 'actor', nil, nil],
-        ['your/his', &theNamePossAdj, 'actor', nil, nil],
-        ['your', &theNamePossAdj, 'actor', nil, nil],
-        ['yours/hers', &theNamePossNoun, 'actor', nil, nil],
-        ['yours/his', &theNamePossNoun, 'actor', nil, nil],
-        ['yours', &theNamePossNoun, 'actor', nil, nil],
-        ['yourself/himself', &itReflexive, 'actor', nil, nil],
-        ['yourself/herself', &itReflexive, 'actor', nil, nil],
-        ['yourself', &itReflexive, 'actor', nil, nil],
-
-        /* parameters that don't imply any target object */
-        ['the/he', &theName, nil, nil, true],
-        ['the/she', &theName, nil, nil, true],
-        ['the/him', &theNameObj, nil, &itReflexive, nil],
-        ['the/her', &theNameObj, nil, &itReflexive, nil],
-        ['the\'s/her', &theNamePossAdj, nil, &itPossAdj, nil],
-        ['the\'s/hers', &theNamePossNoun, nil, &itPossNoun, nil],
-
-        /*
-         *  Verb 's' endings.  In most cases, you should use 's/d', 's/ed',
-         *  or 's/?ed' rather than 's', except in places where you know you
-         *  will never need the past tense form, because 's' doesn't handle
-         *  the past tense.  Don't use 's/?ed' with a literal question
-         *  mark; put a consonant in place of the question mark instead.
-         */
-        ['s', &verbEndingS, nil, nil, true],
-        ['s/d', &verbEndingSD, nil, nil, true],
-        ['s/ed', &verbEndingSEd, nil, nil, true],
-        ['s/?ed', &verbEndingSMessageBuilder_, nil, nil, true],
-
-        ['es', &verbEndingEs, nil, nil, true],
-        ['es/ed', &verbEndingEs, nil, nil, true],
-        ['ies', &verbEndingIes, nil, nil, true],
-        ['ies/ied', &verbEndingIes, nil, nil, true],
-        ['is', &verbToBe, nil, nil, true],
-        ['are', &verbToBe, nil, nil, true],
-        ['was', &verbWas, nil, nil, true],
-        ['were', &verbWas, nil, nil, true],
-        ['has', &verbToHave, nil, nil, true],
-        ['have', &verbToHave, nil, nil, true],
-        ['does', &verbToDo, nil, nil, true],
-        ['do', &verbToDo, nil, nil, true],
-        ['goes', &verbToGo, nil, nil, true],
-        ['go', &verbToGo, nil, nil, true],
-        ['comes', &verbToCome, nil, nil, true],
-        ['come', &verbToCome, nil, nil, true],
-        ['leaves', &verbToLeave, nil, nil, true],
-        ['leave', &verbToLeave, nil, nil, true],
-        ['sees', &verbToSee, nil, nil, true],
-        ['see', &verbToSee, nil, nil, true],
-        ['says', &verbToSay, nil, nil, true],
-        ['say', &verbToSay, nil, nil, true],
-        ['must', &verbMust, nil, nil, true],
-        ['can', &verbCan, nil, nil, true],
-        ['cannot', &verbCannot, nil, nil, true],
-        ['can\'t', &verbCant, nil, nil, true],
-        ['will', &verbWill, nil, nil, true],
-        ['won\'t', &verbWont, nil, nil, true],
-        ['a/he', &aName, nil, nil, true],
-        ['an/he', &aName, nil, nil, true],
-        ['a/she', &aName, nil, nil, true],
-        ['an/she', &aName, nil, nil, true],
-        ['a/him', &aNameObj, nil, &itReflexive, nil],
-        ['an/him', &aNameObj, nil, &itReflexive, nil],
-        ['a/her', &aNameObj, nil, &itReflexive, nil],
-        ['an/her', &aNameObj, nil, &itReflexive, nil],
-        ['it/he', &itNom, nil, nil, true],
-        ['it/she', &itNom, nil, nil, true],
-        ['it/him', &itObj, nil, &itReflexive, nil],
-        ['it/her', &itObj, nil, &itReflexive, nil],
-
-        /*
-         *   note that we don't have its/his, because that leaves
-         *   ambiguous whether we want an adjective or noun form - so we
-         *   only use the feminine pronouns with these, to make the
-         *   meaning unambiguous
-         */
-        ['its/her', &itPossAdj, nil, nil, nil],
-        ['its/hers', &itPossNoun, nil, nil, nil],
-
-        ['it\'s/he\'s', &itIsContraction, nil, nil, true],
-        ['it\'s/she\'s', &itIsContraction, nil, nil, true],
-        ['it\'s', &itIsContraction, nil, nil, true],
-        ['that/he', &thatNom, nil, nil, true],
-        ['that/she', &thatNom, nil, nil, true],
-        ['that/him', &thatObj, nil, &itReflexive, nil],
-        ['that/her', &thatObj, nil, &itReflexive, nil],
-        ['that\'s', &thatIsContraction, nil, nil, true],
-        ['itself', &itReflexive, nil, nil, nil],
-        ['itself/himself', &itReflexive, nil, nil, nil],
-        ['itself/herself', &itReflexive, nil, nil, nil],
+        /* podstatná jména */
+        ['kdoco', &name, 'actor', nil, true],
+        ['kohočeho', &nameKohoCeho, 'actor', nil, nil],
+        ['komučemu', &nameKomuCemu, 'actor', nil, nil],
+        ['kohoco', &nameKohoCo, 'actor', nil, nil],
+        ['komčem', &nameKomCem, 'actor', nil, nil],
+        ['kýmčím', &nameKymCim, 'actor', nil, nil],
+
+        /* přídavná jména */
+        ['ý', &pridavneJmenoMlady, nil, nil, nil],
+        ['ému', &pridavneJmenoMlademu, nil, nil, nil],
+        ['ém', &pridavneJmenoMladem, nil, nil, nil],
+        ['ým', &pridavneJmenoMladym, nil, nil, nil],
+
+        /* osobní zájmena */
+        ['ty', &zajmenoTy, 'actor', nil, nil],
+
+        ['tebe/jí', &zajmenoTebe2J, 'actor', nil, nil],
+        ['tebe/ní', &zajmenoTebe2N, 'actor', nil, nil],
+        ['tě/jí', &zajmenoTe2J, 'actor', nil, nil],
+        ['tě/ní', &zajmenoTe2N, 'actor', nil, nil],
+
+        ['tobě/jemu', &zajmenoTobe3J, 'actor', nil, nil],
+        ['tobě/němu', &zajmenoTobe3N, 'actor', nil, nil],
+        ['ti/jí', &zajmenoTiJ, 'actor', nil, nil],
+        ['ti/ní', &zajmenoTiN, 'actor', nil, nil],
+
+        ['tebe/ji', &zajmenoTebe4J, 'actor', nil, nil],
+        ['tebe/ni', &zajmenoTebe4N, 'actor', nil, nil],
+        ['tě/ji', &zajmenoTe4J, 'actor', nil, nil],
+        ['tě/ni', &zajmenoTe4N, 'actor', nil, nil],
+
+        ['tobě/něm', &zajmenoTobe6, 'actor', nil, nil],
+
+        ['tebou/jím', &zajmenoTebouJ, 'actor', nil, nil],
+        ['tebou/ním', &zajmenoTebouN, 'actor', nil, nil],
+
+        ['on/ona', &zajmenoTy, nil, nil, nil],
+
+        ['jeho/jí', &zajmenoTebe2J, nil, nil, nil],
+        ['něho/ní', &zajmenoTebe2N, nil, nil, nil],
+        ['ho/jí', &zajmenoTe2J, nil, nil, nil],
+        ['ho/ní', &zajmenoTe2N, nil, nil, nil],
+
+        ['jemu/jí', &zajmenoTobe3J, nil, nil, nil],
+        ['němu/ní', &zajmenoTobe3N, nil, nil, nil],
+        ['mu/jí', &zajmenoTiJ, nil, nil, nil],
+        ['mu/ní', &zajmenoTiN, nil, nil, nil],
+
+        ['jeho/ji', &zajmenoTebe4J, nil, nil, nil],
+        ['něho/ni', &zajmenoTebe4N, nil, nil, nil],
+        ['ho/ji', &zajmenoTe4J, nil, nil, nil],
+        ['ho/ni', &zajmenoTe4N, nil, nil, nil],
+        ['jej/ji', &zajmenoJej4J, nil, nil, nil],
+        ['něj/ni', &zajmenoJej4N, nil, nil, nil],
+
+        ['něm/ní', &zajmenoTobe6, nil, nil, nil],
+
+        ['jím/jí', &zajmenoTebouJ, nil, nil, nil],
+        ['ním/ní', &zajmenoTebouN, nil, nil, nil],
+
+        /* přivlastňovací zájmena */
+        ['tvůj', &zajmenoTvuj, 'actor', nil, nil],
+        ['tvoje', &zajmenoTvoje, 'actor', nil, nil],
+        ['tvoji', &zajmenoTvoji, 'actor', nil, nil],
+
+        /* ukazovací zájmena */
+        ['sám', &zajmenoSam, 'actor', nil, nil],
+
+        /* sloveso být s osobním zvratným zájmenem v minulém čase */
+        ['ses', &spojeniSes, 'actor', nil, nil],
+        ['sis', &spojeniSis, 'actor', nil, nil],
+
+        /* slovesa pravidelná */
+        ['eš', &slovesoEs, 'actor', nil, nil],
+        ['neš', &slovesoNes, 'actor', nil, nil],
+        ['ješ', &slovesoJes, 'actor', nil, nil],
+        ['íš', &slovesoIs, 'actor', nil, nil],
+        ['áš', &slovesoAs, 'actor', nil, nil],
+
+        /* Koncovka pravidelných sloves v minulém čase. */
+        ['a', &slovesoMin, 'actor', nil, nil],
+
+        /* některá nepravidelná slovesa */
+        ['je', &slovesoJe, nil, nil, nil],
+        ['není', &slovesoNeni, nil, nil, nil],
+        ['jsi', &slovesoBytProMinulyCas, 'actor', nil, nil],
+        ['jsi/je', &slovesoNebyt, 'actor', nil, nil],
+        ['nejsi/není', &slovesoNebyt, 'actor', nil, nil],
+        ['bys', &slovesoBytPodmin, 'actor', nil, nil],
+        ['chceš', &slovesoChces, 'actor', nil, nil],
+        ['šel', &slovesoSel, 'actor', nil, nil],
 
         /* default preposition for standing in/on something */
-        ['on', &actorInName, nil, nil, nil],
-        ['in', &actorInName, nil, nil, nil],
-        ['outof', &actorOutOfName, nil, nil, nil],
-        ['offof', &actorOutOfName, nil, nil, nil],
-        ['onto', &actorIntoName, nil, nil, nil],
-        ['into', &actorIntoName, nil, nil, nil],
+        ['v', &objInName, nil, nil, nil],
+        ['do', &objIntoName, nil, nil, nil],
+        ['z', &objOutOfName, nil, nil, nil],
 
         /*
          *   The special invisible subject marker - this can be used to
          *   mark the subject in sentences that vary from the
          *   subject-verb-object structure that most English sentences
          *   take.  The usual SVO structure allows the message builder to
          *   see the subject first in most sentences naturally, but in
          *   unusual sentence forms it is sometimes useful to be able to
          *   mark the subject explicitly.  This doesn't actually result in
          *   any output; it's purely for marking the subject for our
          *   internal book-keeping.
          *
          *   (The main reason the message builder wants to know the subject
          *   in the first place is so that it can use a reflexive pronoun
          *   if the same object ends up being used as a direct or indirect
          *   object: "you can't open yourself" rather than "you can't open
          *   you.")
          */
         ['subj', &dummyName, nil, nil, true]
     ]
 
     /*
      *   Add a hook to the generateMessage method, which we use to
      *   pre-process the source string before expanding the substitution
      *   parameters.
      */
     generateMessage(orig) { return inherited(processOrig(orig)); }
 
     /*
      *   Pre-process a source string containing substitution parameters,
      *   before generating the expanded message from it.
      *
      *   We use this hook to implement the special tense-switching syntax
      *   {<present>|<past>}.  Although it superficially looks like an
      *   ordinary substitution parameter, we actually can't use the normal
      *   parameter substitution framework for that, because we want to
      *   allow the <present> and <past> substrings themselves to contain
      *   substitution parameters, and the normal framework doesn't allow
      *   for recursive substitution.
      *
      *   We simply replace every sequence of the form {<present>|<past>}
      *   with either <present> or <past>, depending on the current
      *   narrative tense.  We then substitute braces for square brackets in
      *   the resulting string.  This allows treating every bracketed tag
      *   inside the tense-switching sequence as a regular substitution
      *   parameter.
      *
      *   For example, the sequence "{take[s]|took}" appearing in the
      *   message string would be replaced with "take{s}" if the current
      *   narrative tense is present, and would be replaced with "took" if
      *   the current narrative tense is past.  The string "take{s}", if
      *   selected, would in turn be expanded to either "take" or "takes",
      *   depending on the grammatical person of the subject, as per the
      *   regular substitution mechanism.
      */
     processOrig(str)
     {
         local idx = 1;
         local len;
         local match;
         local replStr;
 
         /*
          *   Keep searching the string until we run out of character
          *   sequences with a special meaning (specifically, we look for
          *   substrings enclosed in braces, and stuttered opening braces).
          */
         for (;;)
         {
             /*
              *   Find the next special sequence.
              */
             match = rexSearch(patSpecial, str, idx);
 
             /*
              *   If there are no more special sequence, we're done
              *   pre-processing the string.
              */
             if (match == nil) break;
 
             /*
              *   Remember the starting index and length of the special
              *   sequence.
              */
             idx = match[1];
             len = match[2];
 
             /*
              *   Check if this special sequence matches our tense-switching
              *   syntax.
              */
             if (nil == rexMatch(patTenseSwitching, str, idx))
             {
                 /*
                  *   It doesn't, so forget about it and continue searching
                  *   from the end of this special sequence.
                  */
                 idx += len;
                 continue;
             }
 
             /*
              *   Extract either the first or the second embedded string,
              *   depending on the current narrative tense.
              */
             match = rexGroup(tSel(1, 2));
             replStr = match[3];
 
             /*
              *   Convert all square brackets to braces in the extracted
              *   string.
              */
             replStr = replStr.findReplace('[', '{', ReplaceAll);
             replStr = replStr.findReplace(']', '}', ReplaceAll);
 
             /*
              *   In the original string, replace the tense-switching
              *   sequence with the extracted string.
              */
             str = str.substr(1, idx - 1) + replStr + str.substr(idx + len);
 
             /*
              *   Move the index at the end of the substituted string.
              */
             idx += match[2];
         }
 
         /*
          *   We're done - return the result.
          */
         return str;
     }
 
     /*
      *   Pre-compiled regular expression pattern matching any sequence with
      *   a special meaning in a message string.
      *
      *   We match either a stuttered opening brace, or a single opening
      *   brace followed by any sequence of characters that doesn't contain
      *   a closing brace followed by a closing brace.
      */
     patSpecial = static new RexPattern
         ('<lbrace><lbrace>|<lbrace>(?!<lbrace>)((?:<^rbrace>)*)<rbrace>')
 
     /*
      *   Pre-compiled regular expression pattern matching our special
      *   tense-switching syntax.
      *
      *   We match a single opening brace, followed by any sequence of
      *   characters that doesn't contain a closing brace or a vertical bar,
      *   followed by a vertical bar, followed by any sequence of characters
      *   that doesn't contain a closing brace or a vertical bar, followed
      *   by a closing brace.
      */
     patTenseSwitching = static new RexPattern
     (
         '<lbrace>(?!<lbrace>)((?:<^rbrace|vbar>)*)<vbar>'
                           + '((?:<^rbrace|vbar>)*)<rbrace>'
     )
 
     /*
      *   The most recent target object used in the nominative case.  We
      *   note this so that we can supply reflexive mappings when the same
      *   object is re-used in the objective case.  This allows us to map
      *   things like "you can't take you" to the better-sounding "you
      *   can't take yourself".
      */
     lastSubject_ = nil
 
     /* the parameter name of the last subject ('dobj', 'actor', etc) */
     lastSubjectName_ = nil
 
     /*
      *   Get the target object property mapping.  If the target object is
      *   the same as the most recent subject object (i.e., the last object
      *   used in the nominative case), and this parameter has a reflexive
      *   form property, we'll return the reflexive form property.
      *   Otherwise, we'll return the standard property mapping.
      *
      *   Also, if there was an exclamation mark at the end of any word in
      *   the tag, we'll return a property returning a fixed-tense form of
      *   the property for the tag.
      */
     getTargetProp(targetObj, paramObj, info)
     {
         local ret;
 
         /*
          *   If this target object matches the last subject, and we have a
          *   reflexive rendering, return the property for the reflexive
          *   rendering.
          *
          *   Only use the reflexive rendering if the parameter name is
          *   different - if the parameter name is the same, then presumably
          *   the message will have been written with a reflexive pronoun or
          *   not, exactly as the author wants it.  When the author knows
          *   going in that these two objects are structurally the same,
          *   they want the exact usage they wrote.
          */
         if (targetObj == lastSubject_
             && paramObj != lastSubjectName_
             && info[4] != nil)
         {
             /* use the reflexive rendering */
             ret = info[4];
         }
         else
         {
             /* no special handling; inherit the default handling */
             ret = inherited(targetObj, paramObj, info);
         }
 
         /* if this is a nominative usage, note it as the last subject */
         if (info[5])
         {
             lastSubject_ = targetObj;
             lastSubjectName_ = paramObj;
         }
 
         /*
          *   If there was an exclamation mark at the end of any word in the
          *   parameter string (which we remember via the fixedTenseProp_
          *   property), store the original target property in
          *   fixedTenseProp_ and use &propWithPresentMessageBuilder_ as the
          *   target property instead.  propWithPresentMessageBuilder_ acts
          *   as a wrapper for the original target property, which it
          *   invokes after temporarily switching to the present tense.
          */
         if (fixedTenseProp_)
         {
             fixedTenseProp_ = ret;
             ret = &propWithPresentMessageBuilder_;
         }
 
         /* return the result */
         return ret;
     }
 
     /* end-of-sentence match pattern */
     patEndOfSentence = static new RexPattern('[.;:!?]<^alphanum>')
 
     /*
      *   Process result text.
      */
     processResult(txt)
     {
         /*
          *   If the text contains any sentence-ending punctuation, reset
          *   our internal memory of the subject of the sentence.  We
          *   consider the sentence to end with a period, semicolon, colon,
          *   question mark, or exclamation point followed by anything
          *   other than an alpha-numeric.  (We require the secondary
          *   character so that we don't confuse things like "3:00" or
          *   "7.5" to contain sentence-ending punctuation.)
          */
         if (rexSearch(patEndOfSentence, txt) != nil)
         {
             /*
              *   we have a sentence ending in this run of text, so any
              *   saved subject object will no longer apply after this text
              *   - forget our subject object
              */
             lastSubject_ = nil;
             lastSubjectName_ = nil;
         }
 
         /* return the inherited processing */
         return inherited(txt);
     }
 
     /* some pre-compiled search patterns we use a lot */
     patIdObjSlashIdApostS = static new RexPattern(
         '(<^space>+)(<space>+<^space>+)\'s(/<^space>+)$')
     patIdObjApostS = static new RexPattern(
         '(?!<^space>+\'s<space>)(<^space>+)(<space>+<^space>+)\'s$')
     patParamWithExclam = static new RexPattern('.*(!)(?:<space>.*|/.*|$)')
-    patSSlashLetterEd = static new RexPattern(
-        's/(<alpha>ed)$|(<alpha>ed)/s$')
 
     /*
      *   Rewrite a parameter string for a language-specific syntax
      *   extension.
      *
      *   For English, we'll handle the possessive apostrophe-s suffix
      *   specially, by allowing the apostrophe-s to be appended to the
      *   target object name.  If we find an apostrophe-s on the target
      *   object name, we'll move it to the preceding identifier name:
      *
      *   the dobj's -> the's dobj
      *.  the dobj's/he -> the's dobj/he
      *.  he/the dobj's -> he/the's dobj
      *
      *   We also use this method to check for the presence of an
      *   exclamation mark at the end of any word in the parameter string
      *   (triggering the fixed-tense handling), and to detect a parameter
      *   string matching the {s/?ed} syntax, where ? is any letter, and
      *   rewrite it literally as 's/?ed' literally.
      */
     langRewriteParam(paramStr)
     {
         /*
          *   Check for an exclamation mark at the end of any word in the
          *   parameter string, and remember the result of the test.
          */
         local exclam = rexMatch(patParamWithExclam, paramStr);
         fixedTenseProp_ = exclam;
 
         /*
          *   Remove the exclamation mark, if any.
          */
         if (exclam)
         {
             local exclamInd = rexGroup(1)[1];
             paramStr = paramStr.substr(1, exclamInd - 1)
                        + paramStr.substr(exclamInd + 1);
         }
 
         /* look for "id obj's" and "id1 obj's/id2" */
         if (rexMatch(patIdObjSlashIdApostS, paramStr) != nil)
         {
             /* rewrite with the "'s" moved to the preceding parameter name */
             paramStr = rexGroup(1)[3] + '\'s'
                        + rexGroup(2)[3] + rexGroup(3)[3];
         }
         else if (rexMatch(patIdObjApostS, paramStr) != nil)
         {
             /* rewrite with the "'s" moved to the preceding parameter name */
             paramStr = rexGroup(1)[3] + '\'s' + rexGroup(2)[3];
         }
 
-        /*
-         *   Check if this parameter matches the {s/?ed} or {?ed/s} syntax.
-         */
-        if (rexMatch(patSSlashLetterEd, paramStr))
-        {
-            /*
-             *   It does - remember the past verb ending, and rewrite the
-             *   parameter literally as 's/?ed'.
-             */
-            pastEnding_ = rexGroup(1)[3];
-            paramStr = 's/?ed';
-        }
-
         /* return our (possibly modified) result */
         return paramStr;
     }
 
     /*
-     *   This property is used to temporarily store the past-tense ending
-     *   of a verb to be displayed by Thing.verbEndingSMessageBuilder_.
-     *   It's for internal use only; game authors shouldn't have any reason
-     *   to access it directly.
-     */
-    pastEnding_ = nil
-
-    /*
      *   This property is used to temporarily store either a boolean value
      *   indicating whether the last encountered parameter string had an
      *   exclamation mark at the end of any word, or a property to be
      *   invoked by Thing.propWithPresentMessageBuilder_.  This field is
      *   for internal use only; authors shouldn't have any reason to access
      *   it directly.
      */
     fixedTenseProp_ = nil
 ;
 
 
 /* ------------------------------------------------------------------------ */
 /*
  *   Temporarily override the current narrative tense and invoke a callback
  *   function.
  */
 withTense(usePastTense, callback)
 {
     /*
      *   Remember the old value of the usePastTense flag.
      */
     local oldUsePastTense = gameMain.usePastTense;
     /*
      *   Set the new value.
      */
     gameMain.usePastTense = usePastTense;
     /*
      *   Invoke the callback (remembering the return value) and restore the
      *   usePastTense flag on our way out.
      */
     local ret;
     try { ret = callback(); }
     finally { gameMain.usePastTense = oldUsePastTense; }
     /*
      *   Return the result.
      */
     return ret;
 }
 
 
 /* ------------------------------------------------------------------------ */
 /*
  *   Functions for spelling out numbers.  These functions take a numeric
  *   value as input, and return a string with the number spelled out as
  *   words in English.  For example, given the number 52, we'd return a
  *   string like 'fifty-two'.
  *
  *   These functions obviously have language-specific implementations.
  *   Note also that even their interfaces might vary by language.  Some
  *   languages might need additional information in the interface; for
  *   example, some languages might need to know the grammatical context
  *   (such as part of speech, case, or gender) of the result.
  *
  *   Note that some of the spellIntXxx flags might not be meaningful in all
  *   languages, because most of the flags are by their very nature
  *   associated with language-specific idioms.  Translations are free to
  *   ignore flags that indicate variations with no local equivalent, and to
  *   add their own language-specific flags as needed.
  */
 
 /*
  *   Spell out an integer number in words.  Returns a string with the
  *   spelled-out number.
  *
  *   Note that this simple version of the function uses the default
  *   options.  If you want to specify non-default options with the
  *   SpellIntXxx flags, you can call spellIntExt().
  */
-spellInt(val)
+spellInt(val, gender)
 {
-    return spellIntExt(val, 0);
+    return spellIntExt(val, gender, 0);
 }
 
 /*
  *   Spell out an integer number in words, but only if it's below the given
  *   threshold.  It's often awkward in prose to spell out large numbers,
  *   but exactly what constitutes a large number depends on context, so
  *   this routine lets the caller specify the threshold.
  *   
  *   If the absolute value of val is less than (not equal to) the threshold
  *   value, we'll return a string with the number spelled out.  If the
  *   absolute value is greater than or equal to the threshold value, we'll
  *   return a string representing the number in decimal digits.  
  */
-spellIntBelow(val, threshold)
+spellIntBelow(val, gender, threshold)
 {
-    return spellIntBelowExt(val, threshold, 0, 0);
+    return spellIntBelowExt(val, gender, threshold, 0, 0);
 }
 
 /*
  *   Spell out an integer number in words if it's below a threshold, using
  *   the spellIntXxx flags given in spellFlags to control the spelled-out
  *   format, and using the DigitFormatXxx flags in digitFlags to control
  *   the digit format.  
  */
-spellIntBelowExt(val, threshold, spellFlags, digitFlags)
+spellIntBelowExt(val, gender, threshold, spellFlags, digitFlags)
 {
     local absval;
 
     /* compute the absolute value */
     absval = (val < 0 ? -val : val);
 
     /* check the value to see whether to spell it or write it as digits */
     if (absval < threshold)
     {
         /* it's below the threshold - spell it out in words */
-        return spellIntExt(val, spellFlags);
+        return spellIntExt(val, gender, spellFlags);
     }
     else
     {
         /* it's not below the threshold - write it as digits */
         return intToDecimal(val, digitFlags);
     }
 }
 
 /*
  *   Format a number as a string of decimal digits.  The DigitFormatXxx
  *   flags specify how the number is to be formatted.`
  */
 intToDecimal(val, flags)
 {
     local str;
     local sep;
 
     /* perform the basic conversion */
     str = toString(val);
 
     /* add group separators as needed */
     if ((flags & DigitFormatGroupComma) != 0)
     {
         /* explicitly use a comma as a separator */
         sep = ',';
     }
     else if ((flags & DigitFormatGroupPeriod) != 0)
     {
         /* explicitly use a period as a separator */
         sep = '.';
     }
     else if ((flags & DigitFormatGroupSep) != 0)
     {
         /* use the current languageGlobals separator */
         sep = languageGlobals.digitGroupSeparator;
     }
     else
     {
         /* no separator */
         sep = nil;
     }
 
     /* if there's a separator, add it in */
     if (sep != nil)
     {
         local i;
         local len;
 
         /*
          *   Insert the separator before each group of three digits.
          *   Start at the right end of the string and work left: peel off
          *   the last three digits and insert a comma.  Then, move back
          *   four characters through the string - another three-digit
          *   group, plus the comma we inserted - and repeat.  Keep going
          *   until the amount we'd want to peel off the end is as long or
          *   longer than the entire remaining string.
          */
         for (i = 3, len = str.length() ; len > i ; i += 4)
         {
             /* insert this comma */
             str = str.substr(1, len - i) + sep + str.substr(len - i + 1);
 
             /* note the new length */
             len = str.length();
         }
     }
 
     /* return the result */
     return str;
 }
 
 /*
  *   Spell out an integer number - "extended" interface with flags.  The
  *   "flags" argument is a (bitwise-OR'd) combination of SpellIntXxx
  *   values, specifying the desired format of the result.
  */
-spellIntExt(val, flags)
+spellIntExt(val, gender, flags)
 {
     local str;
     local trailingSpace;
     local needAnd;
-    local powers = [1000000000, ' billion ',
-                    1000000,    ' million ',
-                    1000,       ' thousand ',
-                    100,        ' hundred '];
+    local jednicka = nil;
+    local powers = [1000000000, 3, ' miliarda ', ' miliardy ', ' miliardy ', ' miliard ', 
+                    1000000,    2, ' milión ', ' milióny ', ' milióny ', ' miliónů ', 
+                    1000,       2, ' tisíc ', ' tisíce ', ' tisíce ', ' tisíc ',
+                    100,        4, ' sto ', ' stě ', ' sta ', ' set ' ];
 
     /* start with an empty string */
     str = '';
     trailingSpace = nil;
     needAnd = nil;
 
     /* if it's zero, it's a special case */
     if (val == 0)
-        return 'zero';
+        return 'nula';
 
     /*
      *   if the number is negative, note it in the string, and use the
      *   absolute value
      */
     if (val < 0)
     {
-        str = 'negative ';
+        str = 'mínus ';
         val = -val;
     }
 
+    /* Pokud je to jednička, povolíme úpravy ohledně skloňování. */
+    if (val == 1) jednicka = true;
+
     /* do each named power of ten */
-    for (local i = 1 ; val >= 100 && i <= powers.length() ; i += 2)
+    for (local i = 1 ; val >= 100 && i <= powers.length() ; i += 6)
     {
         /*
          *   if we're in teen-hundreds mode, do the teen-hundreds - this
          *   only works for values from 1,100 to 9,999, since a number like
          *   12,000 doesn't work this way - 'one hundred twenty hundred' is
          *   no good 
+         *
+         *   V češtině je zvykem jít jen do devatenácti set.
          */
         if ((flags & SpellIntTeenHundreds) != 0
-            && val >= 1100 && val < 10000)
+            && val >= 1100 && val < 2000)
         {
             /* if desired, add a comma if there was a prior power group */
             if (needAnd && (flags & SpellIntCommas) != 0)
                 str = str.substr(1, str.length() - 1) + ', ';
 
             /* spell it out as a number of hundreds */
-            str += spellIntExt(val / 100, flags) + ' hundred ';
+            str += spellIntExt(val / 100, gender, flags) + ' set ';
 
             /* take off the hundreds */
             val %= 100;
 
             /* note the trailing space */
             trailingSpace = true;
 
             /* we have something to put an 'and' after, if desired */
             needAnd = true;
 
             /*
              *   whatever's left is below 100 now, so there's no need to
              *   keep scanning the big powers of ten
              */
             break;
         }
 
         /* if we have something in this power range, apply it */
         if (val >= powers[i])
         {
             /* if desired, add a comma if there was a prior power group */
             if (needAnd && (flags & SpellIntCommas) != 0)
                 str = str.substr(1, str.length() - 1) + ', ';
 
             /* add the number of multiples of this power and the power name */
-            str += spellIntExt(val / powers[i], flags) + powers[i+1];
+            local num = val / powers[i];
+            if(num != 1) str += spellIntExt(num, powers[i + 1], flags);
+    	    str += powers[i + (num >= 5 ? 5 : num >= 3 ? 4 : num == 2 ? 3
+    	        : 2)].substr(num == 1 ? 2 : 1);
 
             /* take it out of the remaining value */
             val %= powers[i];
 
             /*
              *   note that we have a trailing space in the string (all of
              *   the power-of-ten names have a trailing space, to make it
              *   easy to tack on the remainder of the value)
              */
             trailingSpace = true;
 
             /* we have something to put an 'and' after, if one is desired */
             needAnd = true;
         }
     }
 
     /*
      *   if we have anything left, and we have written something so far,
      *   and the caller wanted an 'and' before the tens part, add the
      *   'and'
      */
     if ((flags & SpellIntAndTens) != 0
         && needAnd
         && val != 0)
     {
         /* add the 'and' */
-        str += 'and ';
+        str += 'a ';
         trailingSpace = true;
     }
 
     /* do the tens */
     if (val >= 20)
     {
         /* anything above the teens is nice and regular */
-        str += ['twenty', 'thirty', 'forty', 'fifty', 'sixty',
-                'seventy', 'eighty', 'ninety'][val/10 - 1];
+        str += ['dvacet', 'třicet', 'čtyřicet', 'padesát', 'šedesát',
+                'sedmdesát', 'osmdesát', 'devadesát'][val/10 - 1];
         val %= 10;
 
         /* if it's non-zero, we'll add the units, so add a hyphen */
         if (val != 0)
-            str += '-';
+            str += ' ';
 
         /* we no longer have a trailing space in the string */
         trailingSpace = nil;
+
+        /* Přes dvacítku už spadnem do ženského rodu. */
+        gender = 3;
     }
     else if (val >= 10)
     {
         /* we have a teen */
-        str += ['ten', 'eleven', 'twelve', 'thirteen', 'fourteen',
-                'fifteen', 'sixteen', 'seventeen', 'eighteen',
-                'nineteen'][val - 9];
+        str += ['deset', 'jedenáct', 'dvanáct', 'třináct', 'čtrnáct',
+                'patnáct', 'šestnáct', 'sedmnáct', 'osmnáct',
+                'devatenáct'][val - 9];
 
         /* we've finished with the number */
         val = 0;
 
         /* there's no trailing space */
         trailingSpace = nil;
     }
 
     /* if we have a units value, add it */
     if (val != 0)
     {
         /* add the units name */
-        str += ['one', 'two', 'three', 'four', 'five',
-                'six', 'seven', 'eight', 'nine'][val];
+        local nums = ['jeden', 'dva', 'tři', 'čtyři', 'pět', 'šest', 'sedm',
+            'osm', 'devět', 'jeden', 'dva', 'tři', 'čtyři', 'pět', 'šest',
+            'sedm', 'osm', 'devět', 'jedna', 'dvě', 'tři', 'čtyři', 'pět',
+            'šest', 'sedm', 'osm', 'devět', 'jedno', 'dvě', 'tři', 'čtyři',
+            'pět', 'šest', 'sedm', 'osm', 'devět'];
+
+        /* Ve čtvrtém pádu měníme tvar pro 1. */
+        if(flags & SpellIntKohoCo && jednicka)
+        {
+            nums[1] = 'jednoho';
+            nums[19] = 'jednu';
+        }
+        str += nums[val + (gender - 1) * 9];
 
         /* we have no trailing space now */
         trailingSpace = nil;
     }
 
     /* if there's a trailing space, remove it */
     if (trailingSpace)
         str = str.substr(1, str.length() - 1);
 
     /* return the string */
     return str;
 }
 
 /*
  *   Return a string giving the numeric ordinal representation of a number:
  *   1st, 2nd, 3rd, 4th, etc.  
  */
 intOrdinal(n)
 {
     local s;
 
     /* start by getting the string form of the number */
     s = toString(n);
 
     /* now add the appropriate suffix */
     if (n >= 10 && n <= 19)
     {
         /* the teens all end in 'th' */
         return s + 'th';
     }
     else
     {
         /*
          *   for anything but a teen, a number whose last digit is 1
          *   always has the suffix 'st' (for 'xxx-first', as in '141st'),
          *   a number whose last digit is 2 always ends in 'nd' (for
          *   'xxx-second', as in '532nd'), a number whose last digit is 3
          *   ends in 'rd' (for 'xxx-third', as in '53rd'), and anything
          *   else ends in 'th'
          */
         switch(n % 10)
         {
         case 1:
             return s + 'st';
 
         case 2:
             return s + 'nd';
 
         case 3:
             return s + 'rd';
 
         default:
             return s + 'th';
         }
     }
 }
 
 
 /*
  *   Return a string giving a fully spelled-out ordinal form of a number:
  *   first, second, third, etc.
  */
 spellIntOrdinal(n)
 {
     return spellIntOrdinalExt(n, 0);
 }
 
 /*
  *   Return a string giving a fully spelled-out ordinal form of a number:
  *   first, second, third, etc.  This form takes the same flag values as
  *   spellIntExt().
  */
 spellIntOrdinalExt(n, flags)
 {
     local s;
 
     /* get the spelled-out form of the number itself */
-    s = spellIntExt(n, flags);
+    /* TODO: tady davam ctyrku prozatimne */
+    s = spellIntExt(n, 4, flags);
 
     /*
      *   If the number ends in 'one', change the ending to 'first'; 'two'
      *   becomes 'second'; 'three' becomes 'third'; 'five' becomes
      *   'fifth'; 'eight' becomes 'eighth'; 'nine' becomes 'ninth'.  If
      *   the number ends in 'y', change the 'y' to 'ieth'.  'Zero' becomes
      *   'zeroeth'.  For everything else, just add 'th' to the spelled-out
      *   name
      */
     if (s == 'zero')
         return 'zeroeth';
     if (s.endsWith('one'))
         return s.substr(1, s.length() - 3) + 'first';
     else if (s.endsWith('two'))
         return s.substr(1, s.length() - 3) + 'second';
     else if (s.endsWith('three'))
         return s.substr(1, s.length() - 5) + 'third';
     else if (s.endsWith('five'))
         return s.substr(1, s.length() - 4) + 'fifth';
     else if (s.endsWith('eight'))
         return s.substr(1, s.length() - 5) + 'eighth';
     else if (s.endsWith('nine'))
         return s.substr(1, s.length() - 4) + 'ninth';
     else if (s.endsWith('y'))
         return s.substr(1, s.length() - 1) + 'ieth';
     else
         return s + 'th';
 }
 
 /* ------------------------------------------------------------------------ */
 /*
  *   Parse a spelled-out number.  This is essentially the reverse of
  *   spellInt() and related functions: we take a string that contains a
  *   spelled-out number and return the integer value.  This uses the
  *   command parser's spelled-out number rules, so we can parse anything
  *   that would be recognized as a number in a command.
  *
  *   If the string contains numerals, we'll treat it as a number in digit
  *   format: for example, if it contains '789', we'll return 789.
  *
  *   If the string doesn't parse as a number, we return nil.
  */
 parseInt(str)
 {
     try
     {
         /* tokenize the string */
         local toks = cmdTokenizer.tokenize(str);
 
         /* parse it */
         return parseIntTokens(toks);
     }
     catch (Exception exc)
     {
         /*
          *   on any exception, just return nil to indicate that we couldn't
          *   parse the string as a number
          */
         return nil;
     }
 }
 
 /*
  *   Parse a spelled-out number that's given as a token list (as returned
  *   from Tokenizer.tokenize).  If we can successfully parse the token list
  *   as a number, we'll return the integer value.  If not, we'll return
  *   nil.
  */
 parseIntTokens(toks)
 {
     try
     {
         /*
          *   if the first token contains digits, treat it as a numeric
          *   string value rather than a spelled-out number
          */
         if (toks.length() != 0
             && rexMatch('<digit>+', getTokOrig(toks[1])) != nil)
             return toInteger(getTokOrig(toks[1]));
 
         /* parse it using the spelledNumber production */
         local lst = spelledNumber.parseTokens(toks, cmdDict);
 
         /*
          *   if we got a match, return the integer value; if not, it's not
          *   parseable as a number, so return nil
          */
         return (lst.length() != 0 ? lst[1].getval() : nil);
     }
     catch (Exception exc)
     {
         /*
          *   on any exception, just return nil to indicate that it's not
          *   parseable as a number
          */
         return nil;
     }
 }
 
 
 /* ------------------------------------------------------------------------ */
 /*
  *   Additional token types for US English.
  */
 
 /* special "apostrophe-s" token */
 enum token tokApostropheS;
 
 /* special abbreviation-period token */
 enum token tokAbbrPeriod;
 
 /* special "#nnn" numeric token */
 enum token tokPoundInt;
 
 /*
  *   Command tokenizer for US English.  Other language modules should
  *   provide their own tokenizers to allow for differences in punctuation
  *   and other lexical elements.
  */
 cmdTokenizer: Tokenizer
     rules_ = static
     [
         /* skip whitespace */
         ['whitespace', new RexPattern('<Space>+'), nil, &tokCvtSkip, nil],
 
         /* certain punctuation marks */
         ['punctuation', new RexPattern('[.,;:?!]'), tokPunct, nil, nil],
 
         /*
          *   We have a special rule for spelled-out numbers from 21 to 99:
          *   when we see a 'tens' word followed by a hyphen followed by a
          *   digits word, we'll pull out the tens word, the hyphen, and
          *   the digits word as separate tokens.
          */
         ['spelled number',
          new RexPattern('<NoCase>(twenty|thirty|forty|fifty|sixty|'
                         + 'seventy|eighty|ninety)-'
                         + '(one|two|three|four|five|six|seven|eight|nine)'
                         + '(?!<AlphaNum>)'),
          tokWord, &tokCvtSpelledNumber, nil],
 
 
         /*
          *   Initials.  We'll look for strings of three or two initials,
          *   set off by periods but without spaces.  We'll look for
          *   three-letter initials first ("G.H.W. Billfold"), then
          *   two-letter initials ("X.Y. Zed"), so that we find the longest
          *   sequence that's actually in the dictionary.  Note that we
          *   don't have a separate rule for individual initials, since
          *   we'll pick that up with the regular abbreviated word rule
          *   below.
          *
          *   Some games could conceivably extend this to allow strings of
          *   initials of four letters or longer, but in practice people
          *   tend to elide the periods in longer sets of initials, so that
          *   the initials become an acronym, and thus would fit the
          *   ordinary word token rule.
          */
         ['three initials',
          new RexPattern('<alpha><period><alpha><period><alpha><period>'),
          tokWord, &tokCvtAbbr, &acceptAbbrTok],
 
         ['two initials',
          new RexPattern('<alpha><period><alpha><period>'),
          tokWord, &tokCvtAbbr, &acceptAbbrTok],
 
         /*
          *   Abbbreviated word - this is a word that ends in a period,
          *   such as "Mr.".  This rule comes before the ordinary word rule
          *   because we will only consider the period to be part of the
          *   word (and not a separate token) if the entire string
          *   including the period is in the main vocabulary dictionary.
          */
         ['abbreviation',
          new RexPattern('<Alpha|-><AlphaNum|-|squote>*<period>'),
          tokWord, &tokCvtAbbr, &acceptAbbrTok],
 
         /*
          *   A word ending in an apostrophe-s.  We parse this as two
          *   separate tokens: one for the word and one for the
          *   apostrophe-s.
          */
         ['apostrophe-s word',
          new RexPattern('<Alpha|-|&><AlphaNum|-|&|squote>*<squote>[sS]'),
          tokWord, &tokCvtApostropheS, nil],
 
         /*
          *   Words - note that we convert everything to lower-case.  A word
          *   must start with an alphabetic character, a hyphen, or an
          *   ampersand; after the initial character, a word can contain
          *   alphabetics, digits, hyphens, ampersands, and apostrophes.
          */
         ['word',
          new RexPattern('<Alpha|-|&><AlphaNum|-|&|squote>*'),
          tokWord, nil, nil],
 
         /* an abbreviation word starting with a number */
         ['abbreviation with initial digit',
          new RexPattern('<Digit>(?=<AlphaNum|-|&|squote>*<Alpha|-|&|squote>)'
                         + '<AlphaNum|-|&|squote>*<period>'),
          tokWord, &tokCvtAbbr, &acceptAbbrTok],
 
         /*
          *   A word can start with a number, as long as there's something
          *   other than numbers in the string - if it's all numbers, we
          *   want to treat it as a numeric token.
          */
         ['word with initial digit',
          new RexPattern('<Digit>(?=<AlphaNum|-|&|squote>*<Alpha|-|&|squote>)'
                         + '<AlphaNum|-|&|squote>*'), tokWord, nil, nil],
 
         /* strings with ASCII "straight" quotes */
         ['string ascii-quote',
          new RexPattern('<min>([`\'"])(.*)%1(?!<AlphaNum>)'),
          tokString, nil, nil],
 
         /* some people like to use single quotes like `this' */
         ['string back-quote',
          new RexPattern('<min>`(.*)\'(?!<AlphaNum>)'), tokString, nil, nil],
 
         /* strings with Latin-1 curly quotes (single and double) */
         ['string curly single-quote',
          new RexPattern('<min>\u2018(.*)\u2019'), tokString, nil, nil],
         ['string curly double-quote',
          new RexPattern('<min>\u201C(.*)\u201D'), tokString, nil, nil],
 
         /*
          *   unterminated string - if we didn't just match a terminated
          *   string, but we have what looks like the start of a string,
          *   match to the end of the line
          */
         ['string unterminated',
          new RexPattern('([`\'"\u2018\u201C](.*)'), tokString, nil, nil],
 
         /* integer numbers */
         ['integer', new RexPattern('[0-9]+'), tokInt, nil, nil],
 
         /* numbers with a '#' preceding */
         ['integer with #',
          new RexPattern('#[0-9]+'), tokPoundInt, nil, nil]
     ]
 
     /*
      *   Handle an apostrophe-s word.  We'll return this as two separate
      *   tokens: one for the word preceding the apostrophe-s, and one for
      *   the apostrophe-s itself.
      */
     tokCvtApostropheS(txt, typ, toks)
     {
         local w;
         local s;
 
         /*
          *   pull out the part up to but not including the apostrophe, and
          *   pull out the apostrophe-s part
          */
         w = txt.substr(1, txt.length() - 2);
         s = txt.substr(txt.length() - 1);
 
         /* add the part before the apostrophe as the main token type */
         toks.append([w, typ, w]);
 
         /* add the apostrophe-s as a separate special token */
         toks.append([s, tokApostropheS, s]);
     }
 
     /*
      *   Handle a spelled-out hyphenated number from 21 to 99.  We'll
      *   return this as three separate tokens: a word for the tens name, a
      *   word for the hyphen, and a word for the units name.
      */
     tokCvtSpelledNumber(txt, typ, toks)
     {
         /* parse the number into its three parts with a regular expression */
         rexMatch(patAlphaDashAlpha, txt);
 
         /* add the part before the hyphen */
         toks.append([rexGroup(1)[3], typ, rexGroup(1)[3]]);
 
         /* add the hyphen */
         toks.append(['-', typ, '-']);
 
         /* add the part after the hyphen */
         toks.append([rexGroup(2)[3], typ, rexGroup(2)[3]]);
     }
     patAlphaDashAlpha = static new RexPattern('(<alpha>+)-(<alpha>+)')
 
     /*
      *   Check to see if we want to accept an abbreviated token - this is
      *   a token that ends in a period, which we use for abbreviated words
      *   like "Mr." or "Ave."  We'll accept the token only if it appears
      *   as given - including the period - in the dictionary.  Note that
      *   we ignore truncated matches, since the only way we'll accept a
      *   period in a word token is as the last character; there is thus no
      *   way that a token ending in a period could be a truncation of any
      *   longer valid token.
      */
     acceptAbbrTok(txt)
     {
         /* look up the word, filtering out truncated results */
         return cmdDict.isWordDefined(
             txt, {result: (result & StrCompTrunc) == 0});
     }
 
     /*
      *   Process an abbreviated token.
      *
      *   When we find an abbreviation, we'll enter it with the abbreviated
      *   word minus the trailing period, plus the period as a separate
      *   token.  We'll mark the period as an "abbreviation period" so that
      *   grammar rules will be able to consider treating it as an
      *   abbreviation -- but since it's also a regular period, grammar
      *   rules that treat periods as regular punctuation will also be able
      *   to try to match the result.  This will ensure that we try it both
      *   ways - as abbreviation and as a word with punctuation - and pick
      *   the one that gives us the best result.
      */
     tokCvtAbbr(txt, typ, toks)
     {
         local w;
 
         /* add the part before the period as the ordinary token */
         w = txt.substr(1, txt.length() - 1);
         toks.append([w, typ, w]);
 
         /* add the token for the "abbreviation period" */
         toks.append(['.', tokAbbrPeriod, '.']);
     }
 
     /*
      *   Given a list of token strings, rebuild the original input string.
      *   We can't recover the exact input string, because the tokenization
      *   process throws away whitespace information, but we can at least
      *   come up with something that will display cleanly and produce the
      *   same results when run through the tokenizer.
      */
     buildOrigText(toks)
     {
         local str;
 
         /* start with an empty string */
         str = '';
 
         /* concatenate each token in the list */
         for (local i = 1, local len = toks.length() ; i <= len ; ++i)
         {
             /* add the current token to the string */
             str += getTokOrig(toks[i]);
 
             /*
              *   if this looks like a hyphenated number that we picked
              *   apart into two tokens, put it back together without
              *   spaces
              */
             if (i + 2 <= len
                 && rexMatch(patSpelledTens, getTokVal(toks[i])) != nil
                 && getTokVal(toks[i+1]) == '-'
                 && rexMatch(patSpelledUnits, getTokVal(toks[i+2])) != nil)
             {
                 /*
                  *   it's a hyphenated number, all right - put the three
                  *   tokens back together without any intervening spaces,
                  *   so ['twenty', '-', 'one'] turns into 'twenty-one'
                  */
                 str += getTokOrig(toks[i+1]) + getTokOrig(toks[i+2]);
 
                 /* skip ahead by the two extra tokens we're adding */
                 i += 2;
             }
             else if (i + 1 <= len
                      && getTokType(toks[i]) == tokWord
                      && getTokType(toks[i+1]) == tokApostropheS)
             {
                 /*
                  *   it's a word followed by an apostrophe-s token - these
                  *   are appended together without any intervening spaces
                  */
                 str += getTokOrig(toks[i+1]);
 
                 /* skip the extra token we added */
                 ++i;
             }
 
             /*
              *   if another token follows, and the next token isn't a
              *   punctuation mark, add a space before the next token
              */
             if (i != len && rexMatch(patPunct, getTokVal(toks[i+1])) == nil)
                 str += ' ';
         }
 
         /* return the result string */
         return str;
     }
 
     /* some pre-compiled regular expressions */
     patSpelledTens = static new RexPattern(
         '<nocase>twenty|thirty|forty|fifty|sixty|seventy|eighty|ninety')
     patSpelledUnits = static new RexPattern(
         '<nocase>one|two|three|four|five|six|seven|eight|nine')
     patPunct = static new RexPattern('[.,;:?!]')
 ;
 
 
 /* ------------------------------------------------------------------------ */
 /*
  *   Grammar Rules
  */
 
 /*
  *   Command with explicit target actor.  When a command starts with an
  *   actor's name followed by a comma followed by a verb, we take it as
  *   being directed to the actor.
  */
 grammar firstCommandPhrase(withActor):
     singleNounOnly->actor_ ',' commandPhrase->cmd_
     : FirstCommandProdWithActor
 
     /* "execute" the target actor phrase */
     execActorPhrase(issuingActor)
     {
         /* flag that the actor's being addressed in the second person */
         resolvedActor_.commandReferralPerson = SecondPerson;
     }
 ;
 
-grammar firstCommandPhrase(askTellActorTo):
-    ('ask' | 'tell' | 'a' | 't') singleNounOnly->actor_
-    'to' commandPhrase->cmd_
-    : FirstCommandProdWithActor
-
-    /* "execute" the target actor phrase */
-    execActorPhrase(issuingActor)
-    {
-        /*
-         *   Since our phrasing is TELL <ACTOR> TO <DO SOMETHING>, the
-         *   actor clearly becomes the antecedent for a subsequent
-         *   pronoun.  For example, in TELL BOB TO READ HIS BOOK, the word
-         *   HIS pretty clearly refers back to BOB.
-         */
-        if (resolvedActor_ != nil)
-        {
-            /* set the possessive anaphor object to the actor */
-            resolvedActor_.setPossAnaphorObj(resolvedActor_);
-
-            /* flag that the actor's being addressed in the third person */
-            resolvedActor_.commandReferralPerson = ThirdPerson;
-
-            /*
-             *   in subsequent commands carried out by the issuer, the
-             *   target actor is now the pronoun antecedent (for example:
-             *   after TELL BOB TO GO NORTH, the command FOLLOW HIM means
-             *   to follow Bob)
-             */
-            issuingActor.setPronounObj(resolvedActor_);
-        }
-    }
-;
+/* V češtině by vyžadovalo jiné tvary příkazů */
+//grammar firstCommandPhrase(askTellActorTo):
+//    ('požádej' | 'řekni' | 'pož' | 'řek') singleNounOnly->actor_
+//    'aby' commandPhrase->cmd_
+//    : FirstCommandProdWithActor
+//
+//    /* "execute" the target actor phrase */
+//    execActorPhrase(issuingActor)
+//    {
+//        /*
+//         *   Since our phrasing is TELL <ACTOR> TO <DO SOMETHING>, the
+//         *   actor clearly becomes the antecedent for a subsequent
+//         *   pronoun.  For example, in TELL BOB TO READ HIS BOOK, the word
+//         *   HIS pretty clearly refers back to BOB.
+//         */
+//        if (resolvedActor_ != nil)
+//        {
+//            /* set the possessive anaphor object to the actor */
+//            resolvedActor_.setPossAnaphorObj(resolvedActor_);
+//
+//            /* flag that the actor's being addressed in the third person */
+//            resolvedActor_.commandReferralPerson = ThirdPerson;
+//
+//            /*
+//             *   in subsequent commands carried out by the issuer, the
+//             *   target actor is now the pronoun antecedent (for example:
+//             *   after TELL BOB TO GO NORTH, the command FOLLOW HIM means
+//             *   to follow Bob)
+//             */
+//            issuingActor.setPronounObj(resolvedActor_);
+//        }
+//    }
+//;
 
 /*
  *   An actor-targeted command with a bad command phrase.  This is used as
  *   a fallback if we fail to match anything on the first attempt at
  *   parsing the first command on a line.  The point is to at least detect
  *   the target actor phrase, if that much is valid, so that we better
  *   customize error messages for the rest of the command.  
  */
 grammar actorBadCommandPhrase(main):
     singleNounOnly->actor_ ',' miscWordList
     | ('ask' | 'tell' | 'a' | 't') singleNounOnly->actor_ 'to' miscWordList
     : FirstCommandProdWithActor
 
     /* to resolve nouns, we merely resolve the actor */
     resolveNouns(issuingActor, targetActor, results)
     {
         /* resolve the underlying actor phrase */
         return actor_.resolveNouns(getResolver(issuingActor), results);
     }
 ;
 
 
 /*
  *   Command-only conjunctions.  These words and groups of words can
  *   separate commands from one another, and can't be used to separate noun
  *   phrases in a noun list.  
  */
 grammar commandOnlyConjunction(sentenceEnding):
     '.'
     | '!'
     : BasicProd
 
     /* these conjunctions end the sentence */
     isEndOfSentence() { return true; }
 ;
 
 grammar commandOnlyConjunction(nonSentenceEnding):
-    'then'
-    | 'and' 'then'
-    | ',' 'then'
-    | ',' 'and' 'then'
+    ( | 'a' | ',' | ',' 'a') ('potom' | 'pak' | 'následně')
     | ';'
     : BasicProd
 
     /* these conjunctions do not end a sentence */
     isEndOfSentence() { return nil; }
 ;
 
 
 /*
  *   Command-or-noun conjunctions.  These words and groups of words can be
  *   used to separate commands from one another, and can also be used to
  *   separate noun phrases in a noun list.
  */
 grammar commandOrNounConjunction(main):
     ','
-    | 'and'
-    | ',' 'and'
+    | 'a'
+    | ',' 'a'
     : BasicProd
 
     /* these do not end a sentence */
     isEndOfSentence() { return nil; }
 ;
 
 /*
  *   Noun conjunctions.  These words and groups of words can be used to
  *   separate noun phrases from one another.  Note that these do not need
  *   to be exclusive to noun phrases - these can occur as command
  *   conjunctions as well; this list is separated from
  *   commandOrNounConjunction in case there are conjunctions that can never
  *   be used as command conjunctions, since such conjunctions, which can
  *   appear here, would not appear in commandOrNounConjunctions.  
  */
 grammar nounConjunction(main):
     ','
-    | 'and'
-    | ',' 'and'
+    | 'a'
     : BasicProd
 
     /* these conjunctions do not end a sentence */
     isEndOfSentence() { return nil; }
 ;
 
 /* ------------------------------------------------------------------------ */
 /*
  *   Noun list: one or more noun phrases connected with conjunctions.  This
  *   kind of noun list can end in a terminal noun phrase.
  *   
  *   Note that a single noun phrase is a valid noun list, since a list can
  *   simply be a list of one.  The separate production nounMultiList can be
  *   used when multiple noun phrases are required.  
  */
 
 /*
  *   a noun list can consist of a single terminal noun phrase
  */
 grammar nounList(terminal): terminalNounPhrase->np_ : NounListProd
     resolveNouns(resolver, results)
     {
         /* resolve the underlying noun phrase */
         return np_.resolveNouns(resolver, results);
     }
 ;
 
 /*
  *   a noun list can consist of a list of a single complete (non-terminal)
  *   noun phrase
  */
 grammar nounList(nonTerminal): completeNounPhrase->np_ : NounListProd
     resolveNouns(resolver, results)
     {
         /* resolve the underlying noun phrase */
         return np_.resolveNouns(resolver, results);
     }
 ;
 
 /*
  *   a noun list can consist of a list with two or more entries
  */
 grammar nounList(list): nounMultiList->lst_ : NounListProd
     resolveNouns(resolver, results)
     {
         /* resolve the underlying list */
         return lst_.resolveNouns(resolver, results);
     }
 ;
 
 /*
  *   An empty noun list is one with no words at all.  This is matched when
  *   a command requires a noun list but the player doesn't include one;
  *   this construct has "badness" because we only want to match it when we
  *   have no choice.
  */
 grammar nounList(empty): [badness 500] : EmptyNounPhraseProd
     responseProd = nounList
 ;
 
 /* ------------------------------------------------------------------------ */
 /*
  *   Noun Multi List: two or more noun phrases connected by conjunctions.
  *   This is almost the same as the basic nounList production, but this
  *   type of production requires at least two noun phrases, whereas the
  *   basic nounList production more generally defines its list as any
  *   number - including one - of noun phrases.
  */
 
 /*
  *   a multi list can consist of a noun multi- list plus a terminal noun
  *   phrase, separated by a conjunction
  */
 grammar nounMultiList(multi):
     nounMultiList->lst_ nounConjunction terminalNounPhrase->np_
     : NounListProd
     resolveNouns(resolver, results)
     {
         /* return a list of all of the objects from both underlying lists */
         return np_.resolveNouns(resolver, results)
             + lst_.resolveNouns(resolver, results);
     }
 ;
 
 /*
  *   a multi list can consist of a non-terminal multi list
  */
 grammar nounMultiList(nonterminal): nonTerminalNounMultiList->lst_
     : NounListProd
     resolveNouns(resolver, results)
     {
         /* resolve the underlying list */
         return lst_.resolveNouns(resolver, results);
     }
 ;
 
 /* ------------------------------------------------------------------------ */
 /*
  *   A non-terminal noun multi list is a noun list made up of at least two
  *   non-terminal noun phrases, connected by conjunctions.
  *
  *   This is almost the same as the regular non-terminal noun list
  *   production, but this production requires two or more underlying noun
  *   phrases, whereas the basic non-terminal noun list matches any number
  *   of underlying phrases, including one.
  */
 
 /*
  *   a non-terminal multi-list can consist of a pair of complete noun
  *   phrases separated by a conjunction
  */
 grammar nonTerminalNounMultiList(pair):
     completeNounPhrase->np1_ nounConjunction completeNounPhrase->np2_
     : NounListProd
     resolveNouns(resolver, results)
     {
         /* return the combination of the two underlying noun phrases */
         return np1_.resolveNouns(resolver, results)
             + np2_.resolveNouns(resolver, results);
     }
 ;
 
 /*
  *   a non-terminal multi-list can consist of another non-terminal
  *   multi-list plus a complete noun phrase, connected by a conjunction
  */
 grammar nonTerminalNounMultiList(multi):
     nonTerminalNounMultiList->lst_ nounConjunction completeNounPhrase->np_
     : NounListProd
     resolveNouns(resolver, results)
     {
         /* return the combination of the sublist and the noun phrase */
         return lst_.resolveNouns(resolver, results)
             + np_.resolveNouns(resolver, results);
     }
 ;
 
 
 /* ------------------------------------------------------------------------ */
 /*
  *   "Except" list.  This is a noun list that can contain anything that's
  *   in a regular noun list plus some things that only make sense as
  *   exceptions, such as possessive nouns (e.g., "mine").
  */
 
 grammar exceptList(single): exceptNounPhrase->np_ : ExceptListProd
     resolveNouns(resolver, results)
     {
         return np_.resolveNouns(resolver, results);
     }
 ;
 
 grammar exceptList(list):
     exceptNounPhrase->np_ nounConjunction exceptList->lst_
     : ExceptListProd
     resolveNouns(resolver, results)
     {
         /* return a list consisting of all of our objects */
         return np_.resolveNouns(resolver, results)
             + lst_.resolveNouns(resolver, results);
     }
 ;
 
 /*
  *   An "except" noun phrase is a normal "complete" noun phrase or a
  *   possessive noun phrase that doesn't explicitly qualify another phrase
  *   (for example, "all the coins but bob's" - the "bob's" is just a
  *   possessive noun phrase without another noun phrase attached, since it
  *   implicitly qualifies "the coins").
  */
 grammar exceptNounPhrase(singleComplete): completeNounPhraseWithoutAll->np_
     : ExceptListProd
     resolveNouns(resolver, results)
     {
         return np_.resolveNouns(resolver, results);
     }
 ;
 
 grammar exceptNounPhrase(singlePossessive): possessiveNounPhrase->poss_
     : ButPossessiveProd
 ;
 
 
 /* ------------------------------------------------------------------------ */
 /*
  *   A single noun is sometimes required where, structurally, a list is not
  *   allowed.  Single nouns should not be used to prohibit lists where
  *   there is no structural reason for the prohibition - these should be
  *   used only where it doesn't make sense to use a list structurally.  
  */
 grammar singleNoun(normal): singleNounOnly->np_ : LayeredNounPhraseProd
 ;
 
 /*
  *   An empty single noun is one with no words at all.  This is matched
  *   when a command requires a noun list but the player doesn't include
  *   one; this construct has "badness" because we only want to match it
  *   when we have no choice.
  */
 grammar singleNoun(empty): [badness 500] : EmptyNounPhraseProd
     responseProd = singleNoun
 ;
 
 /*
  *   A user could attempt to use a noun list with more than one entry (a
  *   "multi list") where a single noun is required.  This is not a
  *   grammatical error, so we accept it grammatically; however, for
  *   disambiguation purposes we score it lower than a singleNoun production
  *   with only one noun phrase, and if we try to resolve it, we'll fail
  *   with an error.  
  */
 grammar singleNoun(multiple): nounMultiList->np_ : SingleNounWithListProd
 ;
 
 
 /*
  *   A *structural* single noun phrase.  This production is for use where a
  *   single noun phrase (not a list of nouns) is required grammatically.
  */
 grammar singleNounOnly(main):
     terminalNounPhrase->np_
     | completeNounPhrase->np_
     : SingleNounProd
 ;
 
 /* ------------------------------------------------------------------------ */
 /*
  *   Prepositionally modified single noun phrases.  These can be used in
  *   indirect object responses, so allow for interactions like this:
  *   
  *   >unlock door
  *.  What do you want to unlock it with?
  *   
  *   >with the key
  *   
  *   The entire notion of prepositionally qualified noun phrases in
  *   interactive indirect object responses is specific to English, so this
  *   is implemented in the English module only.  However, the general
  *   notion of specialized responses to interactive indirect object queries
  *   is handled in the language-independent library in some cases, in such
  *   a way that the language-specific library can customize the behavior -
  *   see TIAction.askIobjResponseProd.  
  */
 class PrepSingleNounProd: SingleNounProd
     resolveNouns(resolver, results)
     {
         return np_.resolveNouns(resolver, results);
     }
 ;
 
 /*
  *   Same thing for a Topic phrase
  */
 class PrepSingleTopicProd: TopicProd
     resolveNouns(resolver, results)
     {
         return np_.resolveNouns(resolver, results);
     }
 ;
 
 grammar inSingleNoun(main):
-     singleNoun->np_ | ('in' | 'into' | 'in' 'to') singleNoun->np_
+     singleNoun->np_ | ('v' | 'do') singleNoun->np_
     : PrepSingleNounProd
 ;
 
 grammar forSingleNoun(main):
-   singleNoun->np_ | 'for' singleNoun->np_ : PrepSingleNounProd
+   singleNoun->np_ | 'pro' singleNoun->np_ : PrepSingleNounProd
 ;
 
+/* Umožnit předlozku v odpovědi na dotaz: "Do čeho chceš vstoupit? >do pramice" */
 grammar toSingleNoun(main):
-   singleNoun->np_ | 'to' singleNoun->np_ : PrepSingleNounProd
+   singleNoun->np_ | 'do' singleNoun->np_ : PrepSingleNounProd
 ;
 
+/*
+ *   Předložka "do" resp. "na" pro nastoupení, které může být *do* auta
+ *   i *na* palubu.
+ */
+//grammar doNaSingleNoun(main):
+//   singleNoun->np_ | 'do' singleNoun->np_ | 'na' singleNoun->np_ : PrepSingleNounProd
+//;
+
 grammar throughSingleNoun(main):
-   singleNoun->np_ | ('through' | 'thru') singleNoun->np_
+   singleNoun->np_ | ('skrz' | 'skrze') singleNoun->np_
    : PrepSingleNounProd
 ;
 
 grammar fromSingleNoun(main):
-   singleNoun->np_ | 'from' singleNoun->np_ : PrepSingleNounProd
+   singleNoun->np_ | ('z' | 'ze') singleNoun->np_ : PrepSingleNounProd
 ;
 
 grammar onSingleNoun(main):
-   singleNoun->np_ | ('on' | 'onto' | 'on' 'to') singleNoun->np_
+   singleNoun->np_ | 'na' singleNoun->np_
     : PrepSingleNounProd
 ;
 
 grammar withSingleNoun(main):
-   singleNoun->np_ | 'with' singleNoun->np_ : PrepSingleNounProd
+   singleNoun->np_ | ('s' | 'se') singleNoun->np_ : PrepSingleNounProd
 ;
 
 grammar atSingleNoun(main):
-   singleNoun->np_ | 'at' singleNoun->np_ : PrepSingleNounProd
+   singleNoun->np_ | 'na' singleNoun->np_ : PrepSingleNounProd
 ;
 
 grammar outOfSingleNoun(main):
-   singleNoun->np_ | 'out' 'of' singleNoun->np_ : PrepSingleNounProd
+   singleNoun->np_ | ('z' | 'ze') singleNoun->np_ : PrepSingleNounProd
 ;
 
 grammar aboutTopicPhrase(main):
-   topicPhrase->np_ | 'about' topicPhrase->np_
+   topicPhrase->np_ | 'o' topicPhrase->np_
    : PrepSingleTopicProd
 ;
 
 /* ------------------------------------------------------------------------ */
 /*
  *   Complete noun phrase - this is a fully-qualified noun phrase that
  *   cannot be modified with articles, quantifiers, or anything else.  This
  *   is the highest-level individual noun phrase.  
  */
 
 grammar completeNounPhrase(main):
     completeNounPhraseWithAll->np_ | completeNounPhraseWithoutAll->np_
     : LayeredNounPhraseProd
 ;
 
 /*
  *   Slightly better than a purely miscellaneous word list is a pair of
  *   otherwise valid noun phrases connected by a preposition that's
  *   commonly used in command phrases.  This will match commands where the
  *   user has assumed a command with a prepositional structure that doesn't
  *   exist among the defined commands.  Since we have badness, we'll be
  *   ignored any time there's a valid command syntax with the same
  *   prepositional structure.
  */
 grammar completeNounPhrase(miscPrep):
     [badness 100] completeNounPhrase->np1_
-        ('with' | 'into' | 'in' 'to' | 'through' | 'thru' | 'for' | 'to'
-         | 'onto' | 'on' 'to' | 'at' | 'under' | 'behind')
+        ('s' | 'se' | 'do' | 'v' | 'skrz' | 'skrze' | 'pro' | 'na' | 'pod'
+        | 'za')
         completeNounPhrase->np2_
     : NounPhraseProd
     resolveNouns(resolver, results)
     {
         /* note that we have an invalid prepositional phrase structure */
         results.noteBadPrep();
 
         /* resolve the underlying noun phrases, for scoring purposes */
         np1_.resolveNouns(resolver, results);
         np2_.resolveNouns(resolver, results);
 
         /* return nothing */
         return [];
     }
 ;
 
 
 /*
  *   A qualified noun phrase can, all by itself, be a full noun phrase
  */
 grammar completeNounPhraseWithoutAll(qualified): qualifiedNounPhrase->np_
     : LayeredNounPhraseProd
 ;
 
 /*
  *   Pronoun rules.  A pronoun is a complete noun phrase; it does not allow
  *   further qualification.  
+ *
+ *   "Odemkni dveře. Otveři *je*.", "zeptej se *ho*", "zatáhni za *něj*"
  */
-grammar completeNounPhraseWithoutAll(it):   'it' : ItProd;
-grammar completeNounPhraseWithoutAll(them): 'them' : ThemProd;
-grammar completeNounPhraseWithoutAll(him):  'him' : HimProd;
-grammar completeNounPhraseWithoutAll(her):  'her' : HerProd;
+grammar completeNounPhraseWithoutAll(it): 
+    'jeho' | 'něho' | 'ho' | 'jemu' | 'němu' | 'mu' | 'jej' | 'něj' | 'něm'
+    | 'jím' | 'ním' : ItProd
+;
+
+grammar completeNounPhraseWithoutAll(them):
+    'jich' | 'nich' | 'jim' | 'nim' | 'je' | 'ně' | 'nich' | 'jimi' | 'nimy'
+    : ThemProd
+;
+
+grammar completeNounPhraseWithoutAll(him):
+    'jeho' | 'něho' | 'ho' | 'jemu' | 'němu' | 'mu' | 'jej' | 'něj' | 'něm'
+    | 'jím' | 'ním' : HimProd
+;
+
+grammar completeNounPhraseWithoutAll(her):
+    'jí' | 'ní' | 'ji' | 'ni' : HerProd
+;
 
 /*
  *   Reflexive second-person pronoun, for things like "bob, look at
  *   yourself"
  */
 grammar completeNounPhraseWithoutAll(yourself):
-    'yourself' | 'yourselves' | 'you' : YouProd
+    'sebe' | 'sobě' : YouProd
 ;
 
 /*
  *   Reflexive third-person pronouns.  We accept these in places such as
  *   the indirect object of a two-object verb.
  */
 grammar completeNounPhraseWithoutAll(itself): 'itself' : ItselfProd
     /* check agreement of our binding */
     checkAgreement(lst)
     {
         /* the result is required to be singular and ungendered */
         return (lst.length() == 1 && lst[1].obj_.canMatchIt);
     }
 ;
 
-grammar completeNounPhraseWithoutAll(themselves):
-    'themself' | 'themselves' : ThemselvesProd
-
-    /* check agreement of our binding */
-    checkAgreement(lst)
-    {
-        /*
-         *   For 'themselves', allow anything; we could balk at this
-         *   matching a single object that isn't a mass noun, but that
-         *   would be overly picky, and it would probably reject at least
-         *   a few things that really ought to be acceptable.  Besides,
-         *   'them' is the closest thing English has to a singular
-         *   gender-neutral pronoun, and some people intentionally use it
-         *   as such.
-         */
-        return true;
-    }
-;
+//grammar completeNounPhraseWithoutAll(themselves):
+//    'themself' | 'themselves' : ThemselvesProd
+//
+//    /* check agreement of our binding */
+//    checkAgreement(lst)
+//    {
+//        /*
+//         *   For 'themselves', allow anything; we could balk at this
+//         *   matching a single object that isn't a mass noun, but that
+//         *   would be overly picky, and it would probably reject at least
+//         *   a few things that really ought to be acceptable.  Besides,
+//         *   'them' is the closest thing English has to a singular
+//         *   gender-neutral pronoun, and some people intentionally use it
+//         *   as such.
+//         */
+//        return true;
+//    }
+//;
 
-grammar completeNounPhraseWithoutAll(himself): 'himself' : HimselfProd
+/* "zeptej se ho na *něho*" */
+grammar completeNounPhraseWithoutAll(himself): 'něj' | 'něho' : HimselfProd
     /* check agreement of our binding */
     checkAgreement(lst)
     {
         /* the result is required to be singular and masculine */
         return (lst.length() == 1 && lst[1].obj_.canMatchHim);
     }
 ;
 
-grammar completeNounPhraseWithoutAll(herself): 'herself' : HerselfProd
+grammar completeNounPhraseWithoutAll(herself): 'ni' : HerselfProd
     /* check agreement of our binding */
     checkAgreement(lst)
     {
         /* the result is required to be singular and feminine */
         return (lst.length() == 1 && lst[1].obj_.canMatchHer);
     }
 ;
 
 /*
  *   First-person pronoun, for referring to the speaker: "bob, look at me"
  */
-grammar completeNounPhraseWithoutAll(me): 'me' | 'myself' : MeProd;
+grammar completeNounPhraseWithoutAll(me): 'mě' : MeProd;
 
 /*
  *   "All" and "all but".
  *   
  *   "All" is a "complete" noun phrase, because there's nothing else needed
  *   to make it a noun phrase.  We make this a special kind of complete
  *   noun phrase because 'all' is not acceptable as a complete noun phrase
  *   in some contexts where any of the other complete noun phrases are
  *   acceptable.
  *   
  *   "All but" is a "terminal" noun phrase - this is a special kind of
  *   complete noun phrase that cannot be followed by another noun phrase
  *   with "and".  "All but" is terminal because we want any and's that
  *   follow it to be part of the exception list, so that we interpret "take
  *   all but a and b" as excluding a and b, not as excluding a but then
  *   including b as a separate list.  
  */
 grammar completeNounPhraseWithAll(main):
-    'all' | 'everything'
+    'vše' | 'všechno' | 'všechny' | 'všechna'
     : EverythingProd
 ;
 
 grammar terminalNounPhrase(allBut):
-    ('all' | 'everything') ('but' | 'except' | 'except' 'for')
+    ('vše' | 'všechno' | 'všechny' | 'všechna') ('kromě' | 'mimo' | 'bez')
         exceptList->except_
     : EverythingButProd
 ;
 
 /*
  *   Plural phrase with an exclusion list.  This is a terminal noun phrase
  *   because it ends in an exclusion list.
  */
 grammar terminalNounPhrase(pluralExcept):
     (qualifiedPluralNounPhrase->np_ | detPluralNounPhrase->np_)
-    ('except' | 'except' 'for' | 'but' | 'but' 'not') exceptList->except_
+    ('kromě' | 'mimo' | 'bez' | 'ale' ('bez' | 'ne')) exceptList->except_
     : ListButProd
 ;
 
 /*
  *   Qualified singular with an exception
  */
 grammar terminalNounPhrase(anyBut):
-    'any' nounPhrase->np_
-    ('but' | 'except' | 'except' 'for' | 'but' 'not') exceptList->except_
+    'kteréhokoliv' | 'kterýkoliv' | 'kteroukoliv' | 'kterékoliv' | 'kterákoliv'
+    | 'jakéhokoliv' | 'jakýkoliv' | 'jakoukoliv' | 'jakékoliv' | 'jakákoliv'
+     nounPhrase->np_
+    ('kromě' | 'mimo' | 'ale' ('bez' | 'ne')) exceptList->except_
     : IndefiniteNounButProd
 ;
 
 /* ------------------------------------------------------------------------ */
 /*
  *   A qualified noun phrase is a noun phrase with an optional set of
  *   qualifiers: a definite or indefinite article, a quantifier, words such
  *   as 'any' and 'all', possessives, and locational specifiers ("the box
  *   on the table").
  *
  *   Without qualification, a definite article is implicit, so we read
  *   "take box" as equivalent to "take the box."
  *
  *   Grammar rule instantiations in language-specific modules should set
  *   property np_ to the underlying noun phrase match tree.
  */
 
 /*
  *   A qualified noun phrase can be either singular or plural.  The number
  *   is a feature of the overall phrase; the phrase might consist of
  *   subphrases of different numbers (for example, "bob's coins" is plural
  *   even though it contains a singular subphrase, "bob"; and "one of the
  *   coins" is singular, even though its subphrase "coins" is plural).
  */
 grammar qualifiedNounPhrase(main):
     qualifiedSingularNounPhrase->np_
     | qualifiedPluralNounPhrase->np_
     : LayeredNounPhraseProd
 ;
 
 /* ------------------------------------------------------------------------ */
 /*
  *   Singular qualified noun phrase.
  */
 
 /*
  *   A singular qualified noun phrase with an implicit or explicit definite
  *   article.  If there is no article, a definite article is implied (we
  *   interpret "take box" as though it were "take the box").
  */
 grammar qualifiedSingularNounPhrase(definite):
-    ('the' | 'the' 'one' | 'the' '1' | ) indetSingularNounPhrase->np_
+    ('ten' | 'tu' | ) indetSingularNounPhrase->np_
     : DefiniteNounProd
 ;
 
 /*
  *   A singular qualified noun phrase with an explicit indefinite article.
  */
 grammar qualifiedSingularNounPhrase(indefinite):
-    ('a' | 'an') indetSingularNounPhrase->np_
+    indetSingularNounPhrase->np_
     : IndefiniteNounProd
 ;
 
 /*
  *   A singular qualified noun phrase with an explicit arbitrary
  *   determiner.
  */
 grammar qualifiedSingularNounPhrase(arbitrary):
-    ('any' | 'one' | '1' | 'any' ('one' | '1')) indetSingularNounPhrase->np_
+    ('kteréhokoliv' | 'kterýkoliv' | 'kteroukoliv' | 'kterékoliv' | 'kterákoliv'
+    | 'jakéhokoliv' | 'jakýkoliv' | 'jakoukoliv' | 'jakékoliv' | 'jakákoliv')
+    indetSingularNounPhrase->np_
     : ArbitraryNounProd
 ;
 
 /*
  *   A singular qualified noun phrase with a possessive adjective.
  */
 grammar qualifiedSingularNounPhrase(possessive):
     possessiveAdjPhrase->poss_ indetSingularNounPhrase->np_
     : PossessiveNounProd
 ;
 
 /*
  *   A singular qualified noun phrase that arbitrarily selects from a
  *   plural set.  This is singular, even though the underlying noun phrase
  *   is plural, because we're explicitly selecting one item.
  */
 grammar qualifiedSingularNounPhrase(anyPlural):
-    'any' 'of' explicitDetPluralNounPhrase->np_
+    ('kteréhokoliv' | 'kterýkoliv' | 'kteroukoliv' | 'kterékoliv' | 'kterákoliv'
+    | 'jakéhokoliv' | 'jakýkoliv' | 'jakoukoliv' | 'jakékoliv' | 'jakákoliv')
+    ('z' | 'ze') explicitDetPluralNounPhrase->np_
     : ArbitraryNounProd
 ;
 
 /*
  *   A singular object specified only by its containment, with a definite
  *   article.
+ *
+ *   "Který červený bonbón máš na mysli: červený bonbón na podlaze, nebo tvůj
+ *   červený bonbón? >
  */
 grammar qualifiedSingularNounPhrase(theOneIn):
-    'the' 'one' ('that' ('is' | 'was') | 'that' tokApostropheS | )
-    ('in' | 'inside' | 'inside' 'of' | 'on' | 'from')
+    ('ten' | 'ta' | 'to' | ) (',' ('který' | 'která' | 'které' | 'co')
+    ('je' | 'byl' | 'byla' | 'bylo') | )
+    ('v' | 've' | 'uvnitř' | 'na' | 'z' | 'ze')
     completeNounPhraseWithoutAll->cont_
     : VagueContainerDefiniteNounPhraseProd
 
     /*
      *   our main phrase is simply 'one' (so disambiguation prompts will
      *   read "which one do you mean...")
      */
-    mainPhraseText = 'one'
+    mainPhraseText = ''
 ;
 
 /*
  *   A singular object specified only by its containment, with an
  *   indefinite article.
  */
 grammar qualifiedSingularNounPhrase(anyOneIn):
-    ('anything' | 'one') ('that' ('is' | 'was') | 'that' tokApostropheS | )
-    ('in' | 'inside' | 'inside' 'of' | 'on' | 'from')
+    ('kteréhokoliv' | 'kterýkoliv' | 'kteroukoliv' | 'kterékoliv' | 'kterákoliv'
+    | 'jakéhokoliv' | 'jakýkoliv' | 'jakoukoliv' | 'jakékoliv' | 'jakákoliv')
+    (('který' | 'která' | 'které') ('je' | 'byl' | 'byla' | 'bylo') | )
+    ('v' | 've' | 'na' | 'z' | 'ze')
     completeNounPhraseWithoutAll->cont_
     : VagueContainerIndefiniteNounPhraseProd
 ;
 
 /* ------------------------------------------------------------------------ */
 /*
  *   An "indeterminate" singular noun phrase is a noun phrase without any
  *   determiner.  A determiner is a phrase that specifies the phrase's
  *   number and indicates whether or not it refers to a specific object,
  *   and if so fixes which object it refers to; determiners include
  *   articles ("the", "a") and possessives.
  *
  *   Note that an indeterminate phrase is NOT necessarily an indefinite
  *   phrase.  In fact, in most cases, we assume a definite usage when the
  *   determiner is omitted: we take TAKE BOX as meaning TAKE THE BOX.  This
  *   is more or less the natural way an English speaker would interpret
  *   this ill-formed phrasing, but even more than that, it's the
  *   Adventurese convention, taking into account that most players enter
  *   commands telegraphically and are accustomed to noun phrases being
  *   definite by default.
  */
 
 /* an indetermine noun phrase can be a simple noun phrase */
 grammar indetSingularNounPhrase(basic):
     nounPhrase->np_
     : LayeredNounPhraseProd
 ;
 
 /*
  *   An indetermine noun phrase can specify a location for the object(s).
  *   The location must be a singular noun phrase, but can itself be a fully
  *   qualified noun phrase (so it can have possessives, articles, and
  *   locational qualifiers of its own).
  *   
  *   Note that we take 'that are' even though the noun phrase is singular,
  *   because what we consider a singular noun phrase can have plural usage
  *   ("scissors", for example).  
  */
 grammar indetSingularNounPhrase(locational):
     nounPhrase->np_
     ('that' ('is' | 'was')
-     | 'that' tokApostropheS
      | 'that' ('are' | 'were')
      | )
     ('in' | 'inside' | 'inside' 'of' | 'on' | 'from')
     completeNounPhraseWithoutAll->cont_
     : ContainerNounPhraseProd
 ;
 
 /* ------------------------------------------------------------------------ */
 /*
  *   Plural qualified noun phrase.
  */
 
 /*
  *   A simple unqualified plural phrase with determiner.  Since this form
  *   of plural phrase doesn't have any additional syntax that makes it an
  *   unambiguous plural, we can only accept an actual plural for the
  *   underlying phrase here - we can't accept an adjective phrase.
  */
 grammar qualifiedPluralNounPhrase(determiner):
     ('any' | ) detPluralOnlyNounPhrase->np_
     : LayeredNounPhraseProd
 ;
 
 /* plural phrase qualified with a number and optional "any" */
 grammar qualifiedPluralNounPhrase(anyNum):
     ('any' | ) numberPhrase->quant_ indetPluralNounPhrase->np_
     | ('any' | ) numberPhrase->quant_ 'of' explicitDetPluralNounPhrase->np_
     : QuantifiedPluralProd
 ;
 
 /* plural phrase qualified with a number and "all" */
 grammar qualifiedPluralNounPhrase(allNum):
     'all' numberPhrase->quant_ indetPluralNounPhrase->np_
     | 'all' numberPhrase->quant_ 'of' explicitDetPluralNounPhrase->np_
     : ExactQuantifiedPluralProd
 ;
 
 /* plural phrase qualified with "both" */
 grammar qualifiedPluralNounPhrase(both):
     'both' detPluralNounPhrase->np_
     | 'both' 'of' explicitDetPluralNounPhrase->np_
     : BothPluralProd
 ;
 
 /* plural phrase qualified with "all" */
 grammar qualifiedPluralNounPhrase(all):
     'all' detPluralNounPhrase->np_
     | 'all' 'of' explicitDetPluralNounPhrase->np_
     : AllPluralProd
 ;
 
 /* vague plural phrase with location specified */
 grammar qualifiedPluralNounPhrase(theOnesIn):
     ('the' 'ones' ('that' ('are' | 'were') | )
      | ('everything' | 'all')
-       ('that' ('is' | 'was') | 'that' tokApostropheS | ))
+       ('that' ('is' | 'was') | ))
     ('in' | 'inside' | 'inside' 'of' | 'on' | 'from')
     completeNounPhraseWithoutAll->cont_
     : AllInContainerNounPhraseProd
 ;
 
 /* ------------------------------------------------------------------------ */
 /*
  *   A plural noun phrase with a determiner.  The determiner can be
  *   explicit (such as an article or possessive) or it can implied (the
  *   implied determiner is the definite article, so "take boxes" is
  *   understood as "take the boxes").
  */
 grammar detPluralNounPhrase(main):
     indetPluralNounPhrase->np_ | explicitDetPluralNounPhrase->np_
     : LayeredNounPhraseProd
 ;
 
 /* ------------------------------------------------------------------------ */
 /*
  *   A determiner plural phrase with an explicit underlying plural (i.e.,
  *   excluding adjective phrases with no explicitly plural words).
  */
 grammar detPluralOnlyNounPhrase(main):
     implicitDetPluralOnlyNounPhrase->np_
     | explicitDetPluralOnlyNounPhrase->np_
     : LayeredNounPhraseProd
 ;
 
 /*
  *   An implicit determiner plural phrase is an indeterminate plural phrase
  *   without any extra determiner - i.e., the determiner is implicit.
  *   We'll treat this the same way we do a plural explicitly determined
  *   with a definite article, since this is the most natural interpretation
  *   in English.
  *
  *   (This might seem like a pointless extra layer in the grammar, but it's
  *   necessary for the resolution process to have a layer that explicitly
  *   declares the phrase to be determined, even though the determiner is
  *   implied in the structure.  This extra layer is important because it
  *   explicitly calls results.noteMatches(), which is needed for rankings
  *   and the like.)
  */
 grammar implicitDetPluralOnlyNounPhrase(main):
     indetPluralOnlyNounPhrase->np_
     : DefinitePluralProd
 ;
 
 /* ------------------------------------------------------------------------ */
 /*
  *   A plural noun phrase with an explicit determiner.
  */
 
 /* a plural noun phrase with a definite article */
 grammar explicitDetPluralNounPhrase(definite):
     'the' indetPluralNounPhrase->np_
     : DefinitePluralProd
 ;
 
 /* a plural noun phrase with a definite article and a number */
 grammar explicitDetPluralNounPhrase(definiteNumber):
     'the' numberPhrase->quant_ indetPluralNounPhrase->np_
     : ExactQuantifiedPluralProd
 ;
 
 /* a plural noun phrase with a possessive */
 grammar explicitDetPluralNounPhrase(possessive):
     possessiveAdjPhrase->poss_ indetPluralNounPhrase->np_
     : PossessivePluralProd
 ;
 
 /* a plural noun phrase with a possessive and a number */
 grammar explicitDetPluralNounPhrase(possessiveNumber):
     possessiveAdjPhrase->poss_ numberPhrase->quant_
     indetPluralNounPhrase->np_
     : ExactQuantifiedPossessivePluralProd
 ;
 
 /* ------------------------------------------------------------------------ */
 /*
  *   A plural noun phrase with an explicit determiner and only an
  *   explicitly plural underlying phrase.
  */
 grammar explicitDetPluralOnlyNounPhrase(definite):
     'the' indetPluralOnlyNounPhrase->np_
     : AllPluralProd
 ;
 
 grammar explicitDetPluralOnlyNounPhrase(definiteNumber):
     'the' numberPhrase->quant_ indetPluralNounPhrase->np_
     : ExactQuantifiedPluralProd
 ;
 
 grammar explicitDetPluralOnlyNounPhrase(possessive):
     possessiveAdjPhrase->poss_ indetPluralOnlyNounPhrase->np_
     : PossessivePluralProd
 ;
 
 grammar explicitDetPluralOnlyNounPhrase(possessiveNumber):
     possessiveAdjPhrase->poss_ numberPhrase->quant_
     indetPluralNounPhrase->np_
     : ExactQuantifiedPossessivePluralProd
 ;
 
 
 /* ------------------------------------------------------------------------ */
 /*
  *   An indeterminate plural noun phrase.
  *
  *   For the basic indeterminate plural phrase, allow an adjective phrase
  *   anywhere a plural phrase is allowed; this makes possible the
  *   short-hand of omitting a plural word when the plural number is
  *   unambiguous from context.
  */
 
 /* a simple plural noun phrase */
 grammar indetPluralNounPhrase(basic):
     pluralPhrase->np_ | adjPhrase->np_
     : LayeredNounPhraseProd
 ;
 
 /*
  *   A plural noun phrase with a locational qualifier.  Note that even
  *   though the overall phrase is plural (and so the main underlying noun
  *   phrase is plural), the location phrase itself must always be singular.
  */
 grammar indetPluralNounPhrase(locational):
     (pluralPhrase->np_ | adjPhrase->np_) ('that' ('are' | 'were') | )
     ('in' | 'inside' | 'inside' 'of' | 'on' | 'from')
     completeNounPhraseWithoutAll->cont_
     : ContainerNounPhraseProd
 ;
 
 /*
  *   An indetermine plural noun phrase with only explicit plural phrases.
  */
 grammar indetPluralOnlyNounPhrase(basic):
     pluralPhrase->np_
     : LayeredNounPhraseProd
 ;
 
 grammar indetPluralOnlyNounPhrase(locational):
     pluralPhrase->np_ ('that' ('are' | 'were') | )
     ('in' | 'inside' | 'inside' 'of' | 'on' | 'from')
     completeNounPhraseWithoutAll->cont_
     : ContainerNounPhraseProd
 ;
 
 /* ------------------------------------------------------------------------ */
 /*
  *   Noun Phrase.  This is the basic noun phrase, which serves as a
  *   building block for complete noun phrases.  This type of noun phrase
  *   can be qualified with articles, quantifiers, and possessives, and can
  *   be used to construct possessives via the addition of "'s" at the end
  *   of the phrase.
  *   
  *   In most cases, custom noun phrase rules should be added to this
  *   production, as long as qualification (with numbers, articles, and
  *   possessives) is allowed.  For a custom noun phrase rule that cannot be
  *   qualified, a completeNounPhrase rule should be added instead.  
  */
 grammar nounPhrase(main): compoundNounPhrase->np_
     : LayeredNounPhraseProd
 ;
 
 /*
  *   Plural phrase.  This is the basic plural phrase, and corresponds to
  *   the basic nounPhrase for plural forms.
  */
 grammar pluralPhrase(main): compoundPluralPhrase->np_
     : LayeredNounPhraseProd
 ;
 
 /* ------------------------------------------------------------------------ */
 /*
  *   Compound noun phrase.  This is one or more noun phrases connected with
  *   'of', as in "piece of paper".  The part after the 'of' is another
  *   compound noun phrase.
  *   
  *   Note that this general rule does not allow the noun phrase after the
  *   'of' to be qualified with an article or number, except that we make an
  *   exception to allow a definite article.  Other cases ("a piece of four
  *   papers") do not generally make sense, so we won't attempt to support
  *   them; instead, games can add as special cases new nounPhrase rules for
  *   specific literal sequences where more complex grammar is necessary.  
  */
 grammar compoundNounPhrase(simple): simpleNounPhrase->np_
     : NounPhraseWithVocab
     getVocabMatchList(resolver, results, extraFlags)
     {
         return np_.getVocabMatchList(resolver, results, extraFlags);
     }
     getAdjustedTokens()
     {
         return np_.getAdjustedTokens();
     }
 ;
 
 grammar compoundNounPhrase(of):
     simpleNounPhrase->np1_ 'of'->of_ compoundNounPhrase->np2_
     | simpleNounPhrase->np1_ 'of'->of_ 'the'->the_ compoundNounPhrase->np2_
     : NounPhraseWithVocab
     getVocabMatchList(resolver, results, extraFlags)
     {
         local lst1;
         local lst2;
 
         /* resolve the two underlying lists */
         lst1 = np1_.getVocabMatchList(resolver, results, extraFlags);
         lst2 = np2_.getVocabMatchList(resolver, results, extraFlags);
 
         /*
          *   the result is the intersection of the two lists, since we
          *   want the list of objects with all of the underlying
          *   vocabulary words
          */
         return intersectNounLists(lst1, lst2);
     }
     getAdjustedTokens()
     {
         local ofLst;
 
         /* generate the 'of the' list from the original words */
         if (the_ == nil)
             ofLst = [of_, &miscWord];
         else
             ofLst = [of_, &miscWord, the_, &miscWord];
 
         /* return the full list */
         return np1_.getAdjustedTokens() + ofLst + np2_.getAdjustedTokens();
     }
 ;
 
 
 /* ------------------------------------------------------------------------ */
 /*
  *   Compound plural phrase - same as a compound noun phrase, but involving
  *   a plural part before the 'of'.  
  */
 
 /*
  *   just a single plural phrase
  */
 grammar compoundPluralPhrase(simple): simplePluralPhrase->np_
     : NounPhraseWithVocab
     getVocabMatchList(resolver, results, extraFlags)
     {
         return np_.getVocabMatchList(resolver, results, extraFlags);
     }
     getAdjustedTokens()
     {
         return np_.getAdjustedTokens();
     }
 ;
 
 /*
  *   <plural-phrase> of <noun-phrase>
  */
 grammar compoundPluralPhrase(of):
     simplePluralPhrase->np1_ 'of'->of_ compoundNounPhrase->np2_
     | simplePluralPhrase->np1_ 'of'->of_ 'the'->the_ compoundNounPhrase->np2_
     : NounPhraseWithVocab
     getVocabMatchList(resolver, results, extraFlags)
     {
         local lst1;
         local lst2;
 
         /* resolve the two underlying lists */
         lst1 = np1_.getVocabMatchList(resolver, results, extraFlags);
         lst2 = np2_.getVocabMatchList(resolver, results, extraFlags);
 
         /*
          *   the result is the intersection of the two lists, since we
          *   want the list of objects with all of the underlying
          *   vocabulary words
          */
         return intersectNounLists(lst1, lst2);
     }
     getAdjustedTokens()
     {
         local ofLst;
 
         /* generate the 'of the' list from the original words */
         if (the_ == nil)
             ofLst = [of_, &miscWord];
         else
             ofLst = [of_, &miscWord, the_, &miscWord];
 
         /* return the full list */
         return np1_.getAdjustedTokens() + ofLst + np2_.getAdjustedTokens();
     }
 ;
 
 /* ------------------------------------------------------------------------ */
 /*
  *   Simple noun phrase.  This is the most basic noun phrase, which is
  *   simply a noun, optionally preceded by one or more adjectives.
  */
 
 /*
  *   just a noun
  */
 grammar simpleNounPhrase(noun): nounWord->noun_ : NounPhraseWithVocab
     /* generate a list of my resolved objects */
     getVocabMatchList(resolver, results, extraFlags)
     {
         return noun_.getVocabMatchList(resolver, results, extraFlags);
     }
     getAdjustedTokens()
     {
         return noun_.getAdjustedTokens();
     }
 ;
 
 /*
  *   <adjective> <simple-noun-phrase> (this allows any number of adjectives
  *   to be applied) 
  */
 grammar simpleNounPhrase(adjNP): adjWord->adj_ simpleNounPhrase->np_
     : NounPhraseWithVocab
 
     /* generate a list of my resolved objects */
     getVocabMatchList(resolver, results, extraFlags)
     {
         /*
          *   return the list of objects in scope matching our adjective
          *   plus the list from the underlying noun phrase
          */
         return intersectNounLists(
             adj_.getVocabMatchList(resolver, results, extraFlags),
             np_.getVocabMatchList(resolver, results, extraFlags));
     }
     getAdjustedTokens()
     {
         return adj_.getAdjustedTokens() + np_.getAdjustedTokens();
     }
 ;
 
 /*
  *   A simple noun phrase can also include a number or a quoted string
  *   before or after a noun.  A number can be spelled out or written with
  *   numerals; we consider both forms equivalent in meaning.
  *   
  *   A number in this type of usage is grammatically equivalent to an
  *   adjective - it's not meant to quantify the rest of the noun phrase,
  *   but rather is simply an adjective-like modifier.  For example, an
  *   elevator's control panel might have a set of numbered buttons which we
  *   want to refer to as "button 1," "button 2," and so on.  It is
  *   frequently the case that numeric adjectives are equally at home before
  *   or after their noun: "push 3 button" or "push button 3".  In addition,
  *   we accept a number by itself as a lone adjective, as in "push 3".  
  */
 
 /*
  *   just a numeric/string adjective (for things like "push 3", "push #3",
  *   'push "G"')
  */
 grammar simpleNounPhrase(number): literalAdjPhrase->adj_
     : NounPhraseWithVocab
     getVocabMatchList(resolver, results, extraFlags)
     {
         /*
          *   note that this counts as an adjective-ending phrase, since we
          *   don't have a noun involved
          */
         results.noteAdjEnding();
 
         /* pass through to the underlying literal adjective phrase */
         local lst = adj_.getVocabMatchList(resolver, results,
                                            extraFlags | EndsWithAdj);
 
         /* if in global scope, also try a noun interpretation */
         if (resolver.isGlobalScope)
             lst = adj_.addNounMatchList(lst, resolver, results, extraFlags);
 
         /* return the result */
         return lst;
     }
     getAdjustedTokens()
     {
         /* pass through to the underlying literal adjective phrase */
         return adj_.getAdjustedTokens();
     }
 ;
 
 /*
  *   <literal-adjective> <noun> (for things like "board 44 bus" or 'push
  *   "G" button')
  */
 grammar simpleNounPhrase(numberAndNoun):
     literalAdjPhrase->adj_ nounWord->noun_
     : NounPhraseWithVocab
     getVocabMatchList(resolver, results, extraFlags)
     {
         local nounList;
         local adjList;
 
         /* get the list of objects matching the rest of the noun phrase */
         nounList = noun_.getVocabMatchList(resolver, results, extraFlags);
 
         /* get the list of objects matching the literal adjective */
         adjList = adj_.getVocabMatchList(resolver, results, extraFlags);
 
         /* intersect the two lists and return the results */
         return intersectNounLists(nounList, adjList);
     }
     getAdjustedTokens()
     {
         return adj_.getAdjustedTokens() + noun_.getAdjustedTokens();
     }
 ;
 
 /*
  *   <noun> <literal-adjective> (for things like "press button 3" or 'put
  *   tab "A" in slot "B"')
  */
 grammar simpleNounPhrase(nounAndNumber):
     nounWord->noun_ literalAdjPhrase->adj_
     : NounPhraseWithVocab
     getVocabMatchList(resolver, results, extraFlags)
     {
         local nounList;
         local adjList;
 
         /* get the list of objects matching the rest of the noun phrase */
         nounList = noun_.getVocabMatchList(resolver, results, extraFlags);
 
         /* get the literal adjective matches */
         adjList = adj_.getVocabMatchList(resolver, results, extraFlags);
 
         /* intersect the two lists and return the results */
         return intersectNounLists(nounList, adjList);
     }
     getAdjustedTokens()
     {
         return noun_.getAdjustedTokens() + adj_.getAdjustedTokens();
     }
 ;
 
 /*
  *   A simple noun phrase can also end in an adjective, which allows
  *   players to refer to objects using only their unique adjectives rather
  *   than their full names, which is sometimes more convenient: just "take
  *   gold" rather than "take gold key."
  *   
  *   When a particular phrase can be interpreted as either ending in an
  *   adjective or ending in a noun, we will always take the noun-ending
  *   interpretation - in such cases, the adjective-ending interpretation is
  *   probably a weak binding.  For example, "take pizza" almost certainly
  *   refers to the pizza itself when "pizza" and "pizza box" are both
  *   present, but it can also refer just to the box when no pizza is
  *   present.
  *   
  *   Equivalent to a noun phrase ending in an adjective is a noun phrase
  *   ending with an adjective followed by "one," as in "the red one."  
  */
 grammar simpleNounPhrase(adj): adjWord->adj_ : NounPhraseWithVocab
     /* generate a list of my resolved objects */
     getVocabMatchList(resolver, results, extraFlags)
     {
         /* note in the results that we end in an adjective */
         results.noteAdjEnding();
 
         /* generate a list of objects matching the adjective */
         local lst = adj_.getVocabMatchList(
             resolver, results, extraFlags | EndsWithAdj);
 
         /* if in global scope, also try a noun interpretation */
         if (resolver.isGlobalScope)
             lst = adj_.addNounMatchList(lst, resolver, results, extraFlags);
 
         /* return the result */
         return lst;
     }
     getAdjustedTokens()
     {
         /* return the adjusted token list for the adjective */
         return adj_.getAdjustedTokens();
     }
 ;
 
 grammar simpleNounPhrase(adjAndOne): adjective->adj_ 'one'
     : NounPhraseWithVocab
     /* generate a list of my resolved objects */
     getVocabMatchList(resolver, results, extraFlags)
     {
         /*
          *   This isn't exactly an adjective ending, but consider it as
          *   such anyway, since we're not matching 'one' to a vocabulary
          *   word - we're just using it as a grammatical marker that we're
          *   not providing a real noun.  If there's another match for
          *   which 'one' is a noun, that one is definitely preferred to
          *   this one; the adj-ending marking will ensure that we choose
          *   the other one.
          */
         results.noteAdjEnding();
 
         /* generate a list of objects matching the adjective */
         return getWordMatches(adj_, &adjective, resolver,
                               extraFlags | EndsWithAdj, VocabTruncated);
     }
     getAdjustedTokens()
     {
         return [adj_, &adjective];
     }
 ;
 
 /*
  *   In the worst case, a simple noun phrase can be constructed from
  *   arbitrary words that don't appear in our dictionary.
  */
 grammar simpleNounPhrase(misc):
     [badness 200] miscWordList->lst_ : NounPhraseWithVocab
     getVocabMatchList(resolver, results, extraFlags)
     {
         /* get the match list from the underlying list */
         local lst = lst_.getVocabMatchList(resolver, results, extraFlags);
 
         /*
          *   If there are no matches, note in the results that we have an
          *   arbitrary word list.  Note that we do this only if there are
          *   no matches, because we might match non-dictionary words to an
          *   object with a wildcard in its vocabulary words, in which case
          *   this is a valid, matching phrase after all.
          */
         if (lst == nil || lst.length() == 0)
             results.noteMiscWordList(lst_.getOrigText());
 
         /* return the match list */
         return lst;
     }
     getAdjustedTokens()
     {
         return lst_.getAdjustedTokens();
     }
 ;
 
 /*
  *   If the command has qualifiers but omits everything else, we can have
  *   an empty simple noun phrase.
  */
 grammar simpleNounPhrase(empty): [badness 600] : NounPhraseWithVocab
     getVocabMatchList(resolver, results, extraFlags)
     {
         /* we have an empty noun phrase */
         return results.emptyNounPhrase(resolver);
     }
     getAdjustedTokens()
     {
         return [];
     }
 ;
 
 /* ------------------------------------------------------------------------ */
 /*
  *   An AdjPhraseWithVocab is an English-specific subclass of
  *   NounPhraseWithVocab, specifically for noun phrases that contain
  *   entirely adjectives.  
  */
 class AdjPhraseWithVocab: NounPhraseWithVocab
     /* the property for the adjective literal - this is usually adj_ */
     adjVocabProp = &adj_
 
     /* 
      *   Add the vocabulary matches that we'd get if we were treating our
      *   adjective as a noun.  This combines the noun interpretation with a
      *   list of matches we got for the adjective version.  
      */
     addNounMatchList(lst, resolver, results, extraFlags)
     {
         /* get the word matches with a noun interpretation of our adjective */
         local nLst = getWordMatches(
             self.(adjVocabProp), &noun, resolver, extraFlags, VocabTruncated);
 
         /* combine the lists and return the result */
         return combineWordMatches(lst, nLst);
     }
 ;
 
 /* ------------------------------------------------------------------------ */
 /*
  *   A "literal adjective" phrase is a number or string used as an
  *   adjective.
  */
 grammar literalAdjPhrase(number):
     numberPhrase->num_ | poundNumberPhrase->num_
     : AdjPhraseWithVocab
 
     adj_ = (num_.getStrVal())
     getVocabMatchList(resolver, results, extraFlags)
     {
         local numList;
 
         /*
          *   get the list of objects matching the numeral form of the
          *   number as an adjective
          */
         numList = getWordMatches(num_.getStrVal(), &adjective,
                                  resolver, extraFlags, VocabTruncated);
 
         /* add the list of objects matching the special '#' wildcard */
         numList += getWordMatches('#', &adjective, resolver,
                                   extraFlags, VocabTruncated);
 
         /* return the combined lists */
         return numList;
     }
     getAdjustedTokens()
     {
         return [num_.getStrVal(), &adjective];
     }
 ;
 
 grammar literalAdjPhrase(string): quotedStringPhrase->str_
     : AdjPhraseWithVocab
 
     adj_ = (str_.getStringText().toLower())
     getVocabMatchList(resolver, results, extraFlags)
     {
         local strList;
         local wLst;
 
         /*
          *   get the list of objects matching the string with the quotes
          *   removed
          */
         strList = getWordMatches(str_.getStringText().toLower(),
                                  &literalAdjective,
                                  resolver, extraFlags, VocabTruncated);
 
         /* add the list of objects matching the literal-adjective wildcard */
         wLst = getWordMatches('\u0001', &literalAdjective, resolver,
                               extraFlags, VocabTruncated);
         strList = combineWordMatches(strList, wLst);
 
         /* return the combined lists */
         return strList;
     }
     getAdjustedTokens()
     {
         return [str_.getStringText().toLower(), &adjective];
     }
 ;
 
 /*
  *   In many cases, we might want to write what is semantically a literal
  *   string qualifier without the quotes.  For example, we might want to
  *   refer to an elevator button that's labeled "G" as simply "button G",
  *   without any quotes around the "G".  To accommodate these cases, we
  *   provide the literalAdjective part-of-speech.  We'll match these parts
  *   of speech the same way we'd match them if they were quoted.
  */
 grammar literalAdjPhrase(literalAdj): literalAdjective->adj_
     : AdjPhraseWithVocab
     getVocabMatchList(resolver, results, extraFlags)
     {
         local lst;
 
         /* get a list of objects in scope matching our literal adjective */
         lst = getWordMatches(adj_, &literalAdjective, resolver,
                              extraFlags, VocabTruncated);
 
         /* if the scope is global, also include ordinary adjective matches */
         if (resolver.isGlobalScope)
         {
             /* get the ordinary adjective bindings */
             local aLst = getWordMatches(adj_, &adjective, resolver,
                                         extraFlags, VocabTruncated);
 
             /* global scope - combine the lists */
             lst = combineWordMatches(lst, aLst);
         }
 
         /* return the result */
         return lst;
     }
     getAdjustedTokens()
     {
         return [adj_, &literalAdjective];
     }
 ;
 
 
 /* ------------------------------------------------------------------------ */
 /*
  *   A noun word.  This can be either a simple 'noun' vocabulary word, or
  *   it can be an abbreviated noun with a trailing abbreviation period.
  */
 class NounWordProd: NounPhraseWithVocab
     getVocabMatchList(resolver, results, extraFlags)
     {
         local w;
         local nLst;
 
         /* get our word text */
         w = getNounText();
 
         /* get the list of matches as nouns */
         nLst = getWordMatches(w, &noun, resolver, extraFlags, VocabTruncated);
 
         /*
          *   If the resolver indicates that we're in a "global" scope,
          *   *also* include any additional matches as adjectives.
          *
          *   Normally, when we're operating in limited, local scopes, we
          *   use the structure of the phrasing to determine whether to
          *   match a noun or adjective; if we have a match for a given word
          *   as a noun, we'll treat it only as a noun.  This allows us to
          *   take PIZZA to refer to the pizza (for which 'pizza' is defined
          *   as a noun) rather than to the PIZZA BOX (for which 'pizza' is
          *   a mere adjective) when both are in scope.  It's obvious which
          *   the player means in such cases, so we can be smart about
          *   choosing the stronger match.
          *
          *   In cases of global scope, though, it's much harder to guess
          *   about the player's intentions.  When the player types PIZZA,
          *   they might be thinking of the box even though there's a pizza
          *   somewhere else in the game.  Since the two objects might be in
          *   entirely different locations, both out of view, we can't
          *   assume that one or the other is more likely on the basis of
          *   which is closer to the player's senses.  So, it's better to
          *   allow both to match for now, and decide later, based on the
          *   context of the command, which was actually meant.
          */
         if (resolver.isGlobalScope)
         {
             /* get the list of matching adjectives */
             local aLst = getWordMatches(w, &adjective, resolver,
                                         extraFlags, VocabTruncated);
 
             /* combine it with the noun list */
             nLst = combineWordMatches(nLst, aLst);
         }
 
         /* return the match list */
         return nLst;
     }
     getAdjustedTokens()
     {
         /* the noun includes the period as part of the literal text */
         return [getNounText(), &noun];
     }
 
     /* the actual text of the noun to match to the dictionary */
     getNounText() { return noun_; }
 ;
 
 grammar nounWord(noun): noun->noun_ : NounWordProd
 ;
 
 grammar nounWord(nounAbbr): noun->noun_ tokAbbrPeriod->period_
     : NounWordProd
 
     /*
      *   for dictionary matching purposes, include the text of our noun
      *   with the period attached - the period is part of the dictionary
      *   entry for an abbreviated word
      */
     getNounText() { return noun_ + period_; }
 ;
 
 /* ------------------------------------------------------------------------ */
 /*
  *   An adjective word.  This can be either a simple 'adjective' vocabulary
  *   word, or it can be an 'adjApostS' vocabulary word plus a 's token.  
  */
 grammar adjWord(adj): adjective->adj_ : AdjPhraseWithVocab
     /* generate a list of resolved objects */
     getVocabMatchList(resolver, results, extraFlags)
     {
         /* return a list of objects in scope matching our adjective */
         return getWordMatches(adj_, &adjective, resolver,
                               extraFlags, VocabTruncated);
     }
     getAdjustedTokens()
     {
         return [adj_, &adjective];
     }
 ;
 
 grammar adjWord(adjApostS): adjApostS->adj_ tokApostropheS->apost_
     : AdjPhraseWithVocab
     /* generate a list of resolved objects */
     getVocabMatchList(resolver, results, extraFlags)
     {
         /* return a list of objects in scope matching our adjective */
         return getWordMatches(adj_, &adjApostS, resolver,
                               extraFlags, VocabTruncated);
     }
     getAdjustedTokens()
     {
         return [adj_, &adjApostS];
     }
 ;
 
 grammar adjWord(adjAbbr): adjective->adj_ tokAbbrPeriod->period_
     : AdjPhraseWithVocab
     getVocabMatchList(resolver, results, extraFlags)
     {
         /*
          *   return the list matching our adjective *with* the period
          *   attached; the period is part of the dictionary entry for an
          *   abbreviated word
          */
         return getWordMatches(adj_ + period_, &adjective, resolver,
                               extraFlags, VocabTruncated);
     }
     getAdjustedTokens()
     {
         /* the adjective includes the period as part of the literal text */
         return [adj_ + period_, &adjective];
     }
 ;
 
 /* ------------------------------------------------------------------------ */
 /*
  *   Possessive phrase.  This is a noun phrase expressing ownership of
  *   another object.
  *   
  *   Note that all possessive phrases that can possibly be ambiguous must
  *   define getOrigMainText() to return the "main noun phrase" text.  In
  *   English, this means that we must omit any "'s" suffix.  This is needed
  *   only when the phrase can be ambiguous, so pronouns don't need it since
  *   they are inherently unambiguous.  
+ *
+ *   TADS má možnost definovat vlastnictví předmětu a i když ho momentálně
+ *   vlastník nedrží, může se na předmět odvolávat jako na svůj. Problém tu
+ *   nastává v tom, že se musí správně zacházet se zájmeny můj vs. svůj:
+ *
+ *   vem mého kocoura (kocour patřící hráči, který se personalizuje s PC)
+ *   vem svého kocoura (kocour patřící PC)
+ *   sally, vem mého kocoura (kocour patřící PC)
+ *   sally, vem svého kocoura (kocour patřící sally)
  */
-grammar possessiveAdjPhrase(its): 'its' : ItsAdjProd
+grammar possessiveAdjPhrase(its): 'jeho' : ItsAdjProd
     /* we only agree with a singular ungendered noun */
     checkAnaphorAgreement(lst)
         { return lst.length() == 1 && lst[1].obj_.canMatchIt; }
 ;
-grammar possessiveAdjPhrase(his): 'his' : HisAdjProd
+grammar possessiveAdjPhrase(his): 'jeho' : HisAdjProd
     /* we only agree with a singular masculine noun */
     checkAnaphorAgreement(lst)
         { return lst.length() == 1 && lst[1].obj_.canMatchHim; }
 ;
-grammar possessiveAdjPhrase(her): 'her' : HerAdjProd
+grammar possessiveAdjPhrase(her): 'její' : HerAdjProd
     /* we only agree with a singular feminine noun */
     checkAnaphorAgreement(lst)
         { return lst.length() == 1 && lst[1].obj_.canMatchHer; }
 ;
-grammar possessiveAdjPhrase(their): 'their' : TheirAdjProd
+grammar possessiveAdjPhrase(their): 'jejich' : TheirAdjProd
     /* we only agree with a single noun that has plural usage */
     checkAnaphorAgreement(lst)
         { return lst.length() == 1 && lst[1].obj_.isPlural; }
 ;
-grammar possessiveAdjPhrase(your): 'your' : YourAdjProd
+
+grammar possessiveAdjPhrase(your):
+    'tvůj' | 'tvoje' | 'tvá' | 'tvé' | 'tvého' | 'tvojí' | 'tvému' | 'tvoji'
+    | 'tvou' | 'tvém' | 'tvým' | 'tví' | 'tvých' | 'tvými' | 'svůj' | 'svoje'
+    | 'svá' | 'své' | 'svého' | 'svojí' | 'svému' | 'svoji' | 'svou' | 'svém'
+    | 'svým' | 'sví' | 'svých' | 'svými' : YourAdjProd
     /* we are non-anaphoric */
     checkAnaphorAgreement(lst) { return nil; }
 ;
-grammar possessiveAdjPhrase(my): 'my' : MyAdjProd
+
+grammar possessiveAdjPhrase(my):
+    'můj' | 'má' | 'moje' | 'mé' | 'mého' | 'mojí' | 'mému' | 'mou' | 'moji'
+    | 'mém' | 'mým' : MyAdjProd
     /* we are non-anaphoric */
     checkAnaphorAgreement(lst) { return nil; }
 ;
 
 grammar possessiveAdjPhrase(npApostropheS):
     nounPhrase->np_ tokApostropheS->apost_ : LayeredNounPhraseProd
 
     /* get the original text without the "'s" suffix */
     getOrigMainText()
     {
         /* return just the basic noun phrase part */
         return np_.getOrigText();
     }
 ;
 
 grammar possessiveAdjPhrase(ppApostropheS):
     pluralPhrase->np_ tokApostropheS->apost_ : LayeredNounPhraseProd
 
     /* get the original text without the "'s" suffix */
     getOrigMainText()
     {
         /* return just the basic noun phrase part */
         return np_.getOrigText();
     }
 
     resolveNouns(resolver, results)
     {
         /* note that we have a plural phrase, structurally speaking */
         results.notePlural();
 
         /* inherit the default handling */
         return inherited(resolver, results);
     }
 
     /* the possessive phrase is plural */
     isPluralPossessive = true
 ;
 
 /*
  *   Possessive noun phrases.  These are similar to possessive phrases, but
  *   are stand-alone phrases that can act as nouns rather than as
  *   qualifiers for other noun phrases.  For example, for a first-person
  *   player character, "mine" would be a possessive noun phrase referring
  *   to an object owned by the player character.
  *   
  *   Note that many of the words used for possessive nouns are the same as
  *   for possessive adjectives - for example "his" is the same in either
  *   case, as are "'s" words.  However, we make the distinction internally
  *   because the two have different grammatical uses, and some of the words
  *   do differ ("her" vs "hers", for example).  
  */
-grammar possessiveNounPhrase(its): 'its': ItsNounProd;
-grammar possessiveNounPhrase(his): 'his': HisNounProd;
-grammar possessiveNounPhrase(hers): 'hers': HersNounProd;
-grammar possessiveNounPhrase(theirs): 'theirs': TheirsNounProd;
-grammar possessiveNounPhrase(yours): 'yours' : YoursNounProd;
-grammar possessiveNounPhrase(mine): 'mine' : MineNounProd;
+grammar possessiveNounPhrase(its): 'jeho': ItsNounProd;
+grammar possessiveNounPhrase(his): 'jeho': HisNounProd;
+grammar possessiveNounPhrase(hers): 'její': HersNounProd;
+grammar possessiveNounPhrase(theirs): 'jejich': TheirsNounProd;
+
+grammar possessiveNounPhrase(yours):
+    'tvůj' | 'tvoje' | 'tvá' | 'tvé' | 'tvého' | 'tvojí' | 'tvému' | 'tvoji'
+    | 'tvou' | 'tvém' | 'tvým' | 'tví' | 'tvých' | 'tvými' | 'svůj' | 'svoje'
+    | 'svá' | 'své' | 'svého' | 'svojí' | 'svému' | 'svoji' | 'svou' | 'svém'
+    | 'svým' | 'sví' | 'svých' | 'svými' : YoursNounProd;
+
+grammar possessiveNounPhrase(mine):
+    'můj' | 'má' | 'moje' | 'mé' | 'mého' | 'mojí' | 'mému' | 'mou' | 'moji'
+    | 'mém' | 'mým' : MineNounProd;
 
 grammar possessiveNounPhrase(npApostropheS):
     (nounPhrase->np_ | pluralPhrase->np_) tokApostropheS->apost_
     : LayeredNounPhraseProd
 
     /* get the original text without the "'s" suffix */
     getOrigMainText()
     {
         /* return just the basic noun phrase part */
         return np_.getOrigText();
     }
 ;
 
 
 /* ------------------------------------------------------------------------ */
 /*
  *   Simple plural phrase.  This is the most basic plural phrase, which is
  *   simply a plural noun, optionally preceded by one or more adjectives.
  *   
  *   (English doesn't have any sort of adjective declension in number, so
  *   there's no need to distinguish between plural and singular adjectives;
  *   this equivalent rule in languages with adjective-noun agreement in
  *   number would use plural adjectives here as well as plural nouns.)  
  */
 grammar simplePluralPhrase(plural): plural->plural_ : NounPhraseWithVocab
     /* generate a list of my resolved objects */
     getVocabMatchList(resolver, results, extraFlags)
     {
         local lst;
 
         /* get the list of matching plurals */
         lst = getWordMatches(plural_, &plural, resolver,
                              extraFlags, PluralTruncated);
 
         /* get the list of matching 'noun' definitions */
         local nLst = getWordMatches(plural_, &noun, resolver,
                                     extraFlags, VocabTruncated);
 
         /* get the combined list */
         local comboLst = combineWordMatches(lst, nLst);
 
         /*
          *   If we're in global scope, add in the matches for just plain
          *   'noun' properties as well.  This is important because we'll
          *   sometimes want to define a word that's actually a plural
          *   usage (in terms of the real-world English) under the 'noun'
          *   property.  This occurs particularly when a single game-world
          *   object represents a multiplicity of real-world objects.  When
          *   the scope is global, it's hard to anticipate all of the
          *   possible interactions with vocabulary along these lines, so
          *   it's easiest just to include the 'noun' matches.
          */
         if (resolver.isGlobalScope)
         {
             /* keep the combined list */
             lst = comboLst;
         }
         else if (comboLst.length() > lst.length())
         {
             /*
              *   ordinary scope, so don't include the noun matches; but
              *   since we found extra items to add, at least mark the
              *   plural matches as potentially ambiguous
              */
             lst.forEach({x: x.flags_ |= UnclearDisambig});
         }
 
         /* return the result list */
         return lst;
     }
     getAdjustedTokens()
     {
         return [plural_, &plural];
     }
 ;
 
 grammar simplePluralPhrase(adj): adjWord->adj_ simplePluralPhrase->np_ :
     NounPhraseWithVocab
 
     /* resolve my object list */
     getVocabMatchList(resolver, results, extraFlags)
     {
         /*
          *   return the list of objects in scope matching our adjective
          *   plus the list from the underlying noun phrase
          */
         return intersectNounLists(
             adj_.getVocabMatchList(resolver, results, extraFlags),
             np_.getVocabMatchList(resolver, results, extraFlags));
     }
     getAdjustedTokens()
     {
         return adj_.getAdjustedTokens() + np_.getAdjustedTokens();
     }
 ;
 
 grammar simplePluralPhrase(poundNum):
     poundNumberPhrase->num_ simplePluralPhrase->np_
     : NounPhraseWithVocab
 
     /* resolve my object list */
     getVocabMatchList(resolver, results, extraFlags)
     {
         local baseList;
         local numList;
 
         /* get the base list for the rest of the phrase */
         baseList = np_.getVocabMatchList(resolver, results, extraFlags);
 
         /* get the numeric matches, including numeric wildcards */
         numList = getWordMatches(num_.getStrVal(), &adjective,
                                  resolver, extraFlags, VocabTruncated)
                   + getWordMatches('#', &adjective,
                                    resolver, extraFlags, VocabTruncated);
 
         /* return the intersection of the lists */
         return intersectNounLists(numList, baseList);
     }
     getAdjustedTokens()
     {
         return [num_.getStrVal(), &adjective] + np_.getAdjustedTokens();
     }
 ;
 
 /*
  *   A simple plural phrase can end with an adjective and "ones," as in
  *   "the red ones."
  */
 grammar simplePluralPhrase(adjAndOnes): adjective->adj_ 'ones'
     : NounPhraseWithVocab
     getVocabMatchList(resolver, results, extraFlags)
     {
         /* generate a list of objects matching the adjective */
         return getWordMatches(adj_, &adjective, resolver,
                               extraFlags | EndsWithAdj, VocabTruncated);
     }
     getAdjustedTokens()
     {
         return [adj_, &adjective];
     }
 ;
 
 /*
  *   If the command has qualifiers that require a plural, but omits
  *   everything else, we can have an empty simple noun phrase.
  */
 grammar simplePluralPhrase(empty): [badness 600] : NounPhraseWithVocab
     getVocabMatchList(resolver, results, extraFlags)
     {
         /* we have an empty noun phrase */
         return results.emptyNounPhrase(resolver);
     }
     getAdjustedTokens()
     {
         return [];
     }
 ;
 
 /*
  *   A simple plural phrase can match unknown words as a last resort.
  */
 grammar simplePluralPhrase(misc):
     [badness 300] miscWordList->lst_ : NounPhraseWithVocab
     getVocabMatchList(resolver, results, extraFlags)
     {
         /* get the match list from the underlying list */
         local lst = lst_.getVocabMatchList(resolver, results, extraFlags);
 
         /*
          *   if there are no matches, note in the results that we have an
          *   arbitrary word list that doesn't correspond to any object
          */
         if (lst == nil || lst.length() == 0)
             results.noteMiscWordList(lst_.getOrigText());
 
         /* return the vocabulary match list */
         return lst;
     }
     getAdjustedTokens()
     {
         return lst_.getAdjustedTokens();
     }
 ;
 
 
 /* ------------------------------------------------------------------------ */
 /*
  *   An "adjective phrase" is a phrase made entirely of adjectives.
  */
 grammar adjPhrase(adj): adjective->adj_ : AdjPhraseWithVocab
     getVocabMatchList(resolver, results, extraFlags)
     {
         /* note the adjective ending */
         results.noteAdjEnding();
 
         /* return the match list */
         local lst = getWordMatches(adj_, &adjective, resolver,
                                    extraFlags | EndsWithAdj, VocabTruncated);
 
         /* if in global scope, also try a noun interpretation */
         if (resolver.isGlobalScope)
             lst = addNounMatchList(lst, resolver, results, extraFlags);
 
         /* return the result */
         return lst;
     }
 
     getAdjustedTokens()
     {
         return [adj_, &adjective];
     }
 ;
 
 grammar adjPhrase(adjAdj): adjective->adj_ adjPhrase->ap_
     : NounPhraseWithVocab
     /* generate a list of my resolved objects */
     getVocabMatchList(resolver, results, extraFlags)
     {
         /*
          *   return the list of objects in scope matching our adjective
          *   plus the list from the underlying adjective phrase
          */
         return intersectWordMatches(
             adj_, &adjective, resolver, extraFlags, VocabTruncated,
             ap_.getVocabMatchList(resolver, results, extraFlags));
     }
     getAdjustedTokens()
     {
         return [adj_, &adjective] + ap_.getAdjustedTokens();
     }
 ;
 
 
 /* ------------------------------------------------------------------------ */
 /*
  *   A "topic" is a special type of noun phrase used in commands like "ask
  *   <actor> about <topic>."  We define a topic as simply an ordinary
  *   single-noun phrase.  We distinguish this in the grammar to allow games
  *   to add special syntax for these.  
  */
 grammar topicPhrase(main): singleNoun->np_ : TopicProd
 ;
 
 /*
  *   Explicitly match a miscellaneous word list as a topic.
  *
  *   This might seem redundant with the ordinary topicPhrase that accepts a
  *   singleNoun, because singleNoun can match a miscellaneous word list.
  *   The difference is that singleNoun only matches a miscWordList with a
  *   "badness" value, whereas we match a miscWordList here without any
  *   badness.  We want to be more tolerant of unrecognized input in topic
  *   phrases than in ordinary noun phrases, because it's in the nature of
  *   topic phrases to go outside of what's implemented directly in the
  *   simulation model.  At a grammatical level, we don't want to treat
  *   topic phrases that we can resolve to the simulation model any
  *   differently than we treat those we can't resolve, so we must add this
  *   rule to eliminate the badness that singleNoun associated with a
  *   miscWordList match.
  *
  *   Note that we do prefer resolvable noun phrase matches to miscWordList
  *   matches, but we handle this preference with the resolver's scoring
  *   mechanism rather than with badness.
  */
 grammar topicPhrase(misc): miscWordList->np_ : TopicProd
    resolveNouns(resolver, results)
    {
        /* note in the results that we have an arbitrary word list */
        results.noteMiscWordList(np_.getOrigText());
 
        /* inherit the default TopicProd behavior */
        return inherited(resolver, results);
    }
 ;
 
 /* ------------------------------------------------------------------------ */
 /*
  *   A "quoted string" phrase is a literal enclosed in single or double
  *   quotes.
  *
  *   Note that this is a separate production from literalPhrase.  This
  *   production can be used when *only* a quoted string is allowed.  The
  *   literalPhrase production allows both quoted and unquoted text.
  */
 grammar quotedStringPhrase(main): tokString->str_ : LiteralProd
     /*
      *   get my string, with the quotes trimmed off (so we return simply
      *   the contents of the string)
      */
     getStringText() { return stripQuotesFrom(str_); }
 ;
 
 /*
  *   Service routine: strip quotes from a *possibly* quoted string.  If the
  *   string starts with a quote, we'll remove the open quote.  If it starts
  *   with a quote and it ends with a corresponding close quote, we'll
  *   remove that as well.  
  */
 stripQuotesFrom(str)
 {
     local hasOpen;
     local hasClose;
 
     /* presume we won't find open or close quotes */
     hasOpen = hasClose = nil;
 
     /*
      *   Check for quotes.  We'll accept regular ASCII "straight" single
      *   or double quotes, as well as Latin-1 curly single or double
      *   quotes.  The curly quotes must be used in their normal
      */
     if (str.startsWith('\'') || str.startsWith('"'))
     {
         /* single or double quote - check for a matching close quote */
         hasOpen = true;
         hasClose = (str.length() > 2 && str.endsWith(str.substr(1, 1)));
     }
     else if (str.startsWith('`'))
     {
         /* single in-slanted quote - check for either type of close */
         hasOpen = true;
         hasClose = (str.length() > 2
                     && (str.endsWith('`') || str.endsWith('\'')));
     }
     else if (str.startsWith('\u201C'))
     {
         /* it's a curly double quote */
         hasOpen = true;
         hasClose = str.endsWith('\u201D');
     }
     else if (str.startsWith('\u2018'))
     {
         /* it's a curly single quote */
         hasOpen = true;
         hasClose = str.endsWith('\u2019');
     }
 
     /* trim off the quotes */
     if (hasOpen)
     {
         if (hasClose)
             str = str.substr(2, str.length() - 2);
         else
             str = str.substr(2);
     }
 
     /* return the modified text */
     return str;
 }
 
 /* ------------------------------------------------------------------------ */
 /*
  *   A "literal" is essentially any phrase.  This can include a quoted
  *   string, a number, or any set of word tokens.
  */
 grammar literalPhrase(string): quotedStringPhrase->str_ : LiteralProd
     getLiteralText(results, action, which)
     {
         /* get the text from our underlying quoted string */
         return str_.getStringText();
     }
 
     getTentativeLiteralText()
     {
         /*
          *   our result will never change, so our tentative text is the
          *   same as our regular literal text
          */
         return str_.getStringText();
     }
 
     resolveLiteral(results)
     {
         /* flag the literal text */
         results.noteLiteral(str_.getOrigText());
     }
 ;
 
 grammar literalPhrase(miscList): miscWordList->misc_ : LiteralProd
     getLiteralText(results, action, which)
     {
         /* get my original text */
         local txt = misc_.getOrigText();
 
         /*
          *   if our underlying miscWordList has only one token, strip
          *   quotes, in case that token is a quoted string token
          */
         if (misc_.getOrigTokenList().length() == 1)
             txt = stripQuotesFrom(txt);
 
         /* return the text */
         return txt;
     }
 
     getTentativeLiteralText()
     {
         /* our regular text is permanent, so simply use it now */
         return misc_.getOrigText();
     }
 
     resolveLiteral(results)
     {
         /*
          *   note the length of our literal phrase - when we have a choice
          *   of interpretations, we prefer to choose shorter literal
          *   phrases, since this means that we'll have more of our tokens
          *   being fully interpreted rather than bunched into an
          *   uninterpreted literal
          */
         results.noteLiteral(misc_.getOrigText());
     }
 ;
 
 /*
  *   In case we have a verb grammar rule that calls for a literal phrase,
  *   but the player enters a command with nothing in that slot, match an
  *   empty token list as a last resort.  Since this phrasing has a badness,
  *   we won't match it unless we don't have any better structural match.
  */
 grammar literalPhrase(empty): [badness 400]: EmptyLiteralPhraseProd
     resolveLiteral(results) { }
 ;
 
 /* ------------------------------------------------------------------------ */
 /*
  *   An miscellaneous word list is a list of one or more words of any kind:
  *   any word, any integer, or any apostrophe-S token will do.  Note that
  *   known and unknown words can be mixed in an unknown word list; we care
  *   only that the list is made up of tokWord, tokInt, tokApostropheS,
  *   and/or abbreviation-period tokens.
  *
  *   Note that this kind of phrase is often used with a 'badness' value.
  *   However, we don't assign any badness here, because a miscellaneous
  *   word list might be perfectly valid in some contexts; instead, any
  *   productions that include a misc word list should specify badness as
  *   desired.
  */
 grammar miscWordList(wordOrNumber):
     tokWord->txt_ | tokInt->txt_ | tokApostropheS->txt_
     | tokPoundInt->txt_ | tokString->txt_ | tokAbbrPeriod->txt_
     : NounPhraseWithVocab
     getVocabMatchList(resolver, results, extraFlags)
     {
         /* we don't match anything directly with our vocabulary */
         return [];
     }
     getAdjustedTokens()
     {
         /* our token type is the special miscellaneous word type */
         return [txt_, &miscWord];
     }
 ;
 
 grammar miscWordList(list):
     (tokWord->txt_ | tokInt->txt_ | tokApostropheS->tok_ | tokAbbrPeriod->txt_
      | tokPoundInt->txt_ | tokString->txt_) miscWordList->lst_
     : NounPhraseWithVocab
     getVocabMatchList(resolver, results, extraFlags)
     {
         /* we don't match anything directly with our vocabulary */
         return [];
     }
     getAdjustedTokens()
     {
         /* our token type is the special miscellaneous word type */
         return [txt_, &miscWord] + lst_.getAdjustedTokens();
     }
 ;
 
 /* ------------------------------------------------------------------------ */
 /*
  *   A main disambiguation phrase consists of a disambiguation phrase,
  *   optionally terminated with a period.
  */
 grammar mainDisambigPhrase(main):
     disambigPhrase->dp_
     | disambigPhrase->dp_ '.'
     : BasicProd
     resolveNouns(resolver, results)
     {
         return dp_.resolveNouns(resolver, results);
     }
     getResponseList() { return dp_.getResponseList(); }
 ;
 
 /*
  *   A "disambiguation phrase" is a phrase that answers a disambiguation
  *   question ("which book do you mean...").
  *   
  *   A disambiguation question can be answered with several types of
  *   syntax:
  *   
  *.  all/everything/all of them
  *.  both/both of them
  *.  any/any of them
  *.  <disambig list>
  *.  the <ordinal list> ones
  *.  the former/the latter
  *   
  *   Note that we assign non-zero badness to all of the ordinal
  *   interpretations, so that we will take an actual vocabulary
  *   interpretation instead of an ordinal interpretation whenever possible.
  *   For example, if an object's name is actually "the third button," this
  *   will give us greater affinity for using "third" as an adjective than
  *   as an ordinal in our own list.  
  */
 grammar disambigPhrase(all):
     'all' | 'everything' | 'all' 'of' 'them' : DisambigProd
     resolveNouns(resolver, results)
     {
         /* they want everything we proposed - return the whole list */
         return removeAmbigFlags(resolver.getAll(self));
     }
 
     /* there's only me in the response list */
     getResponseList() { return [self]; }
 ;
 
 grammar disambigPhrase(both): 'both' | 'both' 'of' 'them' : DisambigProd
     resolveNouns(resolver, results)
     {
         /*
          *   they want two items - return the whole list (if it has more
          *   than two items, we'll simply act as though they wanted all of
          *   them)
          */
         return removeAmbigFlags(resolver.getAll(self));
     }
 
     /* there's only me in the response list */
     getResponseList() { return [self]; }
 ;
 
 grammar disambigPhrase(any): 'any' | 'any' 'of' 'them' : DisambigProd
     resolveNouns(resolver, results)
     {
         local lst;
 
         /* they want any item - arbitrarily pick the first one */
         lst = resolver.matchList.sublist(1, 1);
 
         /*
          *   add the "unclear disambiguation" flag to the item we picked,
          *   to indicate that the selection was arbitrary
          */
         if (lst.length() > 0)
             lst[1].flags_ |= UnclearDisambig;
 
         /* return the result */
         return lst;
     }
 
     /* there's only me in the response list */
     getResponseList() { return [self]; }
 ;
 
 grammar disambigPhrase(list): disambigList->lst_ : DisambigProd
     resolveNouns(resolver, results)
     {
         return removeAmbigFlags(lst_.resolveNouns(resolver, results));
     }
 
     /* there's only me in the response list */
     getResponseList() { return lst_.getResponseList(); }
 ;
 
 grammar disambigPhrase(ordinalList):
     disambigOrdinalList->lst_ 'ones'
     | 'the' disambigOrdinalList->lst_ 'ones'
     : DisambigProd
 
     resolveNouns(resolver, results)
     {
         /* return the list with the ambiguity flags removed */
         return removeAmbigFlags(lst_.resolveNouns(resolver, results));
     }
 
     /* the response list consists of my single ordinal list item */
     getResponseList() { return [lst_]; }
 ;
 
 /*
  *   A disambig list consists of one or more disambig list items, connected
  *   by noun phrase conjunctions.  
  */
 grammar disambigList(single): disambigListItem->item_ : DisambigProd
     resolveNouns(resolver, results)
     {
         return item_.resolveNouns(resolver, results);
     }
 
     /* the response list consists of my single item */
     getResponseList() { return [item_]; }
 ;
 
 grammar disambigList(list):
     disambigListItem->item_ commandOrNounConjunction disambigList->lst_
     : DisambigProd
 
     resolveNouns(resolver, results)
     {
         return item_.resolveNouns(resolver, results)
             + lst_.resolveNouns(resolver, results);
     }
 
     /* my response list consists of each of our list items */
     getResponseList() { return [item_] + lst_.getResponseList(); }
 ;
 
 /*
  *   Base class for ordinal disambiguation items
  */
 class DisambigOrdProd: DisambigProd
     resolveNouns(resolver, results)
     {
         /* note the ordinal match */
         results.noteDisambigOrdinal();
 
         /* select the result by the ordinal */
         return selectByOrdinal(ord_, resolver, results);
     }
 
     selectByOrdinal(ordTok, resolver, results)
     {
         local idx;
         local matchList = resolver.ordinalMatchList;
 
         /*
          *   look up the meaning of the ordinal word (note that we assume
          *   that each ordinalWord is unique, since we only create one of
          *   each)
          */
         idx = cmdDict.findWord(ordTok, &ordinalWord)[1].numval;
 
         /*
          *   if it's the special value -1, it indicates that we should
          *   select the *last* item in the list
          */
         if (idx == -1)
             idx = matchList.length();
 
         /* if it's outside the limits of the match list, it's an error */
         if (idx > matchList.length())
         {
             /* note the problem */
             results.noteOrdinalOutOfRange(ordTok);
 
             /* no results */
             return [];
         }
 
         /* return the selected item as a one-item list */
         return matchList.sublist(idx, 1);
     }
 ;
 
 /*
  *   A disambig vocab production is the base class for disambiguation
  *   phrases that involve vocabulary words.
  */
 class DisambigVocabProd: DisambigProd
 ;
 
 /*
  *   A disambig list item consists of:
  *
  *.  first/second/etc
  *.  the first/second/etc
  *.  first one/second one/etc
  *.  the first one/the second one/etc
  *.  <compound noun phrase>
  *.  possessive
  */
 
 grammar disambigListItem(ordinal):
     ordinalWord->ord_
     | ordinalWord->ord_ 'one'
     | 'the' ordinalWord->ord_
     | 'the' ordinalWord->ord_ 'one'
     : DisambigOrdProd
 ;
 
 grammar disambigListItem(noun):
     completeNounPhraseWithoutAll->np_
     | terminalNounPhrase->np_
     : DisambigVocabProd
     resolveNouns(resolver, results)
     {
         /* get the matches for the underlying noun phrase */
         local lst = np_.resolveNouns(resolver, results);
 
         /* note the matches */
         results.noteMatches(lst);
 
         /* return the match list */
         return lst;
     }
 ;
 
 grammar disambigListItem(plural):
     pluralPhrase->np_
     : DisambigVocabProd
     resolveNouns(resolver, results)
     {
         local lst;
 
         /*
          *   get the underlying match list; since we explicitly have a
          *   plural, the result doesn't need to be unique, so simply
          *   return everything we find
          */
         lst = np_.resolveNouns(resolver, results);
 
         /*
          *   if we didn't get anything, it's an error; otherwise, take
          *   everything, since we explicitly wanted a plural usage
          */
         if (lst.length() == 0)
             results.noMatch(resolver.getAction(), np_.getOrigText());
         else
             results.noteMatches(lst);
 
         /* return the list */
         return lst;
     }
 ;
 
 grammar disambigListItem(possessive): possessiveNounPhrase->poss_
     : DisambigPossessiveProd
 ;
 
 /*
  *   A disambig ordinal list consists of two or more ordinal words
  *   separated by noun phrase conjunctions.  Note that there is a minimum
  *   of two entries in the list.
  */
 grammar disambigOrdinalList(tail):
     ordinalWord->ord1_ ('and' | ',') ordinalWord->ord2_ : DisambigOrdProd
     resolveNouns(resolver, results)
     {
         /* note the pair of ordinal matches */
         results.noteDisambigOrdinal();
         results.noteDisambigOrdinal();
 
         /* combine the selections of our two ordinals */
         return selectByOrdinal(ord1_, resolver, results)
             + selectByOrdinal(ord2_, resolver, results);
     }
 ;
 
 grammar disambigOrdinalList(head):
     ordinalWord->ord_ ('and' | ',') disambigOrdinalList->lst_
     : DisambigOrdProd
     resolveNouns(resolver, results)
     {
         /* note the ordinal match */
         results.noteDisambigOrdinal();
 
         /* combine the selections of our ordinal and the sublist */
         return selectByOrdinal(ord_, resolver, results)
             + lst_.resolveNouns(resolver, results);
     }
 ;
 
 
 /* ------------------------------------------------------------------------ */
 /*
  *   Ordinal words.  We define a limited set of these, since we only use
  *   them in a few special contexts where it would be unreasonable to need
  *   even as many as define here.
  */
 #define defOrdinal(str, val) object ordinalWord=#@str numval=val
 
-defOrdinal(former, 1);
-defOrdinal(first, 1);
-defOrdinal(second, 2);
-defOrdinal(third, 3);
-defOrdinal(fourth, 4);
-defOrdinal(fifth, 5);
-defOrdinal(sixth, 6);
-defOrdinal(seventh, 7);
-defOrdinal(eighth, 8);
-defOrdinal(ninth, 9);
-defOrdinal(tenth, 10);
-defOrdinal(eleventh, 11);
-defOrdinal(twelfth, 12);
-defOrdinal(thirteenth, 13);
-defOrdinal(fourteenth, 14);
-defOrdinal(fifteenth, 15);
-defOrdinal(sixteenth, 16);
-defOrdinal(seventeenth, 17);
-defOrdinal(eighteenth, 18);
-defOrdinal(nineteenth, 19);
-defOrdinal(twentieth, 20);
-defOrdinal(1st, 1);
-defOrdinal(2nd, 2);
-defOrdinal(3rd, 3);
-defOrdinal(4th, 4);
-defOrdinal(5th, 5);
-defOrdinal(6th, 6);
-defOrdinal(7th, 7);
-defOrdinal(8th, 8);
-defOrdinal(9th, 9);
-defOrdinal(10th, 10);
-defOrdinal(11th, 11);
-defOrdinal(12th, 12);
-defOrdinal(13th, 13);
-defOrdinal(14th, 14);
-defOrdinal(15th, 15);
-defOrdinal(16th, 16);
-defOrdinal(17th, 17);
-defOrdinal(18th, 18);
-defOrdinal(19th, 19);
-defOrdinal(20th, 20);
+defOrdinal(první, 1);
+defOrdinal(druhý, 2);
+defOrdinal(druhá, 2);
+defOrdinal(druhé, 2);
+defOrdinal(druzí, 2);
+defOrdinal(třetí, 3);
+defOrdinal(čtvrtý, 4);
+defOrdinal(čtvrtá, 4);
+defOrdinal(čtvrté, 4);
+defOrdinal(čtvrtí, 4);
+defOrdinal(pátý, 5);
+defOrdinal(pátá, 5);
+defOrdinal(páté, 5);
+defOrdinal(pátí, 5);
+defOrdinal(šestý, 6);
+defOrdinal(šestá, 6);
+defOrdinal(šesté, 6);
+defOrdinal(šestí, 6);
+defOrdinal(sedmý, 7);
+defOrdinal(sedmá, 7);
+defOrdinal(sedmé, 7);
+defOrdinal(sedmí, 7);
+defOrdinal(osmý, 8);
+defOrdinal(osmá, 8);
+defOrdinal(osmé, 8);
+defOrdinal(osmí, 8);
+defOrdinal(devátý, 9);
+defOrdinal(devátá, 9);
+defOrdinal(deváté, 9);
+defOrdinal(devátí, 9);
+defOrdinal(desátý, 10);
+defOrdinal(desátá, 10);
+defOrdinal(desáté, 10);
+defOrdinal(desátí, 10);
+defOrdinal(jedenáctý, 11);
+defOrdinal(jedenáctá, 11);
+defOrdinal(jedenácté, 11);
+defOrdinal(jedenáctí, 11);
+defOrdinal(dvanáctý, 12);
+defOrdinal(dvanáctá, 12);
+defOrdinal(dvanácté, 12);
+defOrdinal(dvanáctí, 12);
+defOrdinal(třináctý, 13);
+defOrdinal(třináctá, 13);
+defOrdinal(třinácté, 13);
+defOrdinal(třináctí, 13);
+defOrdinal(čtrnáctý, 14);
+defOrdinal(čtrnáctá, 14);
+defOrdinal(čtrnácté, 14);
+defOrdinal(čtrnáctí, 14);
+defOrdinal(patnáctý, 15);
+defOrdinal(patnáctá, 15);
+defOrdinal(patnácté, 15);
+defOrdinal(patnáctí, 15);
+defOrdinal(šestnáctý, 16);
+defOrdinal(šestnáctá, 16);
+defOrdinal(šestnácté, 16);
+defOrdinal(šestnáctí, 16);
+defOrdinal(sedmnáctý, 17);
+defOrdinal(sedmnáctá, 17);
+defOrdinal(sedmnácté, 17);
+defOrdinal(sedmnáctí, 17);
+defOrdinal(osmnáctý, 18);
+defOrdinal(osmnáctá, 18);
+defOrdinal(osmnácté, 18);
+defOrdinal(osmnáctí, 18);
+defOrdinal(devatenáctý, 19);
+defOrdinal(devatenáctá, 19);
+defOrdinal(devatenácté, 19);
+defOrdinal(devatenáctí, 19);
+defOrdinal(dvacátý, 20);
+defOrdinal(dvacátá, 20);
+defOrdinal(dvacáté, 20);
+defOrdinal(dvacátí, 20);
+defOrdinal(1., 1);
+defOrdinal(2., 2);
+defOrdinal(3., 3);
+defOrdinal(4., 4);
+defOrdinal(5., 5);
+defOrdinal(6., 6);
+defOrdinal(7., 7);
+defOrdinal(8., 8);
+defOrdinal(9., 9);
+defOrdinal(10., 10);
+defOrdinal(11., 11);
+defOrdinal(12., 12);
+defOrdinal(13., 13);
+defOrdinal(14., 14);
+defOrdinal(15., 15);
+defOrdinal(16., 16);
+defOrdinal(17., 17);
+defOrdinal(18., 18);
+defOrdinal(19., 19);
+defOrdinal(20., 20);
 
 /*
  *   the special 'last' ordinal - the value -1 is special to indicate the
  *   last item in a list
  */
-defOrdinal(last, -1);
-defOrdinal(latter, -1);
+defOrdinal(poslední, -1);
 
 
 /* ------------------------------------------------------------------------ */
 /*
  *   A numeric production.  These can be either spelled-out numbers (such
  *   as "fifty-seven") or numbers entered in digit form (as in "57").
  */
 class NumberProd: BasicProd
     /* get the numeric (integer) value */
     getval() { return 0; }
 
     /*
      *   Get the string version of the numeric value.  This should return
      *   a string, but the string should be in digit form.  If the
      *   original entry was in digit form, then the original entry should
      *   be returned; otherwise, a string should be constructed from the
      *   integer value.  By default, we'll do the latter.
      */
     getStrVal() { return toString(getval()); }
 ;
 
 /*
  *   A quantifier is simply a number, entered with numerals or spelled out.
  */
 grammar numberPhrase(digits): tokInt->num_ : NumberProd
     /* get the numeric value */
     getval() { return toInteger(num_); }
 
     /*
      *   get the string version of the numeric value - since the token was
      *   an integer to start with, return the actual integer value
      */
     getStrVal() { return num_; }
 ;
 
 grammar numberPhrase(spelled): spelledNumber->num_ : NumberProd
     /* get the numeric value */
     getval() { return num_.getval(); }
 ;
 
 /*
  *   A number phrase preceded by a pound sign.  We distinguish this kind of
  *   number phrase from plain numbers, since this kind has a somewhat more
  *   limited set of valid contexts.  
  */
 grammar poundNumberPhrase(main): tokPoundInt->num_ : NumberProd
     /*
      *   get the numeric value - a tokPoundInt token has a pound sign
      *   followed by digits, so the numeric value is the value of the
      *   substring following the '#' sign
      */
     getval() { return toInteger(num_.substr(2)); }
 
     /*
      *   get the string value - we have a number token following the '#',
      *   so simply return the part after the '#'
      */
     getStrVal() { return num_.substr(2); }
 ;
 
 
 /*
  *   Number literals.  We'll define a set of special objects for numbers:
  *   each object defines a number and a value for the number.
  */
 #define defDigit(num, val) object digitWord=#@num numval=val
 #define defTeen(num, val)  object teenWord=#@num numval=val
 #define defTens(num, val)  object tensWord=#@num numval=val
 
-defDigit(one, 1);
-defDigit(two, 2);
-defDigit(three, 3);
-defDigit(four, 4);
-defDigit(five, 5);
-defDigit(six, 6);
-defDigit(seven, 7);
-defDigit(eight, 8);
-defDigit(nine, 9);
-defTeen(ten, 10);
-defTeen(eleven, 11);
-defTeen(twelve, 12);
-defTeen(thirteen, 13);
-defTeen(fourteen, 14);
-defTeen(fifteen, 15);
-defTeen(sixteen, 16);
-defTeen(seventeen, 17);
-defTeen(eighteen, 18);
-defTeen(nineteen, 19);
-defTens(twenty, 20);
-defTens(thirty, 30);
-defTens(forty, 40);
-defTens(fifty, 50);
-defTens(sixty, 60);
-defTens(seventy, 70);
-defTens(eighty, 80);
-defTens(ninety, 90);
+defDigit(jeden, 1);
+defDigit(jedna, 1);
+defDigit(jedno, 1);
+defDigit(jedni, 1);
+defDigit(jedny, 1);
+defDigit(dva, 2);
+defDigit(dvě, 2);
+defDigit(oba, 2);
+defDigit(obě, 2);
+defDigit(tři, 3);
+defDigit(čtyři, 4);
+defDigit(pět, 5);
+defDigit(šest, 6);
+defDigit(sedm, 7);
+defDigit(osm, 8);
+defDigit(devět, 9);
+defTeen(deset, 10);
+defTeen(jedenáct, 11);
+defTeen(dvanáct, 12);
+defTeen(třináct, 13);
+defTeen(čtrnáct, 14);
+defTeen(patnáct, 15);
+defTeen(šestnáct, 16);
+defTeen(sedmnáct, 17);
+defTeen(osmnáct, 18);
+defTeen(devatenáct, 19);
+defTens(dvacet, 20);
+defTens(třicet, 30);
+defTens(ctyřicet, 40);
+defTens(padesát, 50);
+defTens(šedesát, 60);
+defTens(sedmdesát, 70);
+defTens(osmdesát, 80);
+defTens(devadesát, 90);
 
 grammar spelledSmallNumber(digit): digitWord->num_ : NumberProd
     getval()
     {
         /*
          *   Look up the units word - there should be only one in the
          *   dictionary, since these are our special words.  Return the
          *   object's numeric value property 'numval', which gives the
          *   number for the name.
          */
         return cmdDict.findWord(num_, &digitWord)[1].numval;
     }
 ;
 
 grammar spelledSmallNumber(teen): teenWord->num_ : NumberProd
     getval()
     {
         /* look up the dictionary word for the number */
         return cmdDict.findWord(num_, &teenWord)[1].numval;
     }
 ;
 
 grammar spelledSmallNumber(tens): tensWord->num_ : NumberProd
     getval()
     {
         /* look up the dictionary word for the number */
         return cmdDict.findWord(num_, &tensWord)[1].numval;
     }
 ;
 
 grammar spelledSmallNumber(tensAndUnits):
     tensWord->tens_ '-'->sep_ digitWord->units_
     | tensWord->tens_ digitWord->units_
     : NumberProd
     getval()
     {
         /* look up the words, and add up the values */
         return cmdDict.findWord(tens_, &tensWord)[1].numval
             + cmdDict.findWord(units_, &digitWord)[1].numval;
     }
 ;
 
-grammar spelledSmallNumber(zero): 'zero' : NumberProd
+grammar spelledSmallNumber(zero): 'nula' | 'nic' | 'žádný' | 'žádná' | 'žádné' | 'žádní' : NumberProd
     getval() { return 0; }
 ;
 
 grammar spelledHundred(small): spelledSmallNumber->num_ : NumberProd
     getval() { return num_.getval(); }
 ;
 
 grammar spelledHundred(hundreds): spelledSmallNumber->hun_ 'hundred'
     : NumberProd
     getval() { return hun_.getval() * 100; }
 ;
 
 grammar spelledHundred(hundredsPlus):
     spelledSmallNumber->hun_ 'hundred' spelledSmallNumber->num_
     | spelledSmallNumber->hun_ 'hundred' 'and'->and_ spelledSmallNumber->num_
     : NumberProd
     getval() { return hun_.getval() * 100 + num_.getval(); }
 ;
 
-grammar spelledHundred(aHundred): 'a' 'hundred' : NumberProd
+grammar spelledHundred(aHundred): 'sto' : NumberProd
     getval() { return 100; }
 ;
 
 grammar spelledHundred(aHundredPlus):
-    'a' 'hundred' 'and' spelledSmallNumber->num_
+    'sto' ('a' | ) spelledSmallNumber->num_
     : NumberProd
     getval() { return 100 + num_.getval(); }
 ;
 
 grammar spelledThousand(thousands): spelledHundred->thou_ 'thousand'
     : NumberProd
     getval() { return thou_.getval() * 1000; }
 ;
 
 grammar spelledThousand(thousandsPlus):
     spelledHundred->thou_ 'thousand' spelledHundred->num_
     : NumberProd
     getval() { return thou_.getval() * 1000 + num_.getval(); }
 ;
 
 grammar spelledThousand(thousandsAndSmall):
     spelledHundred->thou_ 'thousand' 'and' spelledSmallNumber->num_
     : NumberProd
     getval() { return thou_.getval() * 1000 + num_.getval(); }
 ;
 
 grammar spelledThousand(aThousand): 'a' 'thousand' : NumberProd
     getval() { return 1000; }
 ;
 
 grammar spelledThousand(aThousandAndSmall):
     'a' 'thousand' 'and' spelledSmallNumber->num_
     : NumberProd
     getval() { return 1000 + num_.getval(); }
 ;
 
 grammar spelledMillion(millions): spelledHundred->mil_ 'million': NumberProd
     getval() { return mil_.getval() * 1000000; }
 ;
 
 grammar spelledMillion(millionsPlus):
     spelledHundred->mil_ 'million'
     (spelledThousand->nxt_ | spelledHundred->nxt_)
     : NumberProd
     getval() { return mil_.getval() * 1000000 + nxt_.getval(); }
 ;
 
 grammar spelledMillion(aMillion): 'a' 'million' : NumberProd
     getval() { return 1000000; }
 ;
 
 grammar spelledMillion(aMillionAndSmall):
     'a' 'million' 'and' spelledSmallNumber->num_
     : NumberProd
     getval() { return 1000000 + num_.getval(); }
 ;
 
 grammar spelledMillion(millionsAndSmall):
     spelledHundred->mil_ 'million' 'and' spelledSmallNumber->num_
     : NumberProd
     getval() { return mil_.getval() * 1000000 + num_.getval(); }
 ;
 
 grammar spelledNumber(main):
     spelledHundred->num_
     | spelledThousand->num_
     | spelledMillion->num_
     : NumberProd
     getval() { return num_.getval(); }
 ;
 
 
 /* ------------------------------------------------------------------------ */
 /*
  *   "OOPS" command syntax
  */
 grammar oopsCommand(main):
     oopsPhrase->oops_ | oopsPhrase->oops_ '.' : BasicProd
     getNewTokens() { return oops_.getNewTokens(); }
 ;
 
 grammar oopsPhrase(main):
-    'oops' miscWordList->lst_
-    | 'oops' ',' miscWordList->lst_
-    | 'o' miscWordList->lst_
-    | 'o' ',' miscWordList->lst_
+    'oprava' miscWordList->lst_ | 'oprava' ',' miscWordList->lst_
+    | 'opr' miscWordList->lst_ | 'opr' ',' miscWordList->lst_
+    | 'o' miscWordList->lst_ | 'o' ',' miscWordList->lst_
     : BasicProd
     getNewTokens() { return lst_.getOrigTokenList(); }
 ;
 
 grammar oopsPhrase(missing):
-    'oops' | 'o'
+    'oprava' | 'opr' | 'o'
     : BasicProd
     getNewTokens() { return nil; }
 ;
 
 /* ------------------------------------------------------------------------ */
 /*
  *   finishGame options.  We provide descriptions and keywords for the
  *   option objects here, because these are inherently language-specific.
  *   
  *   Note that we provide hyperlinks for our descriptions when possible.
  *   When we're in plain text mode, we can't show links, so we'll instead
  *   show an alternate form with the single-letter response highlighted in
  *   the text.  We don't highlight the single-letter response in the
  *   hyperlinked version because (a) if the user wants a shortcut, they can
  *   simply click the hyperlink, and (b) most UI's that show hyperlinks
  *   show a distinctive appearance for the hyperlink itself, so adding even
  *   more highlighting within the hyperlink starts to look awfully busy.  
  */
 modify finishOptionQuit
-    desc = "<<aHrefAlt('quit', 'QUIT', '<b>Q</b>UIT', 'Leave the story')>>"
-    responseKeyword = 'quit'
-    responseChar = 'q'
+    desc = "dát <<aHrefAlt('konec', 'KONEC', '<b>K</b>ONEC', 'Ukončit příběh')>> hry"
+    responseKeyword = 'konec'
+    responseChar = 'k'
 ;
 
 modify finishOptionRestore
-    desc = "<<aHrefAlt('restore', 'RESTORE', '<b>R</b>ESTORE',
-            'Restore a saved position')>> a saved position"
-    responseKeyword = 'restore'
-    responseChar = 'r'
+    desc = "<<aHrefAlt('nahrát', 'NAHRÁT', '<b>N</b>AHRÁT',
+            'Nahrát uloženou pozici')>> uloženou pozici"
+    responseKeyword = 'nahrát'
+    responseChar = 'n'
 ;
 
 modify finishOptionRestart
-    desc = "<<aHrefAlt('restart', 'RESTART', 'RE<b>S</b>TART',
-            'Start the story over from the beginning')>> the story"
-    responseKeyword = 'restart'
+    desc = "<<aHrefAlt('restartovat', 'RESTARTOVAT', 'RE<b>S</b>TARTOVAT',
+            'Spustit příběh od začátku')>> příběh"
+    responseKeyword = 'restartovat'
     responseChar = 's'
 ;
 
 modify finishOptionUndo
-    desc = "<<aHrefAlt('undo', 'UNDO', '<b>U</b>NDO',
-            'Undo the last move')>> the last move"
-    responseKeyword = 'undo'
-    responseChar = 'u'
+    desc = "<<aHrefAlt('odvolat', 'ODVOLAT', '<b>O</b>DVOLAT',
+            'Odvolat poslední tah')>> poslední tah"
+    responseKeyword = 'odvolat'
+    responseChar = 'o'
 ;
 
 modify finishOptionCredits
     desc = "see the <<aHrefAlt('credits', 'CREDITS', '<b>C</b>REDITS',
             'Show credits')>>"
     responseKeyword = 'credits'
     responseChar = 'c'
 ;
 
 modify finishOptionFullScore
-    desc = "see your <<aHrefAlt('full score', 'FULL SCORE',
-            '<b>F</b>ULL SCORE', 'Show full score')>>"
-    responseKeyword = 'full score'
-    responseChar = 'f'
+    desc = "zobrazit své <<aHrefAlt('detailní skóre', 'DETAILNÍ SKÓRE',
+            '<b>D</b>ETAILNÍ SKÓRE', 'Ukázat detailní skóre')>>"
+    responseKeyword = 'detailní skóre'
+    responseChar = 'd'
 ;
 
 modify finishOptionAmusing
-    desc = "see some <<aHrefAlt('amusing', 'AMUSING', '<b>A</b>MUSING',
-            'Show some amusing things to try')>> things to try"
-    responseKeyword = 'amusing'
-    responseChar = 'a'
+    desc = "ukázat zábavné <<aHrefAlt('možnosti', 'MOŽNOSTI', '<b>M</b>OŽNOSTI',
+            'Ukázat zábavné možnosti k vyzkoušení')>> k vyzkoušení"
+    responseKeyword = 'možnosti'
+    responseChar = 'm'
 ;
 
 modify restoreOptionStartOver
     desc = "<<aHrefAlt('start', 'START', '<b>S</b>TART',
-            'Start from the beginning')>> the game from the beginning"
+            'Start hry od začátku')>> hry od začátku"
     responseKeyword = 'start'
     responseChar = 's'
 ;
 
 modify restoreOptionRestoreAnother
-    desc = "<<aHrefAlt('restore', 'RESTORE', '<b>R</b>ESTORE',
-            'Restore a saved position')>> a different saved position"
+    desc = "<<aHrefAlt('nahrát', 'NAHRÁT', '<b>N</b>AHRÁT',
+            'Nahrát uloženou pozici')>> jinou uloženou pozici"
 ;
 
 /* ------------------------------------------------------------------------ */
 /*
  *   Context for Action.getVerbPhrase().  This keeps track of pronoun
  *   antecedents in cases where we're stringing together a series of verb
  *   phrases.
  */
 class GetVerbPhraseContext: object
-    /* get the objective form of an object, using a pronoun as appropriate */
-    objNameObj(obj)
+    /*
+     *   get the objective form of an object, using a pronoun as appropriate
+     *
+     *   V češtině si předáme podle obsahu verbPhrase, který pád chceme získat.
+     *
+     *   TODO: Po opravě regexpů odstranit varianty s mezerou.
+     */
+    objName(obj, pad)
     {
         /*
          *   if it's the pronoun antecedent, use the pronoun form;
          *   otherwise, use the full name
+         *
+         *   Zájmeno se použije, pokud už byl objekt zmíněn.
+         *
+         *   "(nejprve bereš keyring z pocket, potom odemykáš door 022, potom
+         *   otevíráš *je*)"
          */
         if (obj == pronounObj)
-            return obj.itObj;
+        {
+            if(pad == 'co') return obj.zajmenoTe4J;
+            if(pad == 'čeho' || pad == ' čeho') return obj.zajmenoTe2J;
+            return 'TODO:obj.zajmeno(' + pad + ')';
+        }
         else
-            return obj.theNameObj;
+        {
+            if(pad == 'co' || pad == ' co') return obj.nameKohoCo;
+            if(pad == 'čeho' || pad == ' čeho') return obj.nameKohoCeho;
+            return 'TODO:obj.name(' + pad + ')';
+    	}
     }
 
     /* are we showing the given object pronomially? */
     isObjPronoun(obj) { return (obj == pronounObj); }
 
     /* set the pronoun antecedent */
     setPronounObj(obj) { pronounObj = obj; }
 
     /* the pronoun antecedent */
     pronounObj = nil
 ;
 
 /*
  *   Default getVerbPhrase context.  This can be used when no other context
  *   is needed.  This context instance has no state - it doesn't track any
  *   antecedents.  
  */
 defaultGetVerbPhraseContext: GetVerbPhraseContext
     /* we don't remember any antecedents */
     setPronounObj(obj) { }
 ;
 
 /* ------------------------------------------------------------------------ */
 /*
  *   Implicit action context.  This is passed to the message methods that
  *   generate implicit action announcements, to indicate the context in
  *   which the message is to be used.
  */
 class ImplicitAnnouncementContext: object
     /*
      *   Should we use the infinitive form of the verb, or the participle
      *   form for generating the announcement?  By default, use use the
      *   participle form: "(first OPENING THE BOX)".
      */
     useInfPhrase = nil
 
     /* is this message going in a list? */
     isInList = nil
 
     /*
      *   Are we in a sublist of 'just trying' or 'just asking' messages?
      *   (We can only have sublist groupings one level deep, so we don't
      *   need to worry about what kind of sublist we're in.)
      */
     isInSublist = nil
 
     /* our getVerbPhrase context - by default, don't use one */
     getVerbCtx = nil
 
     /* generate the announcement message given the action description */
     buildImplicitAnnouncement(txt)
     {
         /* if we're not in a list, make it a full, stand-alone message */
         if (!isInList)
-            txt = '<./p0>\n<.assume>first ' + txt + '<./assume>\n';
+            txt = '<./p0>\n<.assume>nejprve {|[jsi]} ' + txt + '<./assume>\n';
 
         /* return the result */
         return txt;
     }
 ;
 
 /* the standard implicit action announcement context */
 standardImpCtx: ImplicitAnnouncementContext;
 
 /* the "just trying" implicit action announcement context */
 tryingImpCtx: ImplicitAnnouncementContext
     /*
      *   The action was merely attempted, so use the infinitive phrase in
      *   the announcement: "(first trying to OPEN THE BOX)".
      */
     useInfPhrase = true
 
     /* build the announcement */
     buildImplicitAnnouncement(txt)
     {
         /*
          *   If we're not in a list of 'trying' messages, add the 'trying'
          *   prefix message to the action description.  This isn't
          *   necessary if we're in a 'trying' list, since the list itself
          *   will have the 'trying' part.
          */
         if (!isInSublist)
-            txt = 'trying to ' + txt;
+            txt = '{zkouš[íš]|zkusil[a]} ' + txt;
 
         /* now build the message into the full text as usual */
         return inherited(txt);
     }
 ;
 
 /*
  *   The "asking question" implicit action announcement context.  By
  *   default, we generate the message exactly the same way we do for the
  *   'trying' case.
  */
 askingImpCtx: tryingImpCtx;
 
 /*
  *   A class for messages appearing in a list.  Within a list, we want to
  *   keep track of the last direct object, so that we can refer to it with
  *   a pronoun later in the list.
  */
 class ListImpCtx: ImplicitAnnouncementContext, GetVerbPhraseContext
     /*
      *   Set the appropriate base context for the given implicit action
      *   announcement report (an ImplicitActionAnnouncement object).
      */
     setBaseCtx(ctx)
     {
         /*
          *   if this is a failed attempt, use a 'trying' context;
          *   otherwise, use a standard context
          */
         if (ctx.justTrying)
             baseCtx = tryingImpCtx;
         else if (ctx.justAsking)
             baseCtx = askingImpCtx;
         else
             baseCtx = standardImpCtx;
     }
 
     /* we're in a list */
     isInList = true
 
     /* we are our own getVerbPhrase context */
     getVerbCtx = (self)
 
     /* delegate the phrase format to our underlying announcement context */
     useInfPhrase = (delegated baseCtx)
 
     /* build the announcement using our underlying context */
     buildImplicitAnnouncement(txt) { return delegated baseCtx(txt); }
 
     /* our base context - we delegate some unoverridden behavior to this */
     baseCtx = nil
 ;
 
 /* ------------------------------------------------------------------------ */
 /*
  *   Language-specific Action modifications.
  */
 modify Action
     /*
      *   In the English grammar, all 'predicate' grammar definitions
      *   (which are usually made via the VerbRule macro) are associated
      *   with Action match tree objects; in fact, each 'predicate' grammar
      *   match tree is the specific Action subclass associated with the
      *   grammar for the predicate.  This means that the Action associated
      *   with a grammar match is simply the grammar match object itself.
      *   Hence, we can resolve the action for a 'predicate' match simply
      *   by returning the match itself: it is the Action as well as the
      *   grammar match.
      *
      *   This approach ('grammar predicate' matches are based on Action
      *   subclasses) works well for languages like English that encode the
      *   role of each phrase in the word order of the sentence.
      *
      *   Languages that encode phrase roles using case markers or other
      *   devices tend to be freer with word order.  As a result,
      *   'predicate' grammars for such languages should generally not
      *   attempt to capture all possible word orderings for a given
      *   action, but should instead take the complementary approach of
      *   capturing the possible overall sentence structures independently
      *   of verb phrases, and plug in a verb phrase as a component, just
      *   like noun phrases plug into the English grammar.  In these cases,
      *   the match objects will NOT be Action subclasses; the Action
      *   objects will instead be buried down deeper in the match tree.
      *   Hence, resolveAction() must be defined on whatever class is used
      *   to construct 'predicate' grammar matches, instead of on Action,
      *   since Action will not be a 'predicate' match.
      */
     resolveAction(issuingActor, targetActor) { return self; }
 
     /*
      *   Return the interrogative pronoun for a missing object in one of
      *   our object roles.  In most cases, this is simply "what", but for
      *   some actions, "whom" is more appropriate (for example, the direct
      *   object of "ask" is implicitly a person, so "whom" is most
      *   appropriate for this role).
      */
     whatObj(which)
     {
         /* intransitive verbs have no objects, so there's nothing to show */
     }
 
     /*
-     *   Translate an interrogative word for whatObj.  If the word is
-     *   'whom', translate to the library message for 'whom'; this allows
-     *   authors to use 'who' rather than 'whom' as the objective form of
-     *   'who', which sounds less stuffy to many people.
-     */
-    whatTranslate(txt)
-    {
-        /*
-         *   if it's 'whom', translate to the library message for 'whom';
-         *   otherwise, just show the word as is
-         */
-        return (txt == 'whom' ? gLibMessages.whomPronoun : txt);
-    }
-
-    /*
      *   Return a string with the appropriate pronoun (objective form) for
      *   a list of object matches, with the given resolved cardinality.
      *   This list is a list of ResolveInfo objects.
+     *
+     *   Podej lopatu. "Komu *ji* chceš dát?"
      */
     objListPronoun(objList)
     {
         local himCnt, herCnt, themCnt;
         local FirstPersonCnt, SecondPersonCnt;
         local resolvedNumber;
 
         /* if there's no object list at all, just use 'it' */
         if (objList == nil || objList == [])
             return 'it';
 
         /* note the number of objects in the resolved list */
         resolvedNumber = objList.length();
 
         /*
          *   In the tentatively resolved object list, we might have hidden
          *   away ambiguous matches.  Expand those back into the list so
          *   we have the full list of in-scope matches.
          */
         foreach (local cur in objList)
         {
             /*
              *   if this one has hidden ambiguous objects, add the hidden
              *   objects back into our list
              */
             if (cur.extraObjects != nil)
                 objList += cur.extraObjects;
         }
 
         /*
          *   if the desired cardinality is plural and the object list has
          *   more than one object, simply say 'them'
+         *
+         *   ">dej mince Komu *je* chceš dát?"
          */
         if (objList.length() > 1 && resolvedNumber > 1)
-            return 'them';
+            return 'je';
 
         /*
          *   singular cardinality - count masculine and feminine objects,
          *   and count the referral persons
          */
         himCnt = herCnt = themCnt = 0;
         FirstPersonCnt = SecondPersonCnt = 0;
         foreach (local cur in objList)
         {
             /* if it's masculine, count it */
-            if (cur.obj_.isHim)
+            if (cur.obj_.gender == 1 || cur.obj_.gender == 2)
                 ++himCnt;
 
             /* if it's feminine, count it */
-            if (cur.obj_.isHer)
+            if (cur.obj_.gender == 3)
                 ++herCnt;
 
             /* if it has plural usage, count it */
             if (cur.obj_.isPlural)
                 ++themCnt;
 
             /* if it's first person usage, count it */
             if (cur.obj_.referralPerson == FirstPerson)
                 ++FirstPersonCnt;
 
             /* if it's second person usage, count it */
             if (cur.obj_.referralPerson == SecondPerson)
                 ++SecondPersonCnt;
         }
 
         /*
          *   if they all have plural usage, show "them"; if they're all of
          *   one gender, show "him" or "her" as appropriate; if they're
          *   all neuter, show "it"; otherwise, show "them"
+         *
+         *   "Odemkni dveře. Čím *je* chceš odemknout?" (Dveře jsou pomnožné.)
          */
         if (themCnt == objList.length())
-            return 'them';
+            return 'je'; 
         else if (FirstPersonCnt == objList.length())
             return 'myself';
         else if (SecondPersonCnt == objList.length())
             return 'yourself';
         else if (himCnt == objList.length() && herCnt == 0)
-            return 'him';
+            return 'ho';
         else if (herCnt == objList.length() && himCnt == 0)
-            return 'her';
+            return 'ji';
         else if (herCnt == 0 && himCnt == 0)
-            return 'it';
+            return 'ho';
         else
-            return 'them';
+            return 'je';
     }
 
     /*
      *   Announce a default object used with this action.
      *
      *   'resolvedAllObjects' indicates where we are in the command
      *   processing: this is true if we've already resolved all of the
      *   other objects in the command, nil if not.  We use this
      *   information to get the phrasing right according to the situation.
      */
     announceDefaultObject(obj, whichObj, resolvedAllObjects)
     {
         /*
          *   the basic action class takes no objects, so there can be no
          *   default announcement
          */
         return '';
     }
 
     /*
      *   Announce all defaulted objects in the action.  By default, we
      *   show nothing.
      */
     announceAllDefaultObjects(allResolved) { }
 
     /*
      *   Return a phrase describing the action performed implicitly, as a
      *   participle phrase.  'ctx' is an ImplicitAnnouncementContext object
      *   describing the context in which we're generating the phrase.
      *
      *   This comes in two forms: if the context indicates we're only
      *   attempting the action, we'll return an infinitive phrase ("open
      *   the box") for use in a larger participle phrase describing the
      *   attempt ("trying to...").  Otherwise, we'll be describing the
      *   action as actually having been performed, so we'll return a
      *   present participle phrase ("opening the box").
      */
     getImplicitPhrase(ctx)
     {
         /*
          *   Get the phrase.  Use the infinitive or participle form, as
          *   indicated in the context.
          */
         return getVerbPhrase(ctx.useInfPhrase, ctx.getVerbCtx);
     }
 
     /*
      *   Get the infinitive form of the action.  We are NOT to include the
      *   infinitive complementizer (i.e., "to") as part of the result,
      *   since the complementizer isn't used in all contexts in which we
      *   might want to use the infinitive; for example, we don't want a
      *   "to" in phrases involving an auxiliary verb, such as "he can open
      *   the box."
      */
     getInfPhrase()
     {
         /* return the verb phrase in infinitive form */
         return getVerbPhrase(true, nil);
     }
 
     /*
      *   Get the root infinitive form of our verb phrase as part of a
      *   question in which one of the verb's objects is the "unknown" of
      *   the interrogative.  'which' is one of the role markers
      *   (DirectObject, IndirectObject, etc), indicating which object is
      *   the subject of the interrogative.
      *
      *   For example, for the verb UNLOCK <dobj> WITH <iobj>, if the
      *   unknown is the direct object, the phrase we'd return would be
      *   "unlock": this would plug into contexts such as "what do you want
      *   to unlock."  If the indirect object is the unknown for the same
      *   verb, the phrase would be "unlock it with", which would plug in as
      *   "what do you want to unlock it with".
      *
      *   Note that we are NOT to include the infinitive complementizer
      *   (i.e., "to") as part of the phrase we generate, since the
      *   complementizer isn't used in some contexts where the infinitive
      *   conjugation is needed (for example, "what should I <infinitive>").
+     *
+     *   Co chceš *odemknout*? Co tím chceš *odemknout*?
      */
     getQuestionInf(which)
     {
         /*
          *   for a verb without objects, this is the same as the basic
          *   infinitive
          */
         return getInfPhrase();
     }
 
     /*
      *   Get a string describing the full action in present participle
      *   form, using the current command objects: "taking the watch",
      *   "putting the book on the shelf"
      */
     getParticiplePhrase()
     {
         /* return the verb phrase in participle form */
         return getVerbPhrase(nil, nil);
     }
 
     /*
      *   Get the full verb phrase in either infinitive or participle
      *   format.  This is a common handler for getInfinitivePhrase() and
      *   getParticiplePhrase().
      *
      *   'ctx' is a GetVerbPhraseContext object, which lets us keep track
      *   of antecedents when we're stringing together multiple verb
      *   phrases.  'ctx' can be nil if the verb phrase is being used in
      *   isolation.
      */
     getVerbPhrase(inf, ctx)
     {
         /*
          *   parse the verbPhrase into the parts before and after the
          *   slash, and any additional text following the slash part
+         *
+         *   Tahle funkce vybírá sloveslo do hlášky "(nejprve vstáváš)".
+         *   Přidal jsem extra lomítko pro tvar minulého času a měl bych tu
+         *   rozhodnout, zda chci přítomný a nebo minulý čas, popř. si tu
+         *   informaci nechat předat parametrem.
          */
-        rexMatch('(.*)/(<alphanum|-|squote>+)(.*)', verbPhrase);
+        rexMatch('(.*)/(<alphanum|lbrace|rbrace>+)/(<alphanum|lbrace|rbrace>+)'
+            + '(.*)', verbPhrase);
 
         /* return the appropriate parts */
         if (inf)
         {
             /*
              *   infinitive - we want the part before the slash, plus the
              *   extra prepositions (or whatever) after the switched part
              */
-            return rexGroup(1)[3] + rexGroup(3)[3];
+            return rexGroup(1)[3] + rexGroup(4)[3];
         }
         else
         {
             /* participle - it's the part after the slash */
-            return rexGroup(2)[3] + rexGroup(3)[3];
+            return tSel(rexGroup(2)[3] + rexGroup(4)[3],
+                rexGroup(3)[3] + rexGroup(4)[3]);
         }
     }
 
     /*
      *   Show the "noMatch" library message.  For most verbs, we use the
      *   basic "you can't see that here".  Verbs that are mostly used with
      *   intangible objects, such as LISTEN TO and SMELL, might want to
      *   override this to use a less visually-oriented message.
      */
     noMatch(msgObj, actor, txt) { msgObj.noMatchCannotSee(actor, txt); }
 
     /*
      *   Verb flags - these are used to control certain aspects of verb
      *   formatting.  By default, we have no special flags.
      */
     verbFlags = 0
 
     /* add a space prefix/suffix to a string if the string is non-empty */
     spPrefix(str) { return (str == '' ? str : ' ' + str); }
     spSuffix(str) { return (str == '' ? str : str + ' '); }
 ;
 
 /*
  *   English-specific additions for single-object verbs.
  */
 modify TAction
     /* return an interrogative word for an object of the action */
     whatObj(which)
     {
         /*
          *   Show the interrogative for our direct object - this is the
          *   last word enclosed in parentheses in our verbPhrase string.
+         *
+         *   Vrací první část pro větu typu "*Do čeho* chceš vstoupit?"
+         *   Pro češtinu je to zde evidentně jednodušší, protože chceme
+         *   zobrazit i předložku, která se v anglitině házela až na konec
+         *   věty. 
          */
-        rexSearch('<lparen>.*?(<alpha>+)<rparen>', verbPhrase);
-        return whatTranslate(rexGroup(1)[3]);
+        rexSearch('<lparen>(.*)<rparen>', verbPhrase);
+        return rexGroup(1)[3];
     }
 
     /* announce a default object used with this action */
+    /*
+     *   Zde bude největší problém s rozlišením koho/čeho vs. koho/co.
+     *   Přitom "co" je vždy ve významu koho/co, nikdy není použito jako kdo/co.
+     */
     announceDefaultObject(obj, whichObj, resolvedAllObjects)
     {
         local prep;
-        local nm = obj.getAnnouncementDistinguisher().theName(obj);
-
+        local nm;
+        
         /*
          *   get any direct object preposition - this is the part inside
          *   the "(what)" specifier parens, excluding the last word
          */
-        rexSearch('<lparen>(.*<space>+)?<alpha>+<rparen>', verbPhrase);
+        rexSearch('<lparen>(.*<space>+)?(<alpha>+)<rparen>', verbPhrase);
         prep = (rexGroup(1) == nil ? '' : rexGroup(1)[3]);
 
         /* do any verb-specific adjustment of the preposition */
         if (prep != nil)
             prep = adjustDefaultObjectPrep(prep, obj);
+        
+        local pad = rexGroup(2)[3];
+
+        if(pad == 'čeho') nm = obj.getAnnouncementDistinguisher().nameKohoCeho(obj);
+        else if(pad == 'komu' || pad == 'čemu') nm = obj.getAnnouncementDistinguisher().nameKomuCemu(obj);
+        else if(pad == 'koho' || pad == 'co' || pad == 'kohoco') nm = obj.getAnnouncementDistinguisher().nameKohoCo(obj);
+        else if(pad == 'kým' || pad == 'čím') nm = obj.getAnnouncementDistinguisher().nameKymCim(obj);
+        else nm = obj.getAnnouncementDistinguisher().name(obj);
 
         /* show the preposition (if any) and the object */
         return (prep == '' ? nm : prep + nm);
     }
 
     /*
      *   Adjust the preposition.  In some cases, the verb will want to vary
      *   the preposition according to the object.  This method can return a
      *   custom preposition in place of the one in the verbPhrase.  By
      *   default, we just use the fixed preposition from the verbPhrase,
      *   which is passed in to us in 'prep'.  
      */
     adjustDefaultObjectPrep(prep, obj) { return prep; }
 
     /* announce all defaulted objects */
     announceAllDefaultObjects(allResolved)
     {
         /* announce a defaulted direct object if appropriate */
         maybeAnnounceDefaultObject(dobjList_, DirectObject, allResolved);
     }
 
     /* show the verb's basic infinitive form for an interrogative */
+    /*
+     *   Zobrazuje poslední část v "Do čeho chceš *vstoupit*?" Musel jsem
+     *   odstranit předložku, protože v angličtině je na konci "What do you
+     *   want *enter to*?"
+     */
     getQuestionInf(which)
     {
         /*
          *   Show the present-tense verb form (removing the participle
          *   part - the "/xxxing" part).  Include any prepositions
          *   attached to the verb itself or to the direct object (inside
          *   the "(what)" parens).
+         *
+         *   Tohle generuje např. "Do čeho chceš *vstoupit*?"
+         *
+         *   TODO: rexGroup(2) je předložka, tu vyhodit a dát complementizer
          */
-        rexSearch('(.*)/<alphanum|-|squote>+(.*?)<space>+'
+        rexSearch('(.*)/<alphanum|lbrace|rbrace>+/<alphanum|lbrace|rbrace>+(.*?)<space>+'
                   + '<lparen>(.*?)<space>*?<alpha>+<rparen>',
                   verbPhrase);
-        return rexGroup(1)[3] + spPrefix(rexGroup(2)[3])
-            + spPrefix(rexGroup(3)[3]);
+        return rexGroup(1)[3] + spPrefix(rexGroup(2)[3]);
+    }
+
+    /*
+     *   Tahle nová funkce získává minulý čas do věty typu "Koho chceš, aby
+     *   Sally *následovala*?" Jinak je to obdoba předchozí funkce
+     */
+    getQuestionPast(which)
+    {
+        rexSearch('<alphanum>*/<alphanum|lbrace|rbrace>*/(<alphanum|lbrace|rbrace>*)<space>+',
+                  verbPhrase);
+        return rexGroup(1)[3];
     }
 
     /* get the verb phrase in infinitive or participle form */
     getVerbPhrase(inf, ctx)
     {
         local dobj;
         local dobjText;
         local dobjIsPronoun;
         local ret;
 
         /* use the default pronoun context if one wasn't supplied */
         if (ctx == nil)
             ctx = defaultGetVerbPhraseContext;
 
         /* get the direct object */
         dobj = getDobj();
 
         /* note if it's a pronoun */
         dobjIsPronoun = ctx.isObjPronoun(dobj);
 
         /* get the direct object name */
-        dobjText = ctx.objNameObj(dobj);
+        /* "nejprve bereš *lopatu*" - získává pádovou otázku pro objName */
+        rexMatch('(.*)/(<alphanum|-|squote>+)(.*) <lparen>(.*?)(<space>*?<alpha>+)<rparen>(.*)', verbPhrase);
+        dobjText = ctx.objName(dobj, rexGroup(5)[3]);
 
         /* get the phrasing */
+        /* "nejprve *bereš lopatu*" */
         ret = getVerbPhrase1(inf, verbPhrase, dobjText, dobjIsPronoun);
 
         /* set the pronoun antecedent to my direct object */
         ctx.setPronounObj(dobj);
 
         /* return the result */
         return ret;
     }
 
     /*
      *   Given the text of the direct object phrase, build the verb phrase
      *   for a one-object verb.  This is a class method that can be used by
      *   other kinds of verbs (i.e., non-TActions) that use phrasing like a
      *   single object.
      *
      *   'inf' is a flag indicating whether to use the infinitive form
      *   (true) or the present participle form (nil); 'vp' is the
      *   verbPhrase string; 'dobjText' is the direct object phrase's text;
      *   and 'dobjIsPronoun' is true if the dobj text is rendered as a
      *   pronoun.
+     *
+     *   Výstup této funkce navazuje na slova "nejprve", "potom" v implicitních
+     *   hlášeních.
      */
     getVerbPhrase1(inf, vp, dobjText, dobjIsPronoun)
     {
         local ret;
         local dprep;
         local vcomp;
 
         /*
          *   parse the verbPhrase: pick out the 'infinitive/participle'
          *   part, the complementizer part up to the '(what)' direct
          *   object placeholder, and any preposition within the '(what)'
          *   specifier
+         *
+         *   V češtině "squote" a "-" není potřeba, zato však povolím
+         *   složené závorky na parametry.
          */
-        rexMatch('(.*)/(<alphanum|-|squote>+)(.*) '
+        rexMatch('(.*)/(<alphanum|lbrace|rbrace>+)/'
+                 + '(<alphanum|lbrace|rbrace>+)(.*) '
                  + '<lparen>(.*?)<space>*?<alpha>+<rparen>(.*)',
                  vp);
 
-        /* start off with the infinitive or participle, as desired */
+	ret = '';
+
+        /*
+         *   Pokud dobjIsPronoun, tak ho teď zařadíme do věty. Jedná se
+         *   o případ, kdy už jednou je objekt v hlášení zmíněn a tak podruhé
+         *   je nahražen zájmenem.
+         *
+         *   "Nejprve odemykáš dveře, potom *je* otevíráš."
+         */
+        if (dobjIsPronoun)
+            ret += dobjText + ' ';
+
+        /*
+         *   if there's any suffix following the direct object
+         *   placeholder, add it at the end of the phrase
+         *
+         *   V našem případě je to případné "se", "si".
+         *   "(nejprve *se* dostáváš ven ze stínu)"
+         */
+        ret += spSuffix(rexGroup(6)[3]);
+
+        /*
+         *   Přidáme do věty sloveso. Pokud není infinitiv, tak si vybereme
+         *   správnou verzi času. Ostatní parametry se posunuly o jeden dál,
+         *   protože máme oproti angličitě dvě lomítka ve verbPhrase.
+         *
+         *   "*odemykáš* dveře", "jsi *odemykla* dveře"
+         */
         if (inf)
-            ret = rexGroup(1)[3];
+            ret += rexGroup(1)[3];
         else
-            ret = rexGroup(2)[3];
+            ret += tSel(rexGroup(2)[3], rexGroup(3)[3]);
 
         /* get the prepositional complementizer */
-        vcomp = rexGroup(3)[3];
+        vcomp = rexGroup(4)[3];
 
         /* get the direct object preposition */
-        dprep = rexGroup(4)[3];
+        dprep = rexGroup(5)[3];
 
         /* do any verb-specific adjustment of the preposition */
         if (dprep != nil)
             dprep = adjustDefaultObjectPrep(dprep, getDobj());
 
         /*
          *   if the direct object is not a pronoun, put the complementizer
          *   BEFORE the direct object (the 'up' in "PICKING UP THE BOX")
          */
         if (!dobjIsPronoun)
             ret += spPrefix(vcomp);
 
         /* add the direct object preposition */
         ret += spPrefix(dprep);
 
-        /* add the direct object, using the pronoun form if applicable */
-        ret += ' ' + dobjText;
+        /*
+         *   add the direct object, using the pronoun form if applicable
+         *
+         *   Pouze pokud už jsme nepřidali zájmeno dříve, viz výše.
+         */
+        if (!dobjIsPronoun)
+            ret += ' ' + dobjText;
 
         /*
          *   if the direct object is a pronoun, put the complementizer
          *   AFTER the direct object (the 'up' in "PICKING IT UP")
          */
         if (dobjIsPronoun)
             ret += spPrefix(vcomp);
 
-        /*
-         *   if there's any suffix following the direct object
-         *   placeholder, add it at the end of the phrase
-         */
-        ret += rexGroup(5)[3];
-
         /* return the complete phrase string */
         return ret;
     }
+    /*
+     *   Zde budeme hledat případné "se" za závorkou ve verbPhrase, abychom ho
+     *   umístili do věty "Z čeho *se* chceš dostat ven?"
+     */
+    getZvratneZajmeno(which)
+    {
+        rexMatch('(.*)/(<alphanum|-|squote>+)(.*) <lparen>(.*?)(<space>*?<alpha>+)<rparen> *(.*)', verbPhrase);
+        return rexGroup(6)[3];
+    }
 ;
 
 /*
  *   English-specific additions for two-object verbs.
  */
 modify TIAction
     /*
      *   Flag: omit the indirect object in a query for a missing direct
      *   object.  For many verbs, if we already know the indirect object
      *   and we need to ask for the direct object, the query sounds best
      *   when it includes the indirect object: "what do you want to put in
      *   it?"  or "what do you want to take from it?".  This is the
      *   default phrasing.
      *
      *   However, the corresponding query for some verbs sounds weird:
      *   "what do you want to dig in with it?" or "whom do you want to ask
      *   about it?".  For such actions, this property should be set to
      *   true to indicate that the indirect object should be omitted from
      *   the queries, which will change the phrasing to "what do you want
      *   to dig in", "whom do you want to ask", and so on.
      */
     omitIobjInDobjQuery = nil
 
     /*
      *   For VerbRules: does this verb rule have a prepositional or
      *   structural phrasing of the direct and indirect object slots?  That
      *   is, are the object slots determined by a prepositional marker, or
      *   purely by word order?  For most English verbs with two objects,
      *   the indirect object is marked by a preposition: GIVE BOOK TO BOB,
      *   PUT BOOK IN BOX.  There are a few English verbs that don't include
      *   any prespositional markers for the objects, though, and assign the
      *   noun phrase roles purely by the word order: GIVE BOB BOOK, SHOW
      *   BOB BOOK, THROW BOB BOOK.  We define these phrasings with separate
      *   verb rules, which we mark with this property.
      *
      *   We use this in ranking verb matches.  Non-prepositional verb
      *   structures are especially prone to matching where they shouldn't,
      *   because we can often find a way to pick out words to fill the
      *   slots in the absence of any marker words.  For example, GIVE GREEN
      *   BOOK could be interpreted as GIVE BOOK TO GREEN, where GREEN is
      *   assumed to be an adjective-ending noun phrase; but the player
      *   probably means to give the green book to someone who they assumed
      *   would be filled in as a default.  So, whenever we find an
      *   interpretation that involves a non-prespositional phrasing, we'll
      *   use this flag to know we should be suspicious of it and try
      *   alternative phrasing first.
      *
      *   Most two-object verbs in English use prepositional markers, so
      *   we'll set this as the default.  Individual VerbRules that use
      *   purely structural phrasing should override this.
      */
     isPrepositionalPhrasing = true
 
     /* resolve noun phrases */
     resolveNouns(issuingActor, targetActor, results)
     {
         /*
          *   If we're a non-prepositional phrasing, it means that we have
          *   the VERB IOBJ DOBJ word ordering (as in GIVE BOB BOX or THROW
          *   BOB COIN).  For grammar match ranking purposes, give these
          *   phrasings a lower match probability when the dobj phrase
          *   doesn't have a clear qualifier.  If the dobj phrase starts
          *   with 'the' or a qualifier word like that (GIVE BOB THE BOX),
          *   then it's pretty clear that the structural phrasing is right
          *   after all; but if there's no qualifier, we could reading too
          *   much into the word order.  We could have something like GIVE
          *   GREEN BOX, where we *could* treat this as two objects, but we
          *   could just as well have a missing indirect object phrase.
          */
         if (!isPrepositionalPhrasing)
         {
             /*
              *   If the direct object phrase starts with 'a', 'an', 'the',
              *   'some', or 'any', the grammar is pretty clearly a good
              *   match for the non-prepositional phrasing.  Otherwise, it's
              *   suspect, so rank it accordingly.
              */
             if (rexMatch('(a|an|the|some|any)<space>',
                          dobjMatch.getOrigText()) == nil)
             {
                 /* note this as weak phrasing level 100 */
                 results.noteWeakPhrasing(100);
             }
         }
 
         /* inherit the base handling */
         inherited(issuingActor, targetActor, results);
     }
 
-    /* get the interrogative for one of our objects */
+    /*
+     *   get the interrogative for one of our objects
+     *
+     *   Vrací první část pro větu typu "*V čem* chceš vyhledat?" Pro češtinu
+     *   je to zde evidentně jednodušší, protože chceme zobrazit i předložku,
+     *   která se v anglitině házela až na konec věty.
+     */
     whatObj(which)
     {
         switch (which)
         {
         case DirectObject:
             /*
              *   the direct object interrogative is the first word in
              *   parentheses in our verbPhrase string
              */
-            rexSearch('<lparen>.*?(<alpha>+)<rparen>', verbPhrase);
+            rexSearch('<lparen>(.*)<rparen>.*<lparen>', verbPhrase);
             break;
 
         case IndirectObject:
             /*
              *   the indirect object interrogative is the second
              *   parenthesized word in our verbPhrase string
              */
-            rexSearch('<rparen>.*<lparen>.*?(<alpha>+)<rparen>', verbPhrase);
+            rexSearch('<rparen>.*<lparen>(.*)<rparen>', verbPhrase);
             break;
         }
 
         /* show the group match */
-        return whatTranslate(rexGroup(1)[3]);
+        return rexGroup(1)[3];
     }
 
     /* announce a default object used with this action */
     announceDefaultObject(obj, whichObj, resolvedAllObjects)
     {
         local verb;
         local prep;
+        local pad;
 
         /* presume we won't have a verb or preposition */
         verb = '';
         prep = '';
+        pad = '';
 
         /*
          *   Check the full phrasing - if we're showing the direct object,
          *   but an indirect object was supplied, use the verb's
          *   participle form ("asking bob") in the default string, since
          *   we must clarify that we're not tagging the default string on
          *   to the command line.  Don't include the participle form if we
          *   don't know all the objects yet, since in this case we are in
          *   fact tagging the default string onto the command so far, as
          *   there's nothing else in the command to get in the way.
+         *
+         *   >zeptej se na kouř
+         *   (*ptáš* se uhlíře)
          */
         if (whichObj == DirectObject && resolvedAllObjects)
         {
             /*
              *   extract the verb's participle form (including any
              *   complementizer phrase)
+             *
+             *   TODO: Jeden regexp selhává, vyzkoušet v 3.0.19
              */
-            rexSearch('/(<^lparen>+) <lparen>', verbPhrase);
-            verb = rexGroup(1)[3] + ' ';
+            rexSearch('/(<alpha|lbrace|rbrace>+)/', verbPhrase);
+            local a = rexGroup(1)[3];
+
+            rexSearch('/(<alpha|lbrace|rbrace>+) ', verbPhrase);
+            local b = rexGroup(1)[3];
+
+            rexSearch('/<alpha|lbrace|rbrace>+ (<alpha>+)', verbPhrase);
+            local c = rexGroup(1) ? rexGroup(1)[3] : '';
+
+            verb = tSel(a, b) + '{| [jsi]}' + spPrefix(spSuffix(c));
         }
 
         /* get the preposition to use, if any */
         switch(whichObj)
         {
         case DirectObject:
             /* use the preposition in the first "(what)" phrase */
             rexSearch('<lparen>(.*?)<space>*<alpha>+<rparen>', verbPhrase);
             prep = rexGroup(1)[3];
+            rexSearch('<lparen>.*?(<space>*<alpha>+)<rparen>', verbPhrase);
+            pad = rexGroup(1)[3];
             break;
 
         case IndirectObject:
             /* use the preposition in the second "(what)" phrase */
             rexSearch('<rparen>.*<lparen>(.*?)<space>*<alpha>+<rparen>',
                       verbPhrase);
             prep = rexGroup(1)[3];
+            rexSearch('<rparen>.*<lparen>.*?(<space>*<alpha>+)<rparen>', verbPhrase);
+            pad = rexGroup(1)[3];
             break;
         }
 
         /* build and return the complete phrase */
-        return spSuffix(verb) + spSuffix(prep)
-            + obj.getAnnouncementDistinguisher().theName(obj);
+        /*
+         *   Za sloveso přidávám ještě zvratné zájmeno, pokud se ke slovesu
+         *   váže. Podmíněno je to stejným způsobem, jako získání slovesa. Tj.
+         *   buď se vypíše celé "(*ptáš se* uhlíře)" a nebo jen "(uhlíře)".
+         */
+        local zvratneZajmeno = '';
+        if (whichObj == DirectObject && resolvedAllObjects)
+        {
+            rexSearch('<rparen>.*<rparen><space>*(<alpha>+)', verbPhrase);
+            if(rexGroup(1)) zvratneZajmeno = rexGroup(1)[3];
+        }
+
+        pad = pad.findReplace(' ', '', ReplaceOnce);
+
+        if(pad == 'koho' && zvratneZajmeno == 'se' || pad == 'čeho') return spSuffix(verb) + spSuffix(zvratneZajmeno) + spSuffix(prep) + obj.getAnnouncementDistinguisher().nameKohoCeho(obj);
+        else if(pad == 'komu' || pad == 'čemu') return spSuffix(verb) + spSuffix(zvratneZajmeno) + spSuffix(prep) + obj.getAnnouncementDistinguisher().nameKomuCemu(obj);
+        else if(pad == 'koho' && zvratneZajmeno != 'se' ||  pad == 'co') return spSuffix(verb) + spSuffix(zvratneZajmeno) + spSuffix(prep) + obj.getAnnouncementDistinguisher().nameKohoCo(obj);
+        else if(pad == 'čem') return spSuffix(verb) + spSuffix(zvratneZajmeno) + spSuffix(prep) + obj.getAnnouncementDistinguisher().nameKomCem(obj);
+        else if(pad == 'čím') return spSuffix(verb) + spSuffix(zvratneZajmeno) + spSuffix(prep) + obj.getAnnouncementDistinguisher().nameKymCim(obj);
+        else return spSuffix(verb) + spSuffix(zvratneZajmeno) + spSuffix(prep) + obj.getAnnouncementDistinguisher().name(obj) + '[neznamy pad (' + pad + '[' + prep + ']), ' + verbPhrase + ']';
     }
 
     /* announce all defaulted objects */
     announceAllDefaultObjects(allResolved)
     {
         /* announce a defaulted direct object if appropriate */
         maybeAnnounceDefaultObject(dobjList_, DirectObject, allResolved);
 
         /* announce a defaulted indirect object if appropriate */
         maybeAnnounceDefaultObject(iobjList_, IndirectObject, allResolved);
     }
 
     /* show the verb's basic infinitive form for an interrogative */
     getQuestionInf(which)
     {
         local ret;
         local vcomp;
-        local dprep;
-        local iprep;
-        local pro;
 
         /*
          *   Our verb phrase can one of three formats, depending on which
          *   object role we're asking about (the part in <angle brackets>
          *   is the part we're responsible for generating).  In these
          *   formats, 'verb' is the verb infinitive; 'comp' is the
          *   complementizer, if any (e.g., the 'up' in 'pick up'); 'dprep'
          *   is the direct object preposition (the 'in' in 'dig in x with
          *   y'); and 'iprep' is the indirect object preposition (the
          *   'with' in 'dig in x with y').
          *
          *   asking for dobj: verb vcomp dprep iprep it ('what do you want
          *   to <open with it>?', '<dig in with it>', '<look up in it>').
          *
          *   asking for dobj, but suppressing the iobj part: verb vcomp
          *   dprep ('what do you want to <turn>?', '<look up>?', '<dig
          *   in>')
          *
          *   asking for iobj: verb dprep it vcomp iprep ('what do you want
          *   to <open it with>', '<dig in it with>', '<look it up in>'
+         *
+         *   V češtině se mnoho z této funkcionality přesouvá do msg_neu.t
+         *   a funkcí askMissingObject, missingObject a missingLiteral,
+         *   protože předložky i zájmena se staví do věty a jiné místo.
+         *
+         *   "Na co se ho chceš *zeptat*?"
+         *   "Čím chceš *vyhrabat díru*?"
          */
 
         /* parse the verbPhrase into its component parts */
-        rexMatch('(.*)/<alphanum|-|squote>+(?:<space>+(<^lparen>*))?'
+        rexMatch('(.*)/<alphanum|lbrace|rbrace>+/<alphanum|lbrace|rbrace>+(?:<space>+(<^lparen>*))?'
                  + '<space>+<lparen>(.*?)<space>*<alpha>+<rparen>'
                  + '<space>+<lparen>(.*?)<space>*<alpha>+<rparen>',
                  verbPhrase);
 
-        /* pull out the verb */
-        ret = rexGroup(1)[3];
-
-        /* pull out the verb complementizer */
+        /*
+         *   pull out the verb complementizer
+         *
+         *   Complementizer je část verbPhrase mezi slovesy a zástupci objektů
+         *   v závorkách:
+         *
+         *   verbPhrase = 'vyhrabat/hrab{eš}/vyhrabal{a} *díru* (v čem) (čím)'
+         *
+         *   Ve větě patří přímo za sloveso: "V čem chceš vyhrabat *díru*?"
+         */
         vcomp = (rexGroup(2) == nil ? '' : rexGroup(2)[3]);
 
-        /* pull out the direct and indirect object prepositions */
-        dprep = rexGroup(3)[3];
-        iprep = rexGroup(4)[3];
-
-        /* get the pronoun for the other object phrase */
-        pro = getOtherMessageObjectPronoun(which);
-
-        /* check what we're asking about */
-        if (which == DirectObject)
-        {
-            /* add the <vcomp dprep> part in all cases */
-            ret += spPrefix(vcomp) + spPrefix(dprep);
-
-            /* add the <iprep it> part if we want the indirect object part */
-            if (!omitIobjInDobjQuery && pro != nil)
-                ret += spPrefix(iprep) + ' ' + pro;
-        }
-        else
-        {
-            /* add the <dprep it> part if appropriate */
-            if (pro != nil)
-                ret += spPrefix(dprep) + ' ' + pro;
+        /* pull out the verb */
+        ret = rexGroup(1)[3];
 
-            /* add the <vcomp iprep> part */
-            ret += spPrefix(vcomp) + spPrefix(iprep);
-        }
+        /* add the <vcomp> part in all cases */
+        ret += spPrefix(vcomp);
 
         /* return the result */
         return ret;
     }
 
     /*
      *   Get the pronoun for the message object in the given role.
      */
     getOtherMessageObjectPronoun(which)
     {
         local lst;
 
         /*
          *   Get the resolution list (or tentative resolution list) for the
          *   *other* object, since we want to show a pronoun representing
          *   the other object.  If we don't have a fully-resolved list for
          *   the other object, use the tentative resolution list, which
          *   we're guaranteed to have by the time we start resolving
          *   anything (and thus by the time we need to ask for objects).
          */
         lst = (which == DirectObject ? iobjList_ : dobjList_);
         if (lst == nil || lst == [])
             lst = (which == DirectObject
                    ? tentativeIobj_ : tentativeDobj_);
 
         /* if we found an object list, use the pronoun for the list */
         if (lst != nil && lst != [])
         {
             /* we got a list - return a suitable pronoun for this list */
             return objListPronoun(lst);
         }
         else
         {
             /* there's no object list, so there's no pronoun */
             return nil;
         }
     }
 
     /* get the verb phrase in infinitive or participle form */
     getVerbPhrase(inf, ctx)
     {
         local dobj, dobjText, dobjIsPronoun;
         local iobj, iobjText;
         local ret;
 
         /* use the default context if one wasn't supplied */
         if (ctx == nil)
             ctx = defaultGetVerbPhraseContext;
 
-        /* get the direct object information */
+        /*
+         *   get the direct object information
+         *
+         *   Vezmeme pádovou otázku a podle ní skloňujeme objekt.
+         *
+         *   TODO: bez .* před <lparen> nefunguje, znovu zkusit v 3.0.19 a
+         *   případně poslat další bugreport, viz i níže.
+         */
         dobj = getDobj();
-        dobjText = ctx.objNameObj(dobj);
+        rexMatch('.*<lparen>(<alpha>*?)(<space>?<alpha>+)<rparen><space>', verbPhrase);
+        dobjText = ctx.objName(dobj, rexGroup(2)[3]);
         dobjIsPronoun = ctx.isObjPronoun(dobj);
 
         /* get the indirect object information */
         iobj = getIobj();
-        iobjText = (iobj != nil ? ctx.objNameObj(iobj) : nil);
+        rexMatch('.*<rparen><space>*<lparen>(.*?<space>|)(<alpha>+)', verbPhrase);
+        iobjText = (iobj != nil ? ctx.objName(iobj, rexGroup(2)[3]) : nil);
 
         /* get the phrasing */
         ret = getVerbPhrase2(inf, verbPhrase,
                              dobjText, dobjIsPronoun, iobjText);
 
         /*
          *   Set the antecedent for the next verb phrase.  Our direct
          *   object is normally the antecedent; however, if the indirect
          *   object matches the current antecedent, keep the current
          *   antecedent, so that 'it' (or whatever) remains the same for
          *   the next verb phrase.
          */
         if (ctx.pronounObj != iobj)
             ctx.setPronounObj(dobj);
 
         /* return the result */
         return ret;
     }
 
     /*
      *   Get the verb phrase for a two-object (dobj + iobj) phrasing.  This
      *   is a class method, so that it can be reused by unrelated (i.e.,
      *   non-TIAction) classes that also use two-object syntax but with
      *   other internal structures.  This is the two-object equivalent of
      *   TAction.getVerbPhrase1().
+     *
+     *   Tahle funkce už má dané tvary popisu objektů a jen najde předložky
+     *   a sestaví do věty.
      */
     getVerbPhrase2(inf, vp, dobjText, dobjIsPronoun, iobjText)
     {
         local ret;
         local vcomp;
         local dprep, iprep;
 
         /* parse the verbPhrase into its component parts */
-        rexMatch('(.*)/(<alphanum|-|squote>+)(?:<space>+(<^lparen>*))?'
+        rexMatch('(.*)/(<alphanum|lbrace|rbrace>+)/(<alphanum|lbrace|rbrace>+)(?:<space>+(<^lparen>*))?'
                  + '<space>+<lparen>(.*?)<space>*<alpha>+<rparen>'
                  + '<space>+<lparen>(.*?)<space>*<alpha>+<rparen>',
                  vp);
 
+        ret = '';
+
+        /* get the direct and indirect object prepositions */
+        dprep = rexGroup(5)[3];
+        iprep = rexGroup(6)[3];
+
+        /*
+         *   Pokud dobjIsPronoun, tak ho teď zařadíme do věty. Jedná se
+         *   o případ, kdy už jednou je objekt v hlášení zmíněn a tak podruhé
+         *   je nahražen zájmenem.
+         */
+        if (dobjIsPronoun)
+            ret += spPrefix(dprep) + ' ' + dobjText + ' ';
+
         /* start off with the infinitive or participle, as desired */
         if (inf)
-            ret = rexGroup(1)[3];
+            ret += rexGroup(1)[3];
         else
-            ret = rexGroup(2)[3];
+            ret += tSel(rexGroup(2)[3], rexGroup(3)[3]);
 
         /* get the complementizer */
-        vcomp = (rexGroup(3) == nil ? '' : rexGroup(3)[3]);
-
-        /* get the direct and indirect object prepositions */
-        dprep = rexGroup(4)[3];
-        iprep = rexGroup(5)[3];
+        vcomp = (rexGroup(4) == nil ? '' : rexGroup(4)[3]);
 
         /*
          *   add the complementizer BEFORE the direct object, if the
          *   direct object is being shown as a full name ("PICK UP BOX")
          */
         if (!dobjIsPronoun)
             ret += spPrefix(vcomp);
 
         /*
          *   add the direct object and its preposition, using a pronoun if
          *   applicable
+         *
+         *   Pouze pokud už jsme nepřidali zájmeno dříve, viz výše.
          */
-        ret += spPrefix(dprep) + ' ' + dobjText;
+        if (!dobjIsPronoun)
+            ret += spPrefix(dprep) + ' ' + dobjText;
 
         /*
          *   add the complementizer AFTER the direct object, if the direct
          *   object is shown as a pronoun ("PICK IT UP")
          */
         if (dobjIsPronoun)
             ret += spPrefix(vcomp);
 
         /* if we have an indirect object, add it with its preposition */
         if (iobjText != nil)
             ret += spPrefix(iprep) + ' ' + iobjText;
 
         /* return the result phrase */
         return ret;
     }
 ;
 
 /*
  *   English-specific additions for verbs taking a literal phrase as the
  *   sole object.
  */
 modify LiteralAction
     /* provide a base verbPhrase, in case an instance leaves it out */
     verbPhrase = 'verb/verbing (what)'
 
     /* get an interrogative word for an object of the action */
     whatObj(which)
     {
         /* use the same processing as TAction */
         return delegated TAction(which);
     }
 
     getVerbPhrase(inf, ctx)
     {
         /* handle this as though the literal were a direct object phrase */
         return TAction.getVerbPhrase1(inf, verbPhrase, gLiteral, nil);
     }
 
     getQuestionInf(which)
     {
         /* use the same handling as for a regular one-object action */
         return delegated TAction(which);
     }
 
 ;
 
 /*
  *   English-specific additions for verbs of a direct object and a literal
  *   phrase.
  */
 modify LiteralTAction
     announceDefaultObject(obj, whichObj, resolvedAllObjects)
     {
         /*
          *   Use the same handling as for a regular two-object action.  We
          *   can only default the actual object in this kind of verb; the
          *   actual object always fills the DirectObject slot, but in
          *   message generation it might use a different slot, so use the
          *   message generation slot here.
          */
         return delegated TIAction(obj, whichMessageObject,
                                   resolvedAllObjects);
     }
 
     whatObj(which)
     {
         /* use the same handling we use for a regular two-object action */
         return delegated TIAction(which);
     }
 
     getQuestionInf(which)
     {
         /*
          *   use the same handling as for a two-object action (but note
          *   that we override getMessageObjectPronoun(), which will affect
          *   the way we present the verb infinitive in some cases)
          */
         return delegated TIAction(which);
     }
 
     /*
      *   When we want to show a verb infinitive phrase that involves a
      *   pronoun for the literal phrase, refer to the literal as 'that'
      *   rather than 'it' or anything else.
      */
     getOtherMessageObjectPronoun(which)
     {
         /*
          *   If we're asking about the literal phrase, then the other
          *   pronoun is for the resolved object: so, return the pronoun
          *   for the direct object phrase, because we *always* store the
          *   non-literal in the direct object slot, regardless of the
          *   actual phrasing of the action.
          *
          *   If we're asking about the resolved object (i.e., not the
          *   literal phrase), then return 'that' as the pronoun for the
          *   literal phrase.
          */
         if (which == whichMessageLiteral)
         {
             /*
              *   we're asking about the literal, so the other pronoun is
              *   for the resolved object, which is always in the direct
              *   object slot (so the 'other' slot is effectively the
              *   indirect object)
              */
             return delegated TIAction(IndirectObject);
         }
         else
         {
             /*
              *   We're asking about the resolved object, so the other
              *   pronoun is for the literal phrase: always use 'that' to
              *   refer to the literal phrase.
              */
             return 'that';
         }
     }
 
     getVerbPhrase(inf, ctx)
     {
         local dobj, dobjText, dobjIsPronoun;
         local litText;
         local ret;
 
         /* use the default context if one wasn't supplied */
         if (ctx == nil)
             ctx = defaultGetVerbPhraseContext;
 
         /* get the direct object information */
         dobj = getDobj();
-        dobjText = ctx.objNameObj(dobj);
+        dobjText = ctx.objName(dobj, '');
         dobjIsPronoun = ctx.isObjPronoun(dobj);
 
         /* get our literal text */
         litText = gLiteral;
 
         /*
          *   Use the standard two-object phrasing.  The order of the
          *   phrasing depends on whether our literal phrase is in the
          *   direct or indirect object slot.
          */
         if (whichMessageLiteral == DirectObject)
             ret = TIAction.getVerbPhrase2(inf, verbPhrase,
                                           litText, nil, dobjText);
         else
             ret = TIAction.getVerbPhrase2(inf, verbPhrase,
                                           dobjText, dobjIsPronoun, litText);
 
         /* use the direct object as the antecedent for the next phrase */
         ctx.setPronounObj(dobj);
 
         /* return the result */
         return ret;
     }
 ;
 
 /*
  *   English-specific additions for verbs taking a topic phrase as the sole
  *   object.  
  */
 modify TopicAction
     /* get an interrogative word for an object of the action */
     whatObj(which)
     {
         /* use the same processing as TAction */
         return delegated TAction(which);
     }
 
     getVerbPhrase(inf, ctx)
     {
         /* handle this as though the topic text were a direct object phrase */
         return TAction.getVerbPhrase1(
             inf, verbPhrase, getTopic().getTopicText().toLower(), nil);
     }
 
     getQuestionInf(which)
     {
         /* use the same handling as for a regular one-object action */
         return delegated TAction(which);
     }
 
 ;
 
 /*
  *   English-specific additions for verbs with topic phrases.
  */
 modify TopicTAction
     announceDefaultObject(obj, whichObj, resolvedAllObjects)
     {
         /*
          *   Use the same handling as for a regular two-object action.  We
          *   can only default the actual object in this kind of verb; the
          *   actual object always fills the DirectObject slot, but in
          *   message generation it might use a different slot, so use the
          *   message generation slot here.
          */
         return delegated TIAction(obj, whichMessageObject,
                                   resolvedAllObjects);
     }
 
     whatObj(which)
     {
         /* use the same handling we use for a regular two-object action */
         return delegated TIAction(which);
     }
 
     getQuestionInf(which)
     {
         /* use the same handling as for a regular two-object action */
         return delegated TIAction(which);
     }
 
     getOtherMessageObjectPronoun(which)
     {
         /*
          *   If we're asking about the topic, then the other pronoun is
          *   for the resolved object, which is always in the direct object
          *   slot.  If we're asking about the resolved object, then return
          *   a pronoun for the topic.
          */
         if (which == whichMessageTopic)
         {
             /*
              *   we want the pronoun for the resolved object, which is
              *   always in the direct object slot (so the 'other' slot is
              *   effectively the indirect object)
              */
+             // zrejme: "na co *se* chceš zeptat"/"o co chceš požádat"
             return delegated TIAction(IndirectObject);
         }
         else
         {
             /* return a generic pronoun for the topic */
-            return 'that';
+            /*
+             *   "Koho *se* chceš zeptat?" Ale také "Koho se chceš požádat?"
+             *   Proto tady nebudu vracet nic (jinak je tenhle mechanismus
+             *   vyuzivan na "Komu *ji* chces dat", tak ho nemuzu cely
+             *   odstranit.
+             */
+            
+            return '';
         }
     }
 
     getVerbPhrase(inf, ctx)
     {
         local dobj, dobjText, dobjIsPronoun;
         local topicText;
         local ret;
 
         /* use the default context if one wasn't supplied */
         if (ctx == nil)
             ctx = defaultGetVerbPhraseContext;
 
         /* get the direct object information */
         dobj = getDobj();
-        dobjText = ctx.objNameObj(dobj);
+        dobjText = ctx.objName(dobj, '');
         dobjIsPronoun = ctx.isObjPronoun(dobj);
 
         /* get our topic phrase */
         topicText = getTopic().getTopicText().toLower();
 
         /*
          *   Use the standard two-object phrasing.  The order of the
          *   phrasing depends on whether our topic phrase is in the direct
          *   or indirect object slot.
          */
         if (whichMessageTopic == DirectObject)
             ret = TIAction.getVerbPhrase2(inf, verbPhrase,
                                           topicText, nil, dobjText);
         else
             ret = TIAction.getVerbPhrase2(inf, verbPhrase,
                                           dobjText, dobjIsPronoun, topicText);
 
         /* use the direct object as the antecedent for the next phrase */
         ctx.setPronounObj(dobj);
 
         /* return the result */
         return ret;
     }
 ;
 
 /* ------------------------------------------------------------------------ */
 /*
  *   Verbs.
  *
  *   The actual body of each of our verbs is defined in the main
  *   language-independent part of the library.  We only define the
  *   language-specific grammar rules here.
  */
 
 VerbRule(Take)
-    ('take' | 'pick' 'up' | 'get') dobjList
-    | 'pick' dobjList 'up'
+    ('vezmi' | 'vem' | 'vzít' | 'seber' | 'ber' | 'seb' | 'sebrat' | 'zvedni'
+    | 'zvednout' | 'uchop' | 'uchopit' | 'popadni' | 'popadnout')
+    dobjList
     : TakeAction
-    verbPhrase = 'take/taking (what)'
+    verbPhrase = 'vzít/ber{eš}/vzal{a} (co)'
 ;
 
 VerbRule(TakeFrom)
-    ('take' | 'get') dobjList
-        ('from' | 'out' 'of' | 'off' | 'off' 'of') singleIobj
-    | 'remove' dobjList 'from' singleIobj
+    ('vezmi' | 'vem' | 'vzít' | 'vyndej' | 'vyndat' | 'vyjmi' | 'vyjmout'
+    | 'odstraň' | 'odstranit') dobjList ('z' | 'ze') singleIobj
     : TakeFromAction
-    verbPhrase = 'take/taking (what) (from what)'
+    verbPhrase = 'vzít/ber{eš}/vzal{a} (co) (z čeho)'
 ;
 
 VerbRule(Remove)
-    'remove' dobjList
+    ('vyndej' | 'vyndat' | 'vyjmi' | 'vyjmout' | 'odstraň' | 'odstranit') dobjList
     : RemoveAction
-    verbPhrase = 'remove/removing (what)'
+    verbPhrase = 'vyndat/vyndav{áš}/vyndal{a} (co)'
 ;
 
 VerbRule(Drop)
-    ('drop' | 'put' 'down' | 'set' 'down') dobjList
-    | ('put' | 'set') dobjList 'down'
+    ('polož' | 'položit' | 'odlož' | 'odložit' | 'upusť' | 'upustit') dobjList
     : DropAction
-    verbPhrase = 'drop/dropping (what)'
+    verbPhrase = 'odložit/odklád{áš}/odložil{a} (co)'
 ;
 
 VerbRule(Examine)
-    ('examine' | 'inspect' | 'x' | 'look' 'at' | 'l' 'at') dobjList
+    ('p' | 'pro' | 'prozkoumej' | 'prozkoumat' | 'zkoumej' | 'zkoumat'
+    | ('podívej' | 'podívat') 'se' 'na') dobjList
     : ExamineAction
-    verbPhrase = 'examine/examining (what)'
+    verbPhrase = 'prozkoumat/zkoum{áš}/prozkoumal{a} (co)'
 ;
 
 VerbRule(Read)
-    'read' dobjList
+    ('přečti' | 'přečíst' | 'čti' | 'číst') dobjList
     : ReadAction
-    verbPhrase = 'read/reading (what)'
+    verbPhrase = 'přečíst/čt{eš}/přečetl{a} (co)'
 ;
 
 VerbRule(LookIn)
-    ('look' | 'l') ('in' | 'inside') dobjList
+    ('koukni' | 'kouknout' | 'koukej' | 'koukat' | 'podívej' | 'podívat'
+    | 'dívej' | 'dívat') ('se' | ) 'do' dobjList
+    | ('nahlédni' | 'nahlížej' | 'nahlédnout') 'do' dobjList
     : LookInAction
-    verbPhrase = 'look/looking (in what)'
+    verbPhrase = 'kouknout/kouk{áš}/kouknul{a} (do čeho)'
 ;
 
 VerbRule(Search)
-    'search' dobjList
+    ('prohledej' | 'prohledat') dobjList
     : SearchAction
-    verbPhrase = 'search/searching (what)'
+    verbPhrase = 'prohledat/prohledáv{áš}/prohledal{a} (co)'
 ;
 
+/*
+ *   TODO: "Koukni *do* okna" je také logické, přitom se ale plete s LookIn.
+ *   Budeme to řešit, nebo bude na autorovi si udělat remap?
+ */
 VerbRule(LookThrough)
-    ('look' | 'l') ('through' | 'thru' | 'out') dobjList
+    ('koukni' | 'kouknout' | 'koukej' | 'koukat' | 'nahlédni' | 'nahlédnout')
+    ('skrz' | 'skrze' | ) dobjList
+    | ('vykoukni' | 'vykouknout' | 'vyhlédni' | 'vyhlédnout') ('ven' | )
+    'z' dobjList
     : LookThroughAction
-    verbPhrase = 'look/looking (through what)'
+    verbPhrase = 'kouknout/kouk{áš}/koukl{a} (skrz co)'
 ;
 
 VerbRule(LookUnder)
-    ('look' | 'l') 'under' dobjList
+    ('podívej' | 'podívat' | 'koukni' | 'kouknount' | 'koukej' | 'koukat' |
+    'nahlédni' | 'nahlédnout') ( | 'se') 'pod' dobjList
     : LookUnderAction
-    verbPhrase = 'look/looking (under what)'
+    verbPhrase = 'kouknout/kouk{áš}/koukl{a} (pod co)'
 ;
 
 VerbRule(LookBehind)
-    ('look' | 'l') 'behind' dobjList
+    ('koukni' | 'kouknount' | 'koukej' | 'koukat' | 'nahlédni' | 'nahlédnout')
+    'za' dobjList
     : LookBehindAction
-    verbPhrase = 'look/looking (behind what)'
+    verbPhrase = 'kouknout/kouk{áš}/koukl{a} (za co)'
 ;
 
 VerbRule(Feel)
-    ('feel' | 'touch') dobjList
+    ('dotkni' | 'dotknout') 'se' dobjList
     : FeelAction
-    verbPhrase = 'touch/touching (what)'
+    verbPhrase = 'dotknout/dotýk{áš}/dotkl{a} (čeho)'
 ;
 
 VerbRule(Taste)
-    'taste' dobjList
+    ('ochutnej' | 'ochutnat') dobjList
     : TasteAction
-    verbPhrase = 'taste/tasting (what)'
+    verbPhrase = 'ochutnat/ochutnáv{áš}/ochutnal{a} (co)'
 ;
 
 VerbRule(Smell)
-    ('smell' | 'sniff') dobjList
+    ('čichej' | 'čichat' | 'čmuchej' | 'čmuchat' | 'čenichej' | 'čenichat'
+    | 'přivoň' | 'přivonět' | 'přičichni' | 'přičichnout') ('k' | 'ke' | )
+    dobjList
     : SmellAction
-    verbPhrase = 'smell/smelling (what)'
+    verbPhrase = 'přičichnout/cít{íš}/cítil{a} (k čemu)'
 
     /*
      *   use the "not aware" version of the no-match message - the object
      *   of SMELL is often intangible, so the default "you can't see that"
      *   message is often incongruous for this verb
      */
     noMatch(msgObj, actor, txt) { msgObj.noMatchNotAware(actor, txt); }
 ;
 
 VerbRule(SmellImplicit)
-    'smell' | 'sniff'
+    'čichej' | 'čichat' | 'čmuchej' | 'čmuchat' | 'čenichej' | 'čenichat'
     : SmellImplicitAction
-    verbPhrase = 'smell/smelling'
+    verbPhrase = 'čichat/cít{íš}/cítil{a}'
 ;
 
 VerbRule(ListenTo)
-    ('hear' | 'listen' 'to' ) dobjList
+    ('poslouchej' | 'poslouchat' | 'naslouchej' | 'naslouchat' | 'slyš'
+    | 'slyšet') ('k' | 'ke' | ) dobjList
     : ListenToAction
-    verbPhrase = 'listen/listening (to what)'
+    verbPhrase = 'naslouchat/naslouch{áš}/naslouchal{a} (čemu)'
 
     /*
      *   use the "not aware" version of the no-match message - the object
      *   of LISTEN TO is often intangible, so the default "you can't see
      *   that" message is often incongruous for this verb
      */
     noMatch(msgObj, actor, txt) { msgObj.noMatchNotAware(actor, txt); }
 ;
 
 VerbRule(ListenImplicit)
-    'listen' | 'hear'
+    'poslouchej' | 'poslouchat' | 'naslouchej' | 'naslouchat'
     : ListenImplicitAction
-    verbPhrase = 'listen/listening'
+    verbPhrase = 'naslouchat/naslouch{áš}/naslouchal{a}'
 ;
 
 VerbRule(PutIn)
-    ('put' | 'place' | 'set') dobjList
-        ('in' | 'into' | 'in' 'to' | 'inside' | 'inside' 'of') singleIobj
+    ('dej' | 'dát' | 'polož' | 'položit' | 'vlož' | 'vložit' | 'umísti'
+    | 'umístit') dobjList 'do' singleIobj
     : PutInAction
-    verbPhrase = 'put/putting (what) (in what)'
+    verbPhrase = 'dát/dáv{áš}/dal{a} (co) (do čeho)'
     askIobjResponseProd = inSingleNoun
 ;
 
 VerbRule(PutOn)
-    ('put' | 'place' | 'drop' | 'set') dobjList
-        ('on' | 'onto' | 'on' 'to' | 'upon') singleIobj
-    | 'put' dobjList 'down' 'on' singleIobj
+    ('dej' | 'dát' | 'polož' | 'položit' | 'vlož' | 'vložit' | 'umísti'
+    | 'umístit') dobjList 'na' singleIobj
     : PutOnAction
-    verbPhrase = 'put/putting (what) (on what)'
+    verbPhrase = 'dát/dáv{áš}/dal{a} (co) (na co)'
     askIobjResponseProd = onSingleNoun
 ;
 
 VerbRule(PutUnder)
-    ('put' | 'place' | 'set') dobjList 'under' singleIobj
+    ('dej' | 'dát' | 'polož' | 'položit' | 'vlož' | 'vložit' | 'umísti'
+    | 'umístit') dobjList 'pod' singleIobj
     : PutUnderAction
-    verbPhrase = 'put/putting (what) (under what)'
+    verbPhrase = 'dát/dáv{áš}/dal{a} (co) (pod co)'
 ;
 
 VerbRule(PutBehind)
-    ('put' | 'place' | 'set') dobjList 'behind' singleIobj
+    ('dej' | 'dát' | 'polož' | 'položit' | 'vlož' | 'vložit' | 'umísti'
+    | 'umístit') dobjList 'za' singleIobj
     : PutBehindAction
-    verbPhrase = 'put/putting (what) (behind what)'
+    verbPhrase = 'dát/dáv{áš}/dal{a} (co) (za co)'
 ;
 
 VerbRule(PutInWhat)
-    [badness 500] ('put' | 'place') dobjList
+    [badness 500] ('vlož' | 'vložit') dobjList
     : PutInAction
-    verbPhrase = 'put/putting (what) (in what)'
+    verbPhrase = 'dát/dáv{áš}/dal{a} (co) (do čeho)'
     construct()
     {
         /* set up the empty indirect object phrase */
         iobjMatch = new EmptyNounPhraseProd();
         iobjMatch.responseProd = inSingleNoun;
     }
 ;
 
 VerbRule(Wear)
-    ('wear' | 'don' | 'put' 'on') dobjList
-    | 'put' dobjList 'on'
+    ('oblékni' | 'obléknout' | 'obleč' | 'obléci' | 'nandej' | 'nandat'
+    | 'nasaď' | 'nasadit' | 'obuj' | 'obout' | 'nazuj' | 'nazout') ('si' | )
+    dobjList
     : WearAction
-    verbPhrase = 'wear/wearing (what)'
+    verbPhrase = 'nandat/nandav{áš}/nandal{a} (co) si'
 ;
 
 VerbRule(Doff)
-    ('doff' | 'take' 'off') dobjList
-    | 'take' dobjList 'off'
+    ('svlékni' | 'svléknout' | 'svleč' | 'svléci' | 'sundej' | 'sundat' | 'zuj'
+    | 'zout') ('si' | ) dobjList
     : DoffAction
-    verbPhrase = 'take/taking off (what)'
+    verbPhrase = 'sundat/sundav{áš}/sundal{a} (co) si'
+    askDobjResponseProd = singleNoun
 ;
 
 VerbRule(Kiss)
-    'kiss' singleDobj
+    ('polib' | 'políbit') singleDobj
     : KissAction
-    verbPhrase = 'kiss/kissing (whom)'
+    verbPhrase = 'políbit/líb{áš}/líbal{a} (koho)'
 ;
 
 VerbRule(AskFor)
-    ('ask' | 'a') singleDobj 'for' singleTopic
-    | ('ask' | 'a') 'for' singleTopic 'from' singleDobj
+    ('požádej' | 'požádat' | 'popros' | 'poprosit') singleDobj 'o' singleTopic
+    | ('řekni' | 'říci') 'si' 'o' singleTopic singleDobj
     : AskForAction
-    verbPhrase = 'ask/asking (whom) (for what)'
+    verbPhrase = 'požádat/žád{áš}/požádal{a} (koho) (o co)'
     omitIobjInDobjQuery = true
     askDobjResponseProd = singleNoun
     askIobjResponseProd = forSingleNoun
 ;
 
 VerbRule(AskWhomFor)
-    ('ask' | 'a') 'for' singleTopic
+    ('požádej' | 'požádat' | 'popros' | 'poprosit' | ('řekni' | 'říci') 'si')
+    'o' singleTopic
     : AskForAction
-    verbPhrase = 'ask/asking (whom) (for what)'
+    verbPhrase = 'požádat/žád{áš}/požádal{a} (koho) (o co)'
     omitIobjInDobjQuery = true
     construct()
     {
         /* set up the empty direct object phrase */
         dobjMatch = new EmptyNounPhraseProd();
         dobjMatch.responseProd = singleNoun;
     }
 ;
 
 VerbRule(AskAbout)
-    ('ask' | 'a') singleDobj 'about' singleTopic
+    ('zeptej' | 'zeptat' | 'poptej' | 'poptat' | 'ptej' | 'ptát') ('se' | )
+    singleDobj 'na' singleTopic
     : AskAboutAction
-    verbPhrase = 'ask/asking (whom) (about what)'
+    verbPhrase = 'zeptat/pt{áš}/zeptal{a} (koho) (na co) se'
     omitIobjInDobjQuery = true
     askDobjResponseProd = singleNoun
 ;
 
 VerbRule(AskAboutImplicit)
-    'a' singleTopic
+    ('zeptej' | 'zeptat' | 'poptej' | 'poptat' | 'ptej' | 'ptát') 'se' 'na'
+    singleTopic
+    | 'zep' singleTopic
     : AskAboutAction
-    verbPhrase = 'ask/asking (whom) (about what)'
+    verbPhrase = 'zeptat/pt{áš}/zeptal{a} (koho) (na co) se'
     omitIobjInDobjQuery = true
     construct()
     {
         /* set up the empty direct object phrase */
         dobjMatch = new EmptyNounPhraseProd();
         dobjMatch.responseProd = singleNoun;
     }
 ;
 
 VerbRule(AskAboutWhat)
-    [badness 500] 'ask' singleDobj
+    [badness 500] ('zeptej' | 'zeptat' | 'poptej' | 'poptat' | 'ptej' | 'ptát')
+    'se' singleDobj
     : AskAboutAction
-    verbPhrase = 'ask/asking (whom) (about what)'
+    verbPhrase = 'zeptat/pt{áš}/zeptal{a} (koho) (na co) se'
     askDobjResponseProd = singleNoun
     omitIobjInDobjQuery = true
     construct()
     {
         /* set up the empty topic phrase */
         topicMatch = new EmptyNounPhraseProd();
         topicMatch.responseProd = aboutTopicPhrase;
     }
 ;
 
 
 VerbRule(TellAbout)
-    ('tell' | 't') singleDobj 'about' singleTopic
+    ('řekni' | 'říci') singleDobj 'o' singleTopic
     : TellAboutAction
-    verbPhrase = 'tell/telling (whom) (about what)'
+    verbPhrase = 'říci/řík{áš}/řekl{a} (komu) (o čem)'
     askDobjResponseProd = singleNoun
     omitIobjInDobjQuery = true
 ;
 
 VerbRule(TellAboutImplicit)
-    't' singleTopic
+    ('řekni' | 'říci') 'o' singleTopic
+    | 'řek' singleTopic
     : TellAboutAction
-    verbPhrase = 'tell/telling (whom) (about what)'
+    verbPhrase = 'říci/řík{áš}/řekl{a} (komu) (o čem)'
     omitIobjInDobjQuery = true
     construct()
     {
         /* set up the empty direct object phrase */
         dobjMatch = new EmptyNounPhraseProd();
         dobjMatch.responseProd = singleNoun;
     }
 ;
 
 VerbRule(TellAboutWhat)
-    [badness 500] 'tell' singleDobj
+    [badness 500] ('řekni' | 'říci') singleDobj
     : TellAboutAction
-    verbPhrase = 'tell/telling (whom) (about what)'
+    verbPhrase = 'říci/řík{áš}/řekl{a} (komu) (o čem)'
     askDobjResponseProd = singleNoun
     omitIobjInDobjQuery = true
     construct()
     {
         /* set up the empty topic phrase */
         topicMatch = new EmptyNounPhraseProd();
         topicMatch.responseProd = aboutTopicPhrase;
     }
 ;
 
-VerbRule(AskVague)
-    [badness 500] 'ask' singleDobj singleTopic
-    : AskVagueAction
-    verbPhrase = 'ask/asking (whom)'
-;
-
-VerbRule(TellVague)
-    [badness 500] 'tell' singleDobj singleTopic
-    : AskVagueAction
-    verbPhrase = 'ask/asking (whom)'
-;
+//VerbRule(AskVague)
+//    [badness 500] 'ask' singleDobj singleTopic
+//    : AskVagueAction
+//    verbPhrase = 'ask/asking (whom)'
+//;
+
+//VerbRule(TellVague)
+//    [badness 500] 'tell' singleDobj singleTopic
+//    : AskVagueAction
+//    verbPhrase = 'ask/asking (whom)'
+//;
 
 VerbRule(TalkTo)
-    ('greet' | 'say' 'hello' 'to' | 'talk' 'to') singleDobj
+    ('pozdrav' | 'pozdravit' | ('mluv' | 'mluvit' | 'promluv' | 'promluvit')
+    ('s' | 'na')) singleDobj
     : TalkToAction
-    verbPhrase = 'talk/talking (to whom)'
+    verbPhrase = 'mluvit/mluv{íš}/mluvil{a} (s kým)'
     askDobjResponseProd = singleNoun
 ;
 
 VerbRule(TalkToWhat)
-    [badness 500] 'talk'
+    [badness 500] 'pozdrav' | 'pozdravit' | 'mluv' | 'mluvit' | 'promluv'
+    | 'promluvit'
     : TalkToAction
-    verbPhrase = 'talk/talking (to whom)'
+    verbPhrase = 'mluvit/mluv{íš}/mluvil{a} (s kým)'
     askDobjResponseProd = singleNoun
 
     construct()
     {
         /* set up the empty direct object phrase */
         dobjMatch = new EmptyNounPhraseProd();
         dobjMatch.responseProd = onSingleNoun;
     }
 ;
 
 VerbRule(Topics)
-    'topics'
+    ('ukaž' | 'ukázat' | 'zobraz' | 'zobrazit' | 'vypiš' | 'vypsat' | )
+    ('témata' | 'téma' | 'tém' | 't')
     : TopicsAction
-    verbPhrase = 'show/showing topics'
+    verbPhrase = 'ukázat/ukazu{ješ}/ukazoval{a} témata'
 ;
 
 VerbRule(Hello)
-    ('say' | ) ('hello' | 'hallo' | 'hi')
+    ('řekni' | 'říci' | ) ('ahoj' | 'nazdar' | 'čau' | 'dobrý' 'den')
+    | ('pozdrav' | 'pozdravit') ('se' | )
     : HelloAction
-    verbPhrase = 'say/saying hello'
+    verbPhrase = 'pozdravit/zdrav{íš}/pozdravil{a}'
 ;
 
 VerbRule(Goodbye)
-    ('say' | ()) ('goodbye' | 'good-bye' | 'good' 'bye' | 'bye')
+    ('řekni' | 'říci' | ) ('nasledanou' | 'sbohem')
+    | ('rozluč' | 'rouzloučit') ('se' | )
     : GoodbyeAction
-    verbPhrase = 'say/saying goodbye'
+    verbPhrase = 'rozloučit/louč{íš}/rozloučil{a} se'
 ;
 
 VerbRule(Yes)
-    'yes' | 'affirmative' | 'say' 'yes'
+    ('řekni' | 'říci' | 'odpověz' | 'odpovědět' | ) ('ano' | 'jo')
     : YesAction
-    verbPhrase = 'say/saying yes'
+    verbPhrase = 'říci/řík{áš}/řekl{a} ano'
 ;
 
 VerbRule(No)
-    'no' | 'negative' | 'say' 'no'
+    ('řekni' | 'říci' | 'odpověz' | 'odpovědět' | ) 'ne'
     : NoAction
-    verbPhrase = 'say/saying no'
+    verbPhrase = 'říci/řík{áš}/řekl{a} ne'
 ;
 
 VerbRule(Yell)
-    'yell' | 'scream' | 'shout' | 'holler'
+    'zakřič' | 'zakřičet' | 'zaječ' | 'zaječet' | 'zazřvi' | 'zařvat'
     : YellAction
-    verbPhrase = 'yell/yelling'
+    verbPhrase = 'zakřičet/křič{íš}/zakřičel{a}'
 ;
 
 VerbRule(GiveTo)
-    ('give' | 'offer') dobjList 'to' singleIobj
+    ('dej' | 'dát' | 'podej' | 'podat' | 'nabídni' | 'nabídnout') dobjList
+    singleIobj
     : GiveToAction
-    verbPhrase = 'give/giving (what) (to whom)'
+    verbPhrase = 'dát/dáv{áš}/dal{a} (co) (komu)'
     askIobjResponseProd = toSingleNoun
+    isPrepositionalPhrasing = nil
 ;
-
 VerbRule(GiveToType2)
-    ('give' | 'offer') singleIobj dobjList
+    ('dej' | 'dát' | 'podej' | 'podat' | 'nabídni' | 'nabídnout') singleIobj
+    dobjList
     : GiveToAction
-    verbPhrase = 'give/giving (what) (to whom)'
+    verbPhrase = 'dát/dáv{áš}/dal{a} (co) (komu)'
     askIobjResponseProd = toSingleNoun
-
-    /* this is a non-prepositional phrasing */
     isPrepositionalPhrasing = nil
 ;
 
+/*
+ * Tady vlastne (komucemu) me vaze na urceni padu v ">dej minci" "(mladé
+ * prodavačce)". To se urcuje kolem radku 8680. Jenze viz 9660 je obsah
+ * zavorky pouzivan take ve vetach typu "Do čeho chceš vstoupit?"
+ * Druhá závorka (komu) se použije "Komu chceš dát xxx"
+ */
 VerbRule(GiveToWhom)
-    ('give' | 'offer') dobjList
+    ('dej' | 'dát' | 'podej' | 'podat' | 'nabídni' | 'nabídnout') dobjList
     : GiveToAction
-    verbPhrase = 'give/giving (what) (to whom)'
+    verbPhrase = 'dát/dáv{áš}/dal{a} (co) (komu)'
     construct()
     {
         /* set up the empty indirect object phrase */
         iobjMatch = new ImpliedActorNounPhraseProd();
         iobjMatch.responseProd = toSingleNoun;
     }
 ;
 
-VerbRule(ShowTo)
-    'show' dobjList 'to' singleIobj
-    : ShowToAction
-    verbPhrase = 'show/showing (what) (to whom)'
-    askIobjResponseProd = toSingleNoun
-;
+/*
+ *   TODO: Tady bych měl řešit "ukaž prsten uhlířovi". Problém je, že když
+ *   vynechám předložku "to", tak místo toho zabere ShowToType2 a to samozřejmě
+ *   prohlásí, že diamantovému prstenu nelze uhlíře ukázat.
+ */
+//VerbRule(ShowTo)
+//    'ukaž' dobjList 'to' singleIobj
+//    : ShowToAction
+//    verbPhrase = 'ukázat/ukazu{ješ}/ukázal{a} (co) (komu)'
+//    askIobjResponseProd = toSingleNoun
+//
+//    /* this is a non-prepositional phrasing */
+//    isPrepositionalPhrasing = nil
+//;
 
 VerbRule(ShowToType2)
-    'show' singleIobj dobjList
+    ('ukaž' | 'ukázat') singleIobj dobjList
     : ShowToAction
-    verbPhrase = 'show/showing (what) (to whom)'
+    verbPhrase = 'ukázat/ukazu{ješ}/ukázal{a} (co) (komu)'
     askIobjResponseProd = toSingleNoun
 
     /* this is a non-prepositional phrasing */
     isPrepositionalPhrasing = nil
 ;
 
 VerbRule(ShowToWhom)
-    'show' dobjList
+    ('ukaž' | 'ukázat') dobjList
     : ShowToAction
-    verbPhrase = 'show/showing (what) (to whom)'
+    verbPhrase = 'ukázat/ukazu{ješ}/ukázal{a} (co) (komu)'
     construct()
     {
         /* set up the empty indirect object phrase */
         iobjMatch = new ImpliedActorNounPhraseProd();
         iobjMatch.responseProd = toSingleNoun;
     }
 ;
 
 VerbRule(Throw)
-    ('throw' | 'toss') dobjList
+    ('hoď' | 'hodit' | 'vrhni' | 'vrhnout') dobjList
     : ThrowAction
-    verbPhrase = 'throw/throwing (what)'
+    verbPhrase = 'hodit/ház{íš}/hodil{a} (co)'
 ;
 
 VerbRule(ThrowAt)
-    ('throw' | 'toss') dobjList 'at' singleIobj
+    ('hoď' | 'hodit' | 'vrhni' | 'vrhnout') dobjList ('na' | 'po' | 'do') singleIobj
     : ThrowAtAction
-    verbPhrase = 'throw/throwing (what) (at what)'
+    verbPhrase = 'hodit/ház{íš}/hodil{a} (co) (na co)'
     askIobjResponseProd = atSingleNoun
 ;
 
 VerbRule(ThrowTo)
-    ('throw' | 'toss') dobjList 'to' singleIobj
+    ('hoď' | 'hodit') dobjList singleIobj
     : ThrowToAction
-    verbPhrase = 'throw/throwing (what) (to whom)'
+    verbPhrase = 'hodit/ház{íš}/hodil{a} (co) (komu)'
     askIobjResponseProd = toSingleNoun
+
+    /* this is a non-prepositional phrasing */
+    isPrepositionalPhrasing = nil
 ;
 
 VerbRule(ThrowToType2)
-    'throw' singleIobj dobjList
+    ('hoď' | 'hodit') singleIobj dobjList
     : ThrowToAction
-    verbPhrase = 'throw/throwing (what) (to whom)'
+    verbPhrase = 'hodit/ház{íš}/hodil{a} (co) (komu)'
     askIobjResponseProd = toSingleNoun
 
     /* this is a non-prepositional phrasing */
     isPrepositionalPhrasing = nil
 ;
 
 VerbRule(ThrowDir)
-    ('throw' | 'toss') dobjList ('to' ('the' | ) | ) singleDir
+    ('hoď' | 'hodit' | 'vrhni' | 'vrhnout') dobjList ('na' | ) singleDir
     : ThrowDirAction
-    verbPhrase = ('throw/throwing (what) ' + dirMatch.dir.name)
+    /* TODO: Je tu směr správně? Nepotřebuje doplnit předložku? */
+    verbPhrase = ('hodit/ház{íš}/hodil{a} (co) ' + dirMatch.dir.name)
 ;
 
 /* a special rule for THROW DOWN <dobj> */
 VerbRule(ThrowDirDown)
-    'throw' ('down' | 'd') dobjList
+    ('odhoď' | 'odhodit' | 'shoď' | 'shodit' | 'hoď' | 'hodit')
+    ( | 'dolů' | 'dolu') dobjList
     : ThrowDirAction
-    verbPhrase = ('throw/throwing (what) down')
+    verbPhrase = ('odhodit/odhazu{ješ}/odhodil{a} (co)')
 
     /* the direction is fixed as 'down' for this phrasing */
     getDirection() { return downDirection; }
 ;
 
 VerbRule(Follow)
-    'follow' singleDobj
+    ('následuj' | 'následnovat' | 'sleduj' | 'sledovat') singleDobj
+    | ('jdi' | 'jít') 'za' singleDobj
     : FollowAction
-    verbPhrase = 'follow/following (whom)'
+    verbPhrase = 'následovat/následu{ješ}/následoval{a} (koho)'
     askDobjResponseProd = singleNoun
 ;
 
 VerbRule(Attack)
-    ('attack' | 'kill' | 'hit' | 'kick' | 'punch') singleDobj
+    ('zaútoč' 'na' | 'zaútočit' 'na' | 'zabij' | 'zabít' | 'zasáhni'
+    | 'zasáhnout' | 'udeř' | 'udeřit' | 'kopni' | 'kopnout' | 'bouchni'
+    | 'bouchnout') singleDobj
     : AttackAction
-    verbPhrase = 'attack/attacking (whom)'
+    verbPhrase = 'zaútočit/útoč{íš}/zaútočil{a} (na koho)'
     askDobjResponseProd = singleNoun
 ;
 
+/* TODO: rozdělit na prepositional phrasing a nonprep. phrasing */
 VerbRule(AttackWith)
-    ('attack' | 'kill' | 'hit' | 'kick' | 'punch' | 'strike')
-        singleDobj
-        'with' singleIobj
+    ('zaútoč' 'na' | 'zaútočit' 'na' | 'zabij' | 'zabít' | 'zasáhni'
+    | 'zasáhnout' | 'udeř' | 'udeřit' | 'kopni' | 'kopnout' | 'bouchni'
+    | 'bouchnout') singleDobj singleIobj
     : AttackWithAction
-    verbPhrase = 'attack/attacking (whom) (with what)'
+    verbPhrase = 'zaútočit/útoč{íš}/zaútočil{a} (na koho) (čím)'
     askDobjResponseProd = singleNoun
     askIobjResponseProd = withSingleNoun
 ;
 
 VerbRule(Inventory)
-    'i' | 'inventory' | 'take' 'inventory'
+    'i' | 'inv' | 'inventář'
     : InventoryAction
-    verbPhrase = 'take/taking inventory'
+    verbPhrase = 'prohlídnout/prohlíž{íš}/prohlídl{a} i inventář'
 ;
 
 VerbRule(InventoryTall)
-    'i' 'tall' | 'inventory' 'tall'
+    'i' 'na' 'výšku' | 'inv' 'na' 'výšku' | 'inventář' 'na' 'výšku'
+    | 'vysoký' 'inventář' | 'vysoký' 'inv' | 'vysoký' 'i'
     : InventoryTallAction
-    verbPhrase = 'take/taking "tall" inventory'
+    verbPhrase = 'prohlídnout/prohlíž{íš}/prohlídl{a} inventář na výšku'
 ;
 
 VerbRule(InventoryWide)
-    'i' 'wide' | 'inventory' 'wide'
+    'i' 'na' 'šířku' | 'inv' 'na' 'šířku' | 'inventář' 'na' 'šířku'
+    | 'široký' 'inventář' | 'široký' 'inv' | 'široký' 'i'
     : InventoryWideAction
-    verbPhrase = 'take/taking "wide" inventory'
+    verbPhrase = 'prohlídnout/prohlíž{íš}/prohlídl{a} inventář na šířku'
 ;
 
 VerbRule(Wait)
-    'z' | 'wait'
+    'č' | 'ček' | 'čekej' | 'čekat'
     : WaitAction
-    verbPhrase = 'wait/waiting'
+    verbPhrase = 'počkat/ček{áš}/počkal{a}'
 ;
 
 VerbRule(Look)
-    'look' | 'look' 'around' | 'l' | 'l' 'around'
+    ('rozhlédni' | 'rozhlédnout' | 'porozhlédni' | 'porozhlédnout') ('se' | )
+    | 'roz' | 'r' | 'situace' | 'sit'
     : LookAction
-    verbPhrase = 'look/looking around'
+    verbPhrase = 'rozhlédnout/rozhlíž{íš}/rozhlédl{a} se'
 ;
 
 VerbRule(Quit)
-    'quit' | 'q'
+    'konec' | 'kon' | 'k'
     : QuitAction
-    verbPhrase = 'quit/quitting'
+    verbPhrase = 'ukončit/ukonču{ješ}/ukončil{a}'
 ;
 
 VerbRule(Again)
-    'again' | 'g'
+    'znovu' | 'zno' | 'zn'
     : AgainAction
-    verbPhrase = 'repeat/repeating the last command'
+    verbPhrase = 'zopakovat/opaku{ješ}/zopakoval{a} poslední příkaz'
 ;
 
 VerbRule(Footnote)
-    ('footnote' | 'note') singleNumber
+    ('poznámka' | 'poz') singleNumber
     : FootnoteAction
-    verbPhrase = 'show/showing a footnote'
+    verbPhrase = 'ukázat/ukazu{ješ}/ukázal{a} poznámku pod čarou'
 ;
 
 VerbRule(FootnotesFull)
-    'footnotes' 'full'
+    'poznámky' 'naplno'
     : FootnotesFullAction
-    verbPhrase = 'enable/enabling all footnotes'
+    verbPhrase = 'zapnout/zapín{áš}/zapnul{a} všechny poznámky'
 ;
 
 VerbRule(FootnotesMedium)
-    'footnotes' 'medium'
+    'poznámky' 'středně'
     : FootnotesMediumAction
-    verbPhrase = 'enable/enabling new footnotes'
+    verbPhrase = 'zapnout/zapín{áš}/zapnul{a} nové poznámky'
 ;
 
 VerbRule(FootnotesOff)
-    'footnotes' 'off'
+    'poznámky' 'vypnuté'
     : FootnotesOffAction
-    verbPhrase = 'hide/hiding footnotes'
+    verbPhrase = 'skrýt/skrýv{áš}/skryl{a} poznámky'
 ;
 
 VerbRule(FootnotesStatus)
-    'footnotes'
+    'poznámky' | 'nastavení' 'poznámek'
     : FootnotesStatusAction
-    verbPhrase = 'show/showing footnote status'
+    verbPhrase = 'ukázat/ukazu{ješ}/ukázal{a} nastavení poznámek'
 ;
 
 VerbRule(TipsOn)
-    ('tips' | 'tip') 'on'
+    ('zapni' | 'zapnout' | 'zap') 'tipy'
     : TipModeAction
 
     stat_ = true
 
-    verbPhrase = 'turn/turning tips on'
+    verbPhrase = 'zapnout/zapín{áš}/zapnul{a} tipy'
 ;
 
 VerbRule(TipsOff)
-    ('tips' | 'tip') 'off'
+    ('vypni' | 'vypnout' | 'vyp') 'tipy'
     : TipModeAction
 
     stat_ = nil
 
-    verbPhrase = 'turn/turning tips off'
+    verbPhrase = 'vypnout/vypín{áš}/vypnul{a} tipy'
 ;
 
 VerbRule(Verbose)
-    'verbose'
+    'upovídaný'
     : VerboseAction
-    verbPhrase = 'enter/entering VERBOSE mode'
+    verbPhrase = 'přepnout/přepín{áš}/přepnul{a} na UPOVÍDANÝ režim'
 ;
 
 VerbRule(Terse)
-    'terse' | 'brief'
+    'stručný'
     : TerseAction
-    verbPhrase = 'enter/entering BRIEF mode'
+    verbPhrase = 'přepnout/přepín{áš}/přepnul{a} na STRUČNÝ režim'
 ;
 
 VerbRule(Score)
-    'score' | 'status'
+    'skóre'
     : ScoreAction
-    verbPhrase = 'show/showing score'
+    verbPhrase = 'ukázat/ukazu{ješ}/ukázal{a} skóre'
 ;
 
 VerbRule(FullScore)
-    'full' 'score' | 'fullscore' | 'full'
+    ('detailní' | 'podrobné') 'skóre'
     : FullScoreAction
-    verbPhrase = 'show/showing full score'
+    verbPhrase = 'ukázat/ukazu{ješ}/ukázal{a} detailní skóre'
 ;
 
 VerbRule(Notify)
-    'notify'
+    ('nastavení' | ) 'upozorňování'
     : NotifyAction
-    verbPhrase = 'show/showing notification status'
+    verbPhrase = 'ukázat/ukazu{ješ}/ukázal{a} nastavení upozorňování'
 ;
 
 VerbRule(NotifyOn)
-    'notify' 'on'
+    ('zapni' | 'zapnout' | 'zap') 'upozorňování'
     : NotifyOnAction
-    verbPhrase = 'turn/turning on score notification'
+    verbPhrase = 'zapnout/zapín{áš}/zapnul{a} upozorňování na skóre'
 ;
 
 VerbRule(NotifyOff)
-    'notify' 'off'
+    ('vypni' | 'vypnout' | 'vyp') 'upozorňování'
     : NotifyOffAction
-    verbPhrase = 'turn/turning off score notification'
+    verbPhrase = 'vypnout/vypín{áš}/vypnul{a} upozorňování na skóre'
 ;
 
 VerbRule(Save)
-    'save'
+    'ulož' | 'uložit'
     : SaveAction
-    verbPhrase = 'save/saving'
+    verbPhrase = 'uložit/uklád{áš}/uložil{a}'
 ;
 
 VerbRule(SaveString)
-    'save' quotedStringPhrase->fname_
+    ('ulož' | 'uložit') quotedStringPhrase->fname_
     : SaveStringAction
-    verbPhrase = 'save/saving'
+    verbPhrase = 'uložit/uklád{áš}/uložil{a}'
 ;
 
 VerbRule(Restore)
-    'restore'
+    ('načti' | 'načíst' | 'nahraj' | 'nahrát')
     : RestoreAction
-    verbPhrase = 'restore/restoring'
+    verbPhrase = 'načíst/načít{áš}/načetl{a}'
 ;
 
 VerbRule(RestoreString)
-    'restore' quotedStringPhrase->fname_
+    ('načti' | 'načíst' | 'nahraj' | 'nahrát') quotedStringPhrase->fname_
     : RestoreStringAction
-    verbPhrase = 'restore/restoring'
+    verbPhrase = 'načíst/načít{áš}/načetl{a}'
 ;
 
 VerbRule(SaveDefaults)
-    'save' 'defaults'
+    ('ulož' | 'uložit') 'nastavení'
     : SaveDefaultsAction
-    verbPhrase = 'save/saving defaults'
+    verbPhrase = 'uložit/uklád{áš}/uložil{a} výchozí nastavení'
 ;
 
 VerbRule(RestoreDefaults)
-    'restore' 'defaults'
+    ('načti' | 'načíst' | 'nahraj' | 'nahrát') 'nastavení'
     : RestoreDefaultsAction
-    verbPhrase = 'restore/restoring defaults'
+    verbPhrase = 'načíst/načít{áš}/načetl{a} výchozí nastavení'
 ;
 
 VerbRule(Restart)
-    'restart'
+    'restartuj' | 'restartovat'
     : RestartAction
-    verbPhrase = 'restart/restarting'
+    verbPhrase = 'restartovat/restartu{ješ}/restartoval{a}'
 ;
 
 VerbRule(Pause)
-    'pause'
+    'pauza'
     : PauseAction
-    verbPhrase = 'pause/pausing'
+    verbPhrase = 'pozastavit/pozastavu{ješ}/pozastavil{a} hru'
 ;
 
 VerbRule(Undo)
-    'undo'
+    ('vrať' | 'vrátit') 'tah'
     : UndoAction
-    verbPhrase = 'undo/undoing'
+    verbPhrase = 'vrátit/vrac{íš}/vrátil{a} tah'
 ;
 
 VerbRule(Version)
-    'version'
+    'verze'
     : VersionAction
-    verbPhrase = 'show/showing version'
+    verbPhrase = 'ukázat/ukazu{ješ}/ukázal{a} verzi'
 ;
 
 VerbRule(Credits)
-    'credits'
+    'zásluhy' | 'autor' | 'autoři' | 'titulky'
     : CreditsAction
-    verbPhrase = 'show/showing credits'
+    verbPhrase = 'ukázat/ukazu{ješ}/ukázal{a} titulky'
 ;
 
 VerbRule(About)
-    'about'
+    'o' 'hře' | 'o' 'příběhu' | 'informace' | 'info'
     : AboutAction
-    verbPhrase = 'show/showing story information'
+    verbPhrase = 'ukázat/ukazu{ješ}/ukázal{a} informace o příběhu'
 ;
 
 VerbRule(Script)
-    'script' | 'script' 'on'
+    ('zapni' | 'zapnout' | ) ('zápis' | 'zapisování')
     : ScriptAction
-    verbPhrase = 'start/starting scripting'
+    verbPhrase = 'zahájit/zahaju{ješ}/zahájil{a} zápis průběhu hry'
 ;
 
 VerbRule(ScriptString)
-    'script' quotedStringPhrase->fname_
+    'zápis' quotedStringPhrase->fname_
     : ScriptStringAction
-    verbPhrase = 'start/starting scripting'
+    verbPhrase = 'zahájit/zahaju{ješ}/zahájil{a} zápis průběhu hry'
 ;
 
 VerbRule(ScriptOff)
-    'script' 'off' | 'unscript'
+    ('vypni' | 'vypnout') ('zápis' | 'zapisování')
     : ScriptOffAction
-    verbPhrase = 'end/ending scripting'
+    verbPhrase = 'ukončit/ukonču{ješ}/ukončil{a} zápis průběhu hry'
 ;
 
 VerbRule(Record)
-    'record' | 'record' 'on'
+    ('zapni' | 'zapnout' | ) 'záznam'
     : RecordAction
-    verbPhrase = 'start/starting command recording'
+    verbPhrase = 'zahájit/zahaju{ješ}/zahájil{a} záznam příkazů'
 ;
 
 VerbRule(RecordString)
-    'record' quotedStringPhrase->fname_
+    'záznam' quotedStringPhrase->fname_
     : RecordStringAction
-    verbPhrase = 'start/starting command recording'
+    verbPhrase = 'zahájit/zahaju{ješ}/zahájil{a} záznam příkazů'
 ;
 
 VerbRule(RecordEvents)
-    'record' 'events' | 'record' 'events' 'on'
+    ('zapni' | 'zapnout' | ) 'záznam' 'událostí'
     : RecordEventsAction
-    verbPhrase = 'start/starting event recording'
+    verbPhrase = 'zahájit/zahaju{ješ}/zahájil{a} záznam událostí'
 ;
 
 VerbRule(RecordEventsString)
-    'record' 'events' quotedStringPhrase->fname_
+    'záznam' 'událostí' quotedStringPhrase->fname_
     : RecordEventsStringAction
-    verbPhrase = 'start/starting command recording'
+    verbPhrase = 'zahájit/zahaju{ješ}/zahájil{a} záznam událostí'
 ;
 
 VerbRule(RecordOff)
-    'record' 'off'
+    ('vypni' | 'vypnout') 'záznam'
     : RecordOffAction
-    verbPhrase = 'end/ending command recording'
+    verbPhrase = 'ukončit/ukonču{ješ}/ukončil{a} záznam'
 ;
 
 VerbRule(ReplayString)
-    'replay' ('quiet'->quiet_ | 'nonstop'->nonstop_ | )
+    ('přehraj' | 'přehrát') ('quiet'->quiet_ | 'nonstop'->nonstop_ | )
         (quotedStringPhrase->fname_ | )
     : ReplayStringAction
-    verbPhrase = 'replay/replaying command recording'
+    verbPhrase = 'přehrát/přehráváš/přehrála zaznamenané příkazy'
 
     /* set the appropriate option flags */
     scriptOptionFlags = ((quiet_ != nil ? ScriptFileQuiet : 0)
                          | (nonstop_ != nil ? ScriptFileNonstop : 0))
 ;
 VerbRule(ReplayQuiet)
-    'rq' (quotedStringPhrase->fname_ | )
+    ('přehraj' | 'přehrát') 'potichu' (quotedStringPhrase->fname_ | )
     : ReplayStringAction
 
     scriptOptionFlags = ScriptFileQuiet
 ;
 
-VerbRule(VagueTravel) 'go' | 'walk' : VagueTravelAction
-    verbPhrase = 'go'
+VerbRule(VagueTravel) 'jdi' | 'jít' | 'běž' : VagueTravelAction
+    verbPhrase = 'jít/jd{eš}/{šel}'
 ;
 
 VerbRule(Travel)
-    'go' singleDir | singleDir
+    ('jdi' | 'jít' | 'běž' | ) ('na' | ) singleDir
     : TravelAction
-    verbPhrase = ('go/going ' + dirMatch.dir.name)
+    verbPhrase = ('jít/jd{eš}/{šel} ' + dirMatch.dir.name)
 ;
 
 /*
  *   Create a TravelVia subclass merely so we can supply a verbPhrase.
  *   (The parser looks for subclasses of each specific Action class to find
  *   its verb phrase, since the language-specific Action definitions are
  *   always in the language module's 'grammar' subclasses.  We don't need
  *   an actual grammar rule, since this isn't an input-able verb, so we
  *   merely need to create a regular subclass in order for the verbPhrase
  *   to get found.)  
  */
 class EnTravelVia: TravelViaAction
-    verbPhrase = 'use/using (what)'
+    verbPhrase = 'projít/procház{íš}/pro{šel} (čím)'
 ;
 
 VerbRule(Port)
-    'go' 'to' ('port' | 'p')
+    (('jdi' | 'jít' | 'běž' | ) 'na' | ) 'levobok'
     : PortAction
     dirMatch: DirectionProd { dir = portDirection }
-    verbPhrase = 'go/going to port'
+    verbPhrase = 'jít/jd{eš}/{šel} na levobok'
 ;
 
 VerbRule(Starboard)
-    'go' 'to' ('starboard' | 'sb')
+    (('jdi' | 'jít' | 'běž' | ) 'na' | ) 'pravobok'
     : StarboardAction
     dirMatch: DirectionProd { dir = starboardDirection }
-    verbPhrase = 'go/going to starboard'
+    verbPhrase = 'jít/jd{eš}/{šel} na pravobok'
 ;
 
 VerbRule(In)
-    'enter'
+    'vejdi' | 'vejít' | 'vstup' | 'vstoupit' | 'do' | 'dov'
+    | ('jdi' | 'jít' | 'běž' | ) 'dovnitř'
     : InAction
     dirMatch: DirectionProd { dir = inDirection }
-    verbPhrase = 'enter/entering'
+    verbPhrase = 'vejít/vcház{íš}/ve{šel}'
 ;
 
 VerbRule(Out)
-    'exit' | 'leave'
+    'odejdi' | 'odejít' | 'vyjdi' | 'vyjít' | 'vylez' | 'vylézt' | 'opusť'
+    | 'opustit'
+    | ('jdi' | 'jít' | 'běž' | ) ('ven' | 'pryč')
     : OutAction
     dirMatch: DirectionProd { dir = outDirection }
-    verbPhrase = 'exit/exiting'
+    verbPhrase = 'vyjít/vycház{íš}/vy{šel}'
 ;
 
 VerbRule(GoThrough)
-    ('walk' | 'go' ) ('through' | 'thru')
-        singleDobj
+    ('jdi' | 'jít' | 'běž' | 'lez' | 'lézt' | ('plaz' | 'plazit') 'se')
+    ('skrz' | 'skrze' | 'po') singleDobj
+    | ('projdi' | 'prijít') singleDobj
     : GoThroughAction
-    verbPhrase = 'go/going (through what)'
+    verbPhrase = 'projít/projd{eš}/pro{šel} (čím)'
     askDobjResponseProd = singleNoun
 ;
 
 VerbRule(Enter)
-    ('enter' | 'in' | 'into' | 'in' 'to'
-     | ('walk' | 'go') ('to' | 'in' | 'in' 'to' | 'into'))
-    singleDobj
+    ('jdi' | 'jít' | 'vejdi' | 'vejít' | 'vstup' | 'vstoupit') ('do' | 'na') singleDobj
     : EnterAction
-    verbPhrase = 'enter/entering (what)'
-    askDobjResponseProd = singleNoun
+    verbPhrase = 'vstoupit/vstupu{ješ}/vstoupil{a} (do čeho)'
+    /*
+     *   Chceme umožnit odpověď s předložkou: ">dovnitř Do čeho chceš vstoupit?
+     *   Do čeho chceš vstoupit? >*do* pramice". Proc tady to reaguje na příkaz
+     *   "dovnitř", když ten je VerbRule(In)? dobjFor(Board) asDobjFor(Enter)
+     */
+    askDobjResponseProd = toSingleNoun
 ;
 
 VerbRule(GoBack)
-    'back' | 'go' 'back' | 'return'
+    ('jdi' | 'jít' | ) ('zpátky' | 'zpět')
+    | ('vrať' | 'vrátit') 'se'
     : GoBackAction
-    verbPhrase = 'go/going back'
+    verbPhrase = 'jít/jd{eš}/{šel} zpátky'
 ;
 
 VerbRule(Dig)
-    ('dig' | 'dig' 'in') singleDobj
+    ('vyhrabej' | 'vyhrab' | 'vyhrabat' | 'hrabej' | 'hrabat' | 'vyhlub'
+    | 'vyhloubit') 'díru' ( | 'v' | 'do') singleDobj
     : DigAction
-    verbPhrase = 'dig/digging (in what)'
+    verbPhrase = 'vyhloubit/hloub{íš}/vyhloubil{a} díru (v čem)'
     askDobjResponseProd = inSingleNoun
 ;
 
 VerbRule(DigWith)
-    ('dig' | 'dig' 'in') singleDobj 'with' singleIobj
+    ('vyhrabej' | 'vyhrab' | 'vyhrabat' | 'hrabej' | 'hrabat') 'díru'
+    ( | 'v' | 'do') singleDobj ('s' | 'pomocí' | ) singleIobj
     : DigWithAction
-    verbPhrase = 'dig/digging (in what) (with what)'
+    verbPhrase = 'vyhloubit/hloub{íš}/vyhloubil{a} díru (v čem) (čím)'
     omitIobjInDobjQuery = true
     askDobjResponseProd = inSingleNoun
     askIobjResponseProd = withSingleNoun
 ;
 
 VerbRule(Jump)
-    'jump'
+    'vyskoč' | 'vyskočit'
     : JumpAction
-    verbPhrase = 'jump/jumping'
+    verbPhrase = 'vyskočit/vyskaku{ješ}/vyskočil{a}'
 ;
 
 VerbRule(JumpOffI)
-    'jump' 'off'
+    'seskoč' | 'seskočit'
     : JumpOffIAction
-    verbPhrase = 'jump/jumping off'
+    verbPhrase = 'seskočit/seskaku{ješ}/seskočil{a}'
 ;
 
 VerbRule(JumpOff)
-    'jump' 'off' singleDobj
+    ('seskoč' | 'seskočit') ('z' | 'ze') singleDobj
     : JumpOffAction
-    verbPhrase = 'jump/jumping (off what)'
+    verbPhrase = 'seskočit/seskaku{ješ}/seskočil{a} (z čeho)'
     askDobjResponseProd = singleNoun
 ;
 
 VerbRule(JumpOver)
-    ('jump' | 'jump' 'over') singleDobj
+    ('přeskoč' | 'přeskočit') ( | 'přes') singleDobj
     : JumpOverAction
-    verbPhrase = 'jump/jumping (over what)'
+    verbPhrase = 'přeskočit/přeskaku{ješ}/přeskočil{a} (co)'
     askDobjResponseProd = singleNoun
 ;
 
 VerbRule(Push)
-    ('push' | 'press') dobjList
+    ('zmáčkni' | 'zmáčknout' | 'stiskni' | 'stisknout' | 'tlač' | 'tlačit') dobjList
+    | ('zatlač' | 'zatlačit') ( | 'na') dobjList
     : PushAction
-    verbPhrase = 'push/pushing (what)'
+    verbPhrase = 'zmáčknout/mačk{áš}/zmáčkl{a} (co)'
 ;
 
 VerbRule(Pull)
-    'pull' dobjList
+    ('zatáhni' | 'zatáhnout' | 'táhni' | 'táhnout') ('za' | ) dobjList
     : PullAction
-    verbPhrase = 'pull/pulling (what)'
+    verbPhrase = 'zatáhnout/táh{neš}/zatáhl{a} (za co)'
 ;
 
 VerbRule(Move)
-    'move' dobjList
+    ('odsuň' | 'odsunout' | 'posuň' | 'posunout') dobjList
     : MoveAction
-    verbPhrase = 'move/moving (what)'
+    verbPhrase = 'posunout/posouv{áš}/posunul{a} (co)'
 ;
 
 VerbRule(MoveTo)
-    ('push' | 'move') dobjList ('to' | 'under') singleIobj
+    ('posuň' | 'posunout') dobjList ('do' | 'pod') singleIobj
     : MoveToAction
-    verbPhrase = 'move/moving (what) (to what)'
+    verbPhrase = 'posunout/posouv{áš}/posunul{a} (co) (do čeho)'
     askIobjResponseProd = toSingleNoun
     omitIobjInDobjQuery = true
 ;
 
+/* TODO: rozdělit na prepositional phrasing a nonprep. phrasing */
 VerbRule(MoveWith)
-    'move' singleDobj 'with' singleIobj
+    ('posuň' | 'posunout') singleDobj 'pomocí' singleIobj
     : MoveWithAction
-    verbPhrase = 'move/moving (what) (with what)'
+    verbPhrase = 'posunout/posouv{áš}/posunul{a} (co) (čím)'
     askDobjResponseProd = singleNoun
     askIobjResponseProd = withSingleNoun
     omitIobjInDobjQuery = true
 ;
 
 VerbRule(Turn)
-    ('turn' | 'twist' | 'rotate') dobjList
+    ('otoč' | 'otočit') dobjList
     : TurnAction
-    verbPhrase = 'turn/turning (what)'
+    verbPhrase = 'otočit/otáč{íš}/otočil{a} (co)'
 ;
 
+/* TODO: rozdělit na prepositional phrasing a nonprep. phrasing */
 VerbRule(TurnWith)
-    ('turn' | 'twist' | 'rotate') singleDobj 'with' singleIobj
+    ('otoč' | 'otočit') singleDobj ('pomocí' | ) singleIobj
     : TurnWithAction
-    verbPhrase = 'turn/turning (what) (with what)'
+    verbPhrase = 'otočit/otáč{íš}/otočil{a} (co) (čím)'
     askDobjResponseProd = singleNoun
     askIobjResponseProd = withSingleNoun
 ;
 
 VerbRule(TurnTo)
-    ('turn' | 'twist' | 'rotate') singleDobj
-        'to' singleLiteral
+    ('otoč' | 'otočit' | 'natoč' | 'natočit') singleDobj 'na' singleLiteral
     : TurnToAction
-    verbPhrase = 'turn/turning (what) (to what)'
+    verbPhrase = 'natočit/natáč{íš}/natočil{a} (co) (na co)'
     askDobjResponseProd = singleNoun
     omitIobjInDobjQuery = true
 ;
 
 VerbRule(Set)
-    'set' dobjList
+    ('nastav' | 'nastavit') dobjList
     : SetAction
-    verbPhrase = 'set/setting (what)'
+    verbPhrase = 'nastavit/nastavu{ješ}/nastavil{a} (co)'
 ;
 
 VerbRule(SetTo)
-    'set' singleDobj 'to' singleLiteral
+    ('nastav' | 'nastavit') singleDobj 'na' singleLiteral
     : SetToAction
-    verbPhrase = 'set/setting (what) (to what)'
+    verbPhrase = 'nastavit/nastavu{ješ}/nastavil{a} (co) (na co)'
     askDobjResponseProd = singleNoun
     omitIobjInDobjQuery = true
 ;
 
 VerbRule(TypeOn)
-    'type' 'on' singleDobj
+    ('napiš' | 'napsat') singleDobj
     : TypeOnAction
-    verbPhrase = 'type/typing (on what)'
+    verbPhrase = 'napsat/píš{eš}/napsal{a} (na čem)'
 ;
 
 VerbRule(TypeLiteralOn)
-    'type' singleLiteral 'on' singleDobj
+    ('napiš' | 'napsat') singleLiteral 'na' singleDobj
     : TypeLiteralOnAction
-    verbPhrase = 'type/typing (what) (on what)'
+    verbPhrase = 'napsat/píš{eš}/napsal{a} (co) (na čem)'
     askDobjResponseProd = singleNoun
 ;
 
 VerbRule(TypeLiteralOnWhat)
-    [badness 500] 'type' singleLiteral
+    [badness 500] ('napiš' | 'napsat') singleLiteral
     : TypeLiteralOnAction
-    verbPhrase = 'type/typing (what) (on what)'
+    verbPhrase = 'napsat/píš{eš}/napsal{a} (co) (na čem)'
     construct()
     {
         /* set up the empty direct object phrase */
         dobjMatch = new EmptyNounPhraseProd();
         dobjMatch.responseProd = onSingleNoun;
     }
 ;
 
 VerbRule(EnterOn)
-    'enter' singleLiteral
-        ('on' | 'in' | 'in' 'to' | 'into' | 'with') singleDobj
+    ('zadej' | 'zadat') singleLiteral ('na' | 'do') singleDobj
     : EnterOnAction
-    verbPhrase = 'enter/entering (what) (on what)'
+    verbPhrase = 'zadat/zadáv{áš}/zadal{a} (co) (na čem)'
     askDobjResponseProd = singleNoun
 ;
 
 VerbRule(EnterOnWhat)
-    'enter' singleLiteral
+    ('zadej' | 'zadat') singleLiteral
     : EnterOnAction
-    verbPhrase = 'enter/entering (what) (on what)'
+    verbPhrase = 'zadat/zadáv{áš}/zadal{a} (co) (na čem)'
     construct()
     {
         /*
          *   ENTER <text> is a little special, because it could mean ENTER
          *   <text> ON <keypad>, or it could mean GO INTO <object>.  It's
          *   hard to tell which based on the grammar alone, so we have to
          *   do some semantic analysis to make a good decision about it.
          *
          *   We'll start by assuming it's the ENTER <text> ON <iobj> form
          *   of the command, and we'll look for a suitable default object
          *   to serve as the iobj.  If we can't find a suitable default, we
          *   won't prompt for the missing object as we usually would.
          *   Instead, we'll try re-parsing the command as GO INTO.  To do
          *   this, use our custom "asker" - this won't actually prompt for
          *   the missing object, but will instead retry the command as a GO
          *   INTO command.
          */
         dobjMatch = new EmptyNounPhraseProd();
         dobjMatch.setPrompt(onSingleNoun, enterOnWhatAsker);
     }
 ;
 
 /* our custom "asker" for the missing iobj in an "ENTER <text>" command */
 enterOnWhatAsker: ResolveAsker
     askMissingObject(targetActor, action, which)
     {
         /*
          *   This method is called when the resolver has failed to find a
          *   suitable default for the missing indirect object of ENTER
          *   <text> ON <iobj>.
          *
          *   Instead of issuing the prompt that we'd normally issue under
          *   these circumstances, assume that we're totally wrong about the
          *   way we've been interpreting the command: assume that it's not
          *   meant as ENTER <text> ON <iobj> after all, but was actually
          *   meant as GO IN <object>.  So, rephrase the command as such and
          *   start over with the new phrasing.
          */
         throw new ReplacementCommandStringException(
-            'get in ' + action.getLiteral(), gIssuingActor, gActor);
+            'vejdi do ' + action.getLiteral(), gIssuingActor, gActor);
     }
 ;
 
 VerbRule(Consult)
-    'consult' singleDobj : ConsultAction
-    verbPhrase = 'consult/consulting (what)'
+    ('poraď' | 'poradit') 'se' ('s' | 'se') singleDobj : ConsultAction
+    verbPhrase = 'poradit/rad{íš}/poradil{a} (s čím) se'
     askDobjResponseProd = singleNoun
 ;
 
 VerbRule(ConsultAbout)
-    'consult' singleDobj ('on' | 'about') singleTopic
-    | 'search' singleDobj 'for' singleTopic
-    | (('look' | 'l') ('up' | 'for')
-       | 'find'
-       | 'search' 'for'
-       | 'read' 'about')
-         singleTopic 'in' singleDobj
-    | ('look' | 'l') singleTopic 'up' 'in' singleDobj
+    ('poraď' | 'poradit') 'se' ('s' | 'se') singleDobj 'o' singleTopic
+    | ('najdi' | 'najít' | 'hledej' | 'hledat' | 'vyhledej' | 'vyhledat') singleTopic ('na' | 'v') singleDobj
     : ConsultAboutAction
-    verbPhrase = 'consult/consulting (what) (about what)'
+    verbPhrase = 'poradit/rad{íš}/poradil{a} (s čím) (o čem) se'
     omitIobjInDobjQuery = true
     askDobjResponseProd = singleNoun
 ;
 
 VerbRule(ConsultWhatAbout)
-    (('look' | 'l') ('up' | 'for')
-     | 'find'
-     | 'search' 'for'
-     | 'read' 'about')
-    singleTopic
-    | ('look' | 'l') singleTopic 'up'
+    ('najdi' | 'najít' | 'hledej' | 'hledat' | 'vyhledej' | 'vyhledat'
+    | ('přečti' | 'přečíst') 'si' 'o') singleTopic
     : ConsultAboutAction
-    verbPhrase = 'look/looking up (what) (in what)'
+    verbPhrase = 'hledat/hled{áš}/hledal{a} (co) (v čem)'
     whichMessageTopic = DirectObject
     construct()
     {
         /* set up the empty direct object phrase */
         dobjMatch = new EmptyNounPhraseProd();
         dobjMatch.responseProd = inSingleNoun;
     }
 ;
 
 VerbRule(Switch)
-    'switch' dobjList
+    ('přepni' | 'přepnout') dobjList
     : SwitchAction
-    verbPhrase = 'switch/switching (what)'
+    verbPhrase = 'přepnout/přepín{áš}/přepnul{a} (co)'
 ;
 
 VerbRule(Flip)
-    'flip' dobjList
+    ('obrať' | 'obrátit') dobjList
     : FlipAction
-    verbPhrase = 'flip/flipping (what)'
+    verbPhrase = 'obrátit/obrac{íš}/obrátil{a} (co)'
 ;
 
 VerbRule(TurnOn)
-    ('activate' | ('turn' | 'switch') 'on') dobjList
-    | ('turn' | 'switch') dobjList 'on'
+    ('zapni' | 'zapnout' | 'zap' | 'aktivuj' | 'aktivovat') dobjList
     : TurnOnAction
-    verbPhrase = 'turn/turning on (what)'
+    verbPhrase = 'zapnout/zapín{áš}/zapnul{a} (co)'
 ;
 
 VerbRule(TurnOff)
-    ('deactivate' | ('turn' | 'switch') 'off') dobjList
-    | ('turn' | 'switch') dobjList 'off'
+    ('vypni' | 'vypnout' | 'vyp' | 'deaktivuj' | 'deaktivovat') dobjList
     : TurnOffAction
-    verbPhrase = 'turn/turning off (what)'
+    verbPhrase = 'vypnout/vypín{áš}/vypnul{a} (co)'
 ;
 
 VerbRule(Light)
-    'light' dobjList
+    ('rozsviť' | 'rozsvítit') dobjList
     : LightAction
-    verbPhrase = 'light/lighting (what)'
+    verbPhrase = 'rozsvítit/rozsvěc{íš}/rozsvítil{a} (co)'
 ;
 
 DefineTAction(Strike);
 VerbRule(Strike)
-    'strike' dobjList
+    ('škrtni' | 'škrtnout') dobjList
     : StrikeAction
-    verbPhrase = 'strike/striking (what)'
+    verbPhrase = 'škrtnout/škrt{áš}/škrtnul{a} (čím)'
 ;
 
 VerbRule(Burn)
-    ('burn' | 'ignite' | 'set' 'fire' 'to') dobjList
+    ('zapal' | 'zapálit') dobjList
     : BurnAction
-    verbPhrase = 'light/lighting (what)'
+    verbPhrase = 'zapálit/zapalu{ješ}/zapálil{a} (co)'
 ;
 
+/* TODO: rozdělit na prepositional phrasing a nonprep. phrasing */
 VerbRule(BurnWith)
-    ('light' | 'burn' | 'ignite' | 'set' 'fire' 'to') singleDobj
-        'with' singleIobj
+    ('zapal' | 'zapálit') singleDobj singleIobj
+    | ('zapal' | 'zapálit') singleIobj singleDobj
     : BurnWithAction
-    verbPhrase = 'light/lighting (what) (with what)'
+    verbPhrase = 'zapálit/zapalu{ješ}/zapálil{a} (co) (čím)'
     omitIobjInDobjQuery = true
     askDobjResponseProd = singleNoun
     askIobjResponseProd = withSingleNoun
 ;
 
 VerbRule(Extinguish)
-    ('extinguish' | 'douse' | 'put' 'out' | 'blow' 'out') dobjList
-    | ('blow' | 'put') dobjList 'out'
+    ('uhas' | 'uhasit' | 'sfoukni' | 'sfouknout' | 'zhasni' | 'zhasnout') dobjList
     : ExtinguishAction
-    verbPhrase = 'extinguish/extinguishing (what)'
+    verbPhrase = 'uhasit/has{íš}/uhasil{a} (co)'
 ;
 
 VerbRule(Break)
-    ('break' | 'ruin' | 'destroy' | 'wreck') dobjList
+    ('rozbij' | 'rozbít' | 'znič' | 'zničit' | 'vyraž' | 'vyrazit' | 'rozkopni'
+    | 'rozkopnout') dobjList
     : BreakAction
-    verbPhrase = 'break/breaking (what)'
+    verbPhrase = 'rozbít/rozbíj{íš}/rozbil{a} (co)'
 ;
 
 VerbRule(CutWithWhat)
-    [badness 500] 'cut' singleDobj
+    [badness 500] ('uřízni' | 'uříznout' | 'přeřízni' | 'přeříznout') singleDobj
     : CutWithAction
-    verbPhrase = 'cut/cutting (what) (with what)'
+    verbPhrase = 'uříznout/řež{eš}/uřízl{a} (co) (čím)'
     construct()
     {
         /* set up the empty indirect object phrase */
         iobjMatch = new EmptyNounPhraseProd();
         iobjMatch.responseProd = withSingleNoun;
     }
 ;
 
+/* TODO: rozdělit na prepositional phrasing a nonprep. phrasing */
 VerbRule(CutWith)
-    'cut' singleDobj 'with' singleIobj
+    ('uřízni' | 'uříznout') singleDobj singleIobj
+    | ('uřízni' | 'uříznout') singleIobj singleDobj
     : CutWithAction
-    verbPhrase = 'cut/cutting (what) (with what)'
+    verbPhrase = 'uříznout/řež{eš}/uřízl{a} (co) (čím)'
     askDobjResponseProd = singleNoun
     askIobjResponseProd = withSingleNoun
 ;
 
 VerbRule(Eat)
-    ('eat' | 'consume') dobjList
+    ('sněz' | 'sníst' | 'jez' | 'jíst') dobjList
     : EatAction
-    verbPhrase = 'eat/eating (what)'
+    verbPhrase = 'snízt/j{íš}/snědl{a} (co)'
 ;
 
 VerbRule(Drink)
-    ('drink' | 'quaff' | 'imbibe') dobjList
+    ('pij' | 'pít' | 'vypij' | 'vypít' | ('napij' | 'napít') 'se') dobjList
     : DrinkAction
-    verbPhrase = 'drink/drinking (what)'
+    verbPhrase = 'vypít/pi{ješ}/vypil{a} (co)'
 ;
 
 VerbRule(Pour)
-    'pour' dobjList
+    ('rozlij' | 'rozlít' | 'vylij' | 'vylít') dobjList
     : PourAction
-    verbPhrase = 'pour/pouring (what)'
+    verbPhrase = 'lít/li{ješ}/lil{a} (co)'
 ;
 
 VerbRule(PourInto)
-    'pour' dobjList ('in' | 'into' | 'in' 'to') singleIobj
+    ('nalij' | 'nalít') dobjList 'do' singleIobj
     : PourIntoAction
-    verbPhrase = 'pour/pouring (what) (into what)'
+    verbPhrase = 'nalít/nalév{áš}/nalil{a} (co) (do čeho)'
     askIobjResponseProd = inSingleNoun
 ;
 
 VerbRule(PourOnto)
-    'pour' dobjList ('on' | 'onto' | 'on' 'to') singleIobj
+    ('rozlij' | 'rozlít' | 'vylij' | 'vylít') dobjList ('na' | 'po') singleIobj
     : PourOntoAction
-    verbPhrase = 'pour/pouring (what) (onto what)'
+    verbPhrase = 'rozlít/rozlév{áš}/rozlil{a} (co) (na co)'
     askIobjResponseProd = onSingleNoun
 ;
 
 VerbRule(Climb)
-    'climb' singleDobj
+    ('šplhej' | 'šplhat' | 'lez' | 'lézt') ('na' | 'po') singleDobj
     : ClimbAction
-    verbPhrase = 'climb/climbing (what)'
+    verbPhrase = 'šplhat/šplh{áš}/šplhal{a} (po čem)'
     askDobjResponseProd = singleNoun
 ;
 
 VerbRule(ClimbUp)
-    ('climb' | 'go' | 'walk') 'up' singleDobj
+    ('vyšplhej' | 'vyšplhat' | 'vylez' | 'vylézt' | 'vystoupej' | 'vystoupat'
+    | 'vystup' | 'vystoupit') ('na' | 'po') singleDobj
     : ClimbUpAction
-    verbPhrase = 'climb/climbing (up what)'
+    verbPhrase = 'vyšplhat/šplh{áš}/vyšplhal{a} (na co)'
     askDobjResponseProd = singleNoun
 ;
 
 VerbRule(ClimbUpWhat)
-    [badness 200] ('climb' | 'go' | 'walk') 'up'
+    [badness 200] 'vyšplhej' | 'vyšplhat' | 'vylez' | 'vylézt' | 'vystoupej'
+    | 'vystoupat'
     : ClimbUpAction
-    verbPhrase = 'climb/climbing (up what)'
+    verbPhrase = 'vyšplhat/šplh{áš}/vyšplhal{a} (na co)'
     askDobjResponseProd = singleNoun
     construct()
     {
         dobjMatch = new EmptyNounPhraseProd();
         dobjMatch.responseProd = onSingleNoun;
     }
 ;
 
 VerbRule(ClimbDown)
-    ('climb' | 'go' | 'walk') 'down' singleDobj
+    ('sešplhej' | 'sešplhat' | 'sestoupej' | 'sestoupat' | 'sestup'
+    | 'sestoupit') ('z' | 'ze' | 'po') singleDobj
     : ClimbDownAction
-    verbPhrase = 'climb/climbing (down what)'
+    verbPhrase = 'sešplhat/sešplháv{áš}/sešplhal{a} (z čeho)'
     askDobjResponseProd = singleNoun
 ;
 
 VerbRule(ClimbDownWhat)
-    [badness 200] ('climb' | 'go' | 'walk') 'down'
+    [badness 200] 'sešplhej' | 'sešplhat' | 'sestoupej' | 'sestoupat' | 'sestup'
+    | 'sestoupit'
     : ClimbDownAction
-    verbPhrase = 'climb/climbing (down what)'
+    verbPhrase = 'sešplhat/sešplháv{áš}/sešplhal{a} (z čeho)'
     askDobjResponseProd = singleNoun
     construct()
     {
         dobjMatch = new EmptyNounPhraseProd();
         dobjMatch.responseProd = onSingleNoun;
     }
 ;
 
 VerbRule(Clean)
-    'clean' dobjList
+    ('vyčisti' | 'vyčistit') dobjList
     : CleanAction
-    verbPhrase = 'clean/cleaning (what)'
+    verbPhrase = 'vyčistit/čist{íš}/vyčistil{a} (co)'
 ;
 
+/* TODO: rozdělit na prepositional phrasing a nonprep. phrasing */
 VerbRule(CleanWith)
-    'clean' dobjList 'with' singleIobj
+    ('vyčisti' | 'vyčistit') dobjList singleIobj
+    | ('vyčisti' | 'vyčistit') singleIobj dobjList
     : CleanWithAction
-    verbPhrase = 'clean/cleaning (what) (with what)'
+    verbPhrase = 'vyčistit/čist{íš}/vyčistil{a} (co) (čím)'
     askIobjResponseProd = withSingleNoun
     omitIobjInDobjQuery = true
 ;
 
 VerbRule(AttachTo)
-    ('attach' | 'connect') dobjList 'to' singleIobj
+    ('připevni' | 'připevnit' | 'přidělej' | 'přidělat') dobjList ('k' | 'ke') singleIobj
     : AttachToAction
     askIobjResponseProd = toSingleNoun
-    verbPhrase = 'attach/attaching (what) (to what)'
+    verbPhrase = 'připevnit/připevňu{ješ}/připevnil{a} (co) (k čemu)'
 ;
 
 VerbRule(AttachToWhat)
-    [badness 500] ('attach' | 'connect') dobjList
+    [badness 500] ('připevni' | 'připevnit' | 'přidělej' | 'přidělat') dobjList
     : AttachToAction
-    verbPhrase = 'attach/attaching (what) (to what)'
+    verbPhrase = 'připevnit/připevňu{ješ}/připevnil{a} (co) (k čemu)'
     construct()
     {
         /* set up the empty indirect object phrase */
         iobjMatch = new EmptyNounPhraseProd();
         iobjMatch.responseProd = toSingleNoun;
     }
 ;
 
 VerbRule(DetachFrom)
-    ('detach' | 'disconnect') dobjList 'from' singleIobj
+    ('oddělej' | 'oddělat' | 'uvolni' | 'uvolnit') dobjList
+    ('od' | 'z' | 'ze') singleIobj
     : DetachFromAction
-    verbPhrase = 'detach/detaching (what) (from what)'
+    verbPhrase
+    {
+        if(dobjCur_.ofKind(PlugAttachable) && iobjCur_.ofKind(PlugAttachable))
+            return 'odpojit/odpoju{ješ}/odpojil{a} (co) (od čeho)';
+        else
+    	    return 'uvolnit/uvolňu{ješ}/uvolnil{a} (co) (od čeho)';
+    }
     askIobjResponseProd = fromSingleNoun
 ;
 
 VerbRule(Detach)
-    ('detach' | 'disconnect') dobjList
+    ('oddělej' | 'oddělat' | 'uvolni' | 'uvolnit') dobjList
     : DetachAction
-    verbPhrase = 'detach/detaching (what)'
+    verbPhrase = 'uvolnit/uvolňu{ješ}/uvolnil{a} (co)'
 ;
 
 VerbRule(Open)
-    'open' dobjList
+    ('otevři' | 'otevřít' | 'ote') dobjList
     : OpenAction
-    verbPhrase = 'open/opening (what)'
+    verbPhrase = 'otevřít/otevír{áš}/otevřel{a} (co)'
 ;
 
 VerbRule(Close)
-    ('close' | 'shut') dobjList
+    ('zavři' | 'zavřít' | 'zav') dobjList
     : CloseAction
-    verbPhrase = 'close/closing (what)'
+    verbPhrase = 'zavřít/zavír{áš}/zavřel{a} (co)'
 ;
 
 VerbRule(Lock)
-    'lock' dobjList
+    ('zamkni' | 'zamknout' | 'zam') dobjList
     : LockAction
-    verbPhrase = 'lock/locking (what)'
+    verbPhrase = 'zamknout/zamyk{áš}/zamkl{a} (co)'
 ;
 
 VerbRule(Unlock)
-    'unlock' dobjList
+    ('odemkni' | 'odemknout' | 'ode') dobjList
     : UnlockAction
-    verbPhrase = 'unlock/unlocking (what)'
+    verbPhrase = 'odemknout/odemyk{áš}/odemkl{a} (co)'
 ;
 
+/* TODO: rozdělit na prepositional phrasing a nonprep. phrasing */
 VerbRule(LockWith)
-    'lock' singleDobj 'with' singleIobj
+    ('zamkni' | 'zamknout' | 'zam') singleDobj singleIobj
+    | ('zamkni' | 'zamknout' | 'zam') singleIobj singleDobj
     : LockWithAction
-    verbPhrase = 'lock/locking (what) (with what)'
+    verbPhrase = 'zamknout/zamyk{áš}/zamkl{a} (co) (čím)'
     omitIobjInDobjQuery = true
     askDobjResponseProd = singleNoun
     askIobjResponseProd = withSingleNoun
 ;
 
+/* TODO: rozdělit na prepositional phrasing a nonprep. phrasing */
 VerbRule(UnlockWith)
-    'unlock' singleDobj 'with' singleIobj
+    ('odemkni' | 'odemknout' | 'ode') singleDobj singleIobj
+    | ('odemkni' | 'odemknout' | 'ode') singleIobj singleDobj
     : UnlockWithAction
-    verbPhrase = 'unlock/unlocking (what) (with what)'
+    verbPhrase = 'odemknout/odemyk{áš}/odemkl{a} (co) (čím)'
     omitIobjInDobjQuery = true
     askDobjResponseProd = singleNoun
     askIobjResponseProd = withSingleNoun
 ;
 
 VerbRule(SitOn)
-    'sit' ('on' | 'in' | 'down' 'on' | 'down' 'in')
-        singleDobj
+    ('sedni' | 'sednout') ( | 'si') ('na' | 'do') singleDobj
     : SitOnAction
-    verbPhrase = 'sit/sitting (on what)'
+    verbPhrase = 'sednout/sed{áš}/sedl{a} (na co) si'
     askDobjResponseProd = singleNoun
 
-    /* use the actorInPrep, if there's a direct object available */
+    /* use the objInPrep, if there's a direct object available */
     adjustDefaultObjectPrep(prep, obj)
-        { return (obj != nil ? obj.actorInPrep + ' ' : prep); }
+        { return (obj != nil ? obj.objInPrep + ' ' : prep); }
 ;
 
 VerbRule(Sit)
-    'sit' ( | 'down') : SitAction
-    verbPhrase = 'sit/sitting down'
+    ('sedni' | 'sednout') ( | 'si') : SitAction
+    verbPhrase = 'sednout/sed{áš}/sedl{a} si'
 ;
 
 VerbRule(LieOn)
-    'lie' ('on' | 'in' | 'down' 'on' | 'down' 'in')
-        singleDobj
+    ('lehni' | 'lehnout') ('si' | ) 'na' singleDobj
+    : LieOnAction
+    verbPhrase = 'lehnout/leh{áš}/lehl{a} (na co) si'
+    askDobjResponseProd = singleNoun
+
+    /* use the objInPrep, if there's a direct object available */
+    adjustDefaultObjectPrep(prep, obj)
+        { return (obj != nil ? obj.objInPrep + ' ' : prep); }
+;
+
+VerbRule(LieOnType2)
+    ('lehni' | 'lehnout') ('si' | ) 'do' singleDobj
     : LieOnAction
-    verbPhrase = 'lie/lying (on what)'
+    verbPhrase = 'lehnout/leh{áš}/lehl{a} (do čeho) si'
     askDobjResponseProd = singleNoun
 
-    /* use the actorInPrep, if there's a direct object available */
+    /* use the objInPrep, if there's a direct object available */
     adjustDefaultObjectPrep(prep, obj)
-        { return (obj != nil ? obj.actorInPrep + ' ' : prep); }
+        { return (obj != nil ? obj.objInPrep + ' ' : prep); }
 ;
 
 VerbRule(Lie)
-    'lie' ( | 'down') : LieAction
-    verbPhrase = 'lie/lying down'
+    ('lehni' | 'lehnout') ('si' | ) : LieAction
+    verbPhrase = 'lehnout/leh{áš}/lehl{a} si'
 ;
 
 VerbRule(StandOn)
-    ('stand' ('on' | 'in' | 'onto' | 'on' 'to' | 'into' | 'in' 'to')
-     | 'climb' ('on' | 'onto' | 'on' 'to'))
-    singleDobj
+    ('stoupni' | 'stoupnout') ('si' | ) ('na' | 'do') singleDobj
     : StandOnAction
-    verbPhrase = 'stand/standing (on what)'
+    verbPhrase = 'stoupnout/stoup{áš}/stoupl{a} (na co) si'
     askDobjResponseProd = singleNoun
 
-    /* use the actorInPrep, if there's a direct object available */
+    /* use the objInPrep, if there's a direct object available */
     adjustDefaultObjectPrep(prep, obj)
-        { return (obj != nil ? obj.actorInPrep + ' ' : prep); }
+        { return (obj != nil ? obj.objInPrep + ' ' : prep); }
 ;
 
 VerbRule(Stand)
-    'stand' | 'stand' 'up' | 'get' 'up'
+    'vstaň' | 'vstát' | 'stůj' | 'stát' | ('stoupni' | 'stoupnout') ('si' | )
+    | ('postav' | 'postavit') ('se' | )
     : StandAction
-    verbPhrase = 'stand/standing up'
+    verbPhrase = 'vstát/vstáv{áš}/vstal{a}'
 ;
 
 VerbRule(GetOutOf)
-    ('out' 'of' | 'get' 'out' 'of' | 'climb' 'out' 'of' | 'leave' | 'exit')
-    singleDobj
+    ('opusť' | 'opustit') singleDobj
     : GetOutOfAction
-    verbPhrase = 'get/getting (out of what)'
+    verbPhrase = 'dostat/dostáv{áš}/dostal{a} ven (z čeho) se'
     askDobjResponseProd = singleNoun
 
-    /* use the actorOutOfPrep, if there's a direct object available */
+    /* use the objOutOfPrep, if there's a direct object available */
+    /*
+     * Tohle se podílí na větě ">ven (z dřevěného prkna)
+     */
     adjustDefaultObjectPrep(prep, obj)
-        { return (obj != nil ? obj.actorOutOfPrep + ' ' : prep); }
+        { return (obj != nil ? obj.objOutOfPrep + ' ' : prep); }
 ;
 
 VerbRule(GetOffOf)
-    'get' ('off' | 'off' 'of' | 'down' 'from') singleDobj
+    ('slez' | 'slézt' | 'pryč' 'z') singleDobj
     : GetOffOfAction
-    verbPhrase = 'get/getting (off of what)'
+    verbPhrase = 'dostat/dostáv{áš}/dostal{a} pryč (z čeho) se'
     askDobjResponseProd = singleNoun
 
-    /* use the actorOutOfPrep, if there's a direct object available */
+    /* use the objOutOfPrep, if there's a direct object available */
     adjustDefaultObjectPrep(prep, obj)
-        { return (obj != nil ? obj.actorOutOfPrep + ' ' : prep); }
+        { return (obj != nil ? obj.objOutOfPrep + ' ' : prep); }
 ;
 
 VerbRule(GetOut)
-    'get' 'out'
-    | 'get' 'off'
-    | 'get' 'down'
-    | 'disembark'
-    | 'climb' 'out'
+    ('vystup' | 'vystoupit' | 'vys') ( | 'ven')
     : GetOutAction
-    verbPhrase = 'get/getting out'
+    verbPhrase = 'dostat/dostáv{áš}/dostal{a} ven'
 ;
 
+/*
+ *   "askDobjResponseProd = doNaSingleNoun" říká, že na otázku "Do čeho chceš
+ *   nastoupit?" mohu odpovědět s předložkou, např. "do loďky", ale i "na
+ *   palubu". Ale proč to nefunguje?
+ */
 VerbRule(Board)
-    ('board'
-     | ('get' ('in' | 'into' | 'in' 'to' | 'on' | 'onto' | 'on' 'to'))
-     | ('climb' ('in' | 'into' | 'in' 'to')))
-    singleDobj
+    ('nastup' | 'nastoupit' | 'nas') ('na' | 'do' | ) singleDobj
     : BoardAction
-    verbPhrase = 'get/getting (in what)'
-    askDobjResponseProd = singleNoun
+    verbPhrase = 'nastoupit/nastupu{ješ}/nastoupil{a} (do čeho)'
+    askDobjResponseProd = toSingleNoun
 ;
 
 VerbRule(Sleep)
-    'sleep'
+    'spi' | 'spát'
     : SleepAction
-    verbPhrase = 'sleep/sleeping'
+    verbPhrase = 'spát/sp{íš}/spal{a}'
 ;
 
 VerbRule(Fasten)
-    ('fasten' | 'buckle' | 'buckle' 'up') dobjList
+    ('připoutej' | 'připoutat') dobjList
     : FastenAction
-    verbPhrase = 'fasten/fastening (what)'
+    verbPhrase = 'připoutat/připoutáv{áš}/připoutal{a} (co)'
 ;
 
 VerbRule(FastenTo)
-    ('fasten' | 'buckle') dobjList 'to' singleIobj
+    ('připoutej' | 'připoutat') dobjList ('k' | 'ke') singleIobj
     : FastenToAction
-    verbPhrase = 'fasten/fastening (what) (to what)'
+    verbPhrase = 'připoutat/připoutáv{áš}/připoutal{a} (co) (k čemu)'
     askIobjResponseProd = toSingleNoun
 ;
 
 VerbRule(Unfasten)
-    ('unfasten' | 'unbuckle') dobjList
+    ('odpoutej' | 'odpoutat') dobjList
     : UnfastenAction
-    verbPhrase = 'unfasten/unfastening (what)'
+    verbPhrase = 'odpoutat/odpoutáv{áš}/odpoutal{a} (co)'
 ;
 
 VerbRule(UnfastenFrom)
-    ('unfasten' | 'unbuckle') dobjList 'from' singleIobj
+    ('odpoutej' | 'odpoutat') dobjList ('od' | 'z' | 'ze') singleIobj
     : UnfastenFromAction
-    verbPhrase = 'unfasten/unfastening (what) (from what)'
+    verbPhrase = 'odpoutat/odpoutáv{áš}/odpoutal{a} (co) (od čeho)'
     askIobjResponseProd = fromSingleNoun
 ;
 
 VerbRule(PlugInto)
-    'plug' dobjList ('in' | 'into' | 'in' 'to') singleIobj
+    ('připoj' | 'připojit' | 'zapoj' | 'zapojit') dobjList ('do' | 'k' | 'ke') singleIobj
     : PlugIntoAction
-    verbPhrase = 'plug/plugging (what) (into what)'
+    verbPhrase = 'připojit/připoju{ješ}/připojil{a} (co) (k čemu)'
     askIobjResponseProd = inSingleNoun
 ;
 
 VerbRule(PlugIntoWhat)
-    [badness 500] 'plug' dobjList
+    [badness 500] ('připoj' | 'připojit' | 'zapoj' | 'zapojit') dobjList
     : PlugIntoAction
-    verbPhrase = 'plug/plugging (what) (into what)'
+    verbPhrase = 'připojit/připoju{ješ}/připojil{a} (co) (k čemu)'
     construct()
     {
         /* set up the empty indirect object phrase */
         iobjMatch = new EmptyNounPhraseProd();
         iobjMatch.responseProd = inSingleNoun;
     }
 ;
 
 VerbRule(PlugIn)
-    'plug' dobjList 'in'
-    | 'plug' 'in' dobjList
+    ('zapoj' | 'zapojit') dobjList
     : PlugInAction
-    verbPhrase = 'plug/plugging (what)'
+    verbPhrase = 'zapojit/zapoju{ješ}/zapojil{a} (co)'
 ;
 
 VerbRule(UnplugFrom)
-    'unplug' dobjList 'from' singleIobj
+    ('odpoj' | 'odpojit' | 'vypoj' | 'vypojit') dobjList ('z' | 'ze' | 'od') singleIobj
     : UnplugFromAction
-    verbPhrase = 'unplug/unplugging (what) (from what)'
+    verbPhrase = 'odpojit/odpoju{ješ}/odpojil{a} (co) (z čeho)'
     askIobjResponseProd = fromSingleNoun
 ;
 
 VerbRule(Unplug)
-    'unplug' dobjList
+    ('odpoj' | 'odpojit' | 'vypoj' | 'vypojit') dobjList
     : UnplugAction
-    verbPhrase = 'unplug/unplugging (what)'
+    verbPhrase = 'odpojit/odpoju{ješ}/odpojil{a} (co)'
 ;
 
 VerbRule(Screw)
-    'screw' dobjList
+    ('zašroubuj' | 'zašroubovat') dobjList
     : ScrewAction
-    verbPhrase = 'screw/screwing (what)'
+    verbPhrase = 'přišroubovat/přišroubováv{áš}/přišrouboval{a} (co)'
 ;
 
+/* TODO: rozdělit na prepositional phrasing a nonprep. phrasing */
 VerbRule(ScrewWith)
-    'screw' dobjList 'with' singleIobj
+    ('zašroubuj' | 'zašroubovat') dobjList singleIobj
+    | ('zašroubuj' | 'zašroubovat') singleIobj dobjList
     : ScrewWithAction
-    verbPhrase = 'screw/screwing (what) (with what)'
+    verbPhrase = 'přišroubovat/přišroubováv{áš}/přišrouboval{a} (co) (čím)'
     omitIobjInDobjQuery = true
     askIobjResponseProd = withSingleNoun
 ;
 
 VerbRule(Unscrew)
-    'unscrew' dobjList
+    ('odšroubuj' | 'odšroubovat') dobjList
     : UnscrewAction
-    verbPhrase = 'unscrew/unscrewing (what)'
+    verbPhrase = 'odšroubovat/odšroubováv{áš}/odšrouboval{a} (co)'
 ;
 
+/* TODO: rozdělit na prepositional phrasing a nonprep. phrasing */
 VerbRule(UnscrewWith)
-    'unscrew' dobjList 'with' singleIobj
+    ('odšroubuj' | 'odšroubovat') dobjList singleIobj
+    | ('odšroubuj' | 'odšroubovat') singleIobj dobjList
     : UnscrewWithAction
-    verbPhrase = 'unscrew/unscrewing (what) (with what)'
+    verbPhrase = 'odšroubovat/odšroubováv{áš}/odšrouboval{a} (co) (čím)'
     omitIobjInDobjQuery = true
     askIobjResponseProd = withSingleNoun
 ;
 
 VerbRule(PushTravelDir)
-    ('push' | 'pull' | 'drag' | 'move') singleDobj singleDir
+    ('tlač' | 'tlačit' | 'odtlač' | 'odtlačit' | 'vytlač' | 'vytlačit' |
+    'strkej' | 'strkat' | 'vystrkej' | 'vystrkat') singleDobj
+    ( | 'na') singleDir
     : PushTravelDirAction
-    verbPhrase = ('push/pushing (what) ' + dirMatch.dir.name)
+    verbPhrase = ('tlačit/tlač{íš}/tlačil{a} (co) ' + dirMatch.dir.name)
 ;
 
 VerbRule(PushTravelThrough)
-    ('push' | 'pull' | 'drag' | 'move') singleDobj
-    ('through' | 'thru') singleIobj
+    ('tlač' | 'tlačit' | 'odtlač' | 'odtlačit') singleDobj
+    'skrz' singleIobj
     : PushTravelThroughAction
-    verbPhrase = 'push/pushing (what) (through what)'
+    verbPhrase = 'tlačit/tlač{íš}/tlačil{a} (co) (skrz co)'
 ;
 
 VerbRule(PushTravelEnter)
-    ('push' | 'pull' | 'drag' | 'move') singleDobj
-    ('in' | 'into' | 'in' 'to') singleIobj
+    ('tlač' | 'tlačit' | 'odtlač' | 'odtlačit') singleDobj
+    'do' singleIobj
     : PushTravelEnterAction
-    verbPhrase = 'push/pushing (what) (into what)'
+    verbPhrase = 'tlačit/tlač{íš}/tlačil{a} (co) (do čeho)'
 ;
 
 VerbRule(PushTravelGetOutOf)
-    ('push' | 'pull' | 'drag' | 'move') singleDobj
-    'out' ('of' | ) singleIobj
+    ('tlač' | 'tlačit' | 'odtlač' | 'odtlačit' | 'vytlač' | 'vytlačit')
+    singleDobj ('ven' | ) 'z' singleIobj
     : PushTravelGetOutOfAction
-    verbPhrase = 'push/pushing (what) (out of what)'
+    verbPhrase = 'tlačit/tlač{íš}/tlačil{a} (co) (ven z čeho)'
 ;
 
-
+/* TODO: Tyhle dvě jsou nějaké divné, nedovedu si představit využití. Mozna na schodech, ktere reaguji na climb? */
 VerbRule(PushTravelClimbUp)
-    ('push' | 'pull' | 'drag' | 'move') singleDobj
-    'up' singleIobj
+    ('tlač' | 'tlačit' | 'odtlač' | 'odtlačit') singleDobj
+    'na' singleIobj
     : PushTravelClimbUpAction
-    verbPhrase = 'push/pushing (what) (up what)'
+    verbPhrase = 'tlačit/tlač{íš}/tlačil{a} (co) (na co)'
     omitIobjInDobjQuery = true
 ;
 
 VerbRule(PushTravelClimbDown)
-    ('push' | 'pull' | 'drag' | 'move') singleDobj
-    'down' singleIobj
+    ('tlač' | 'tlačit' | 'odtlač' | 'odtlačit') singleDobj
+    'pod' singleIobj
     : PushTravelClimbDownAction
-    verbPhrase = 'push/pushing (what) (down what)'
+    verbPhrase = 'tlačit/tlač{íš}/tlačil{a} (co) (pod co)'
 ;
 
 VerbRule(Exits)
-    'exits'
+    ('ukaž' | 'ukázat') ('mi' | ) ('směry' | 'východy' | 'cesty')
     : ExitsAction
-    verbPhrase = 'exits/showing exits'
+    verbPhrase = 'ukázat/ukazu{ješ}/ukázal{a} směry'
 ;
 
 VerbRule(ExitsMode)
-    'exits' ('on'->on_ | 'all'->on_
-             | 'off'->off_ | 'none'->off_
-             | ('status' ('line' | ) | 'statusline') 'look'->on_
-             | 'look'->on_ ('status' ('line' | ) | 'statusline')
-             | 'status'->stat_ ('line' | ) | 'statusline'->stat_
-             | 'look'->look_)
+    ('zapnout'->on_ | 'všechny'->on_ | 'vypnout'->off_ | 'žádné'->off_ ) 'směry'
+    | 'směry' 'v' ('záhlaví'->stat_ | 'popisu'->look_)
     : ExitsModeAction
-    verbPhrase = 'turn/turning off exits display'
+    verbPhrase = 'vypnout/vypín{áš}/vypnul{a} zobrazení směrů'
 ;
 
 VerbRule(HintsOff)
-    'hints' 'off'
+    ('vypni' | 'vypnout' | 'vyp') ('nápovědy' | 'náp')
     : HintsOffAction
-    verbPhrase = 'disable/disabling hints'
+    verbPhrase = 'vypnout/vypín{áš}/vypnul{a} nápovědy'
 ;
 
 VerbRule(Hint)
-    'hint' | 'hints'
+    ('ukaž' | 'ukázat' | ) ('nápověda' | 'nápovědy' | 'náp')
     : HintAction
-    verbPhrase = 'show/showing hints'
+    verbPhrase = 'ukázat/ukazu{ješ}/ukázal{a} nápovědy'
 ;
 
 VerbRule(Oops)
-    ('oops' | 'o') singleLiteral
+    ('oprava' | 'opr' | 'o') singleLiteral
     : OopsAction
-    verbPhrase = 'oops/correcting (what)'
+    verbPhrase = 'opravit/opravu{ješ}/opravil{a} (co)'
 ;
 
 VerbRule(OopsOnly)
-    ('oops' | 'o')
+    ('oprava' | 'opr' | 'o')
     : OopsIAction
-    verbPhrase = 'oops/correcting'
+    verbPhrase = 'opravit/opravu{ješ}/opravil{a}'
 ;
 
 /* ------------------------------------------------------------------------ */
 /*
  *   "debug" verb - special verb to break into the debugger.  We'll only
  *   compile this into the game if we're compiling a debug version to begin
  *   with, since a non-debug version can't be run under the debugger.  
  */
 #ifdef __DEBUG
 
 VerbRule(Debug)
-    'debug'
+    'debuguj' | 'debugovat' | 'debug'
     : DebugAction
-    verbPhrase = 'debug/debugging'
+    verbPhrase = 'debugovat/debugu{ješ}/debugoval{a}'
 ;
 
 #endif /* __DEBUG */