diff --git a/Packets/ParseVariant.hh b/Packets/ParseVariant.hh
index 9deb622679e990f0dda5ba6c37afb81957bf0185..0c33791864bb1c10f88ea6dbe4bf270e565c89f0 100644
--- a/Packets/ParseVariant.hh
+++ b/Packets/ParseVariant.hh
@@ -151,10 +151,11 @@ namespace senf {
         \see senf::Parser_Variant
         \ingroup parsecollection
      */
-    template <class ChooserType, unsigned Distance, SENF_PARSE_VARIANT_TPL_ARGS_DFL(class P)>
+    template <class ChooserType, unsigned Distance, class Translator,
+              SENF_PARSE_VARIANT_TPL_ARGS_DFL(class P)>
     struct Parse_Variant_Direct
     {
-        typedef Parse_Variant< detail::Parse_Variant_Direct<ChooserType, Distance>,
+        typedef Parse_Variant< detail::Parse_Variant_Direct<ChooserType, Distance, Translator>,
                                SENF_PARSE_VARIANT_TPL_ARGS(P) > parser;
     };
 
@@ -210,8 +211,12 @@ namespace senf {
         \hideinitializer
         \ingroup packetparsermacros
      */
-#   define SENF_PARSER_VARIANT(name, chooser, types) \
-        SENF_PARSER_VARIANT_I(SENF_PARSER_FIELD, name, chooser, types)
+#   define SENF_PARSER_VARIANT(name, chooser, types)                                              \
+        SENF_PARSER_VARIANT_I(SENF_PARSER_FIELD,                                                  \
+                              name,                                                               \
+                              chooser,                                                            \
+                              senf::detail::Parse_Variant_IdentityTranslator,                     \
+                              types)
 
     /** \brief Define Parse_Variant_Direct field (private)
         
@@ -219,8 +224,61 @@ namespace senf {
         \hideinitializer
         \ingroup packetparsermacros
      */
-#   define SENF_PARSER_PRIVATE_VARIANT(name, chooser, types) \
-        SENF_PARSER_VARIANT_I(SENF_PARSER_PRIVATE_FIELD, name, chooser, types)
+#   define SENF_PARSER_PRIVATE_VARIANT(name, chooser, types)                                      \
+        SENF_PARSER_VARIANT_I(SENF_PARSER_PRIVATE_FIELD,                                          \
+                              name,                                                               \
+                              chooser,                                                            \
+                              senf::detail::Parse_Variant_IdentityTranslator,                     \
+                              types)
+
+    /** \brief Define Parse_Variant_Direct field with translator
+        
+        This is like \ref SENF_PARSER_VARIANT(), however it allows to specify a \a translator
+        argument which translates between \a chooser values and type indices:
+        \code
+        struct SomeTranslator {
+            static unsigned fromChooser(chooser_field_t::value_type value) {
+                switch (value) {
+                case 1  : return 0 ;
+                case 5  : return 1 ;
+                default : return 2 ;
+                }
+            }
+
+            static chooser_field_t::value_type foChooser(unsigned value) {
+                static chooser_field_t::value_type table[] const = { 1, 5, 0 };
+                return table[value];
+            }
+        };
+        \endcode
+        The \a translator class must have two publicly accessible static members, \c fromChooser and
+        \c toChooser. \c fromChooser takes the value as returned by the \a chooser field and must
+        return the corresponding class index whereas \c toChooser takes the class index and must
+        return the value to write into the \a chooser field.
+
+        \see \ref SENF_PARSER_VARIANT()
+        \hideinitializer
+        \ingroup packetparsermacros
+     */
+#   define SENF_PARSER_VARIANT_TRANS(name, chooser, translator, types)                            \
+        SENF_PARSER_VARIANT_I(SENF_PARSER_FIELD,                                                  \
+                              name,                                                               \
+                              chooser,                                                            \
+                              translator,                                                         \
+                              types)
+
+    /** \brief Define Parse_Variant_Direct field with translator (private)
+        
+        \see \ref SENF_PARSER_VARIANT_TRANS()
+        \hideinitializer
+        \ingroup packetparsermacros
+     */
+#   define SENF_PARSER_PRIVATE_VARIANT_TRANS(name, chooser, types)                                \
+        SENF_PARSER_VARIANT_I(SENF_PARSER_PRIVATE_FIELD,                                          \
+                              name,                                                               \
+                              chooser,                                                            \
+                              translator,                                                         \
+                              types)
 
 }
 
diff --git a/Packets/ParseVariant.ih b/Packets/ParseVariant.ih
index 0e33da0ea092ee9a3d86b68210439a7f69eabfca..11660770f7f4272a81911ba6e5b7795c11f3e8af 100644
--- a/Packets/ParseVariant.ih
+++ b/Packets/ParseVariant.ih
@@ -56,7 +56,7 @@ namespace detail {
 #   endif
     
     /** \brief Internal: Variant Policy used by senf::Parse_Variant_Direct */
-    template <class ChooserType, unsigned Distance>
+    template <class ChooserType, unsigned Distance, class Translator>
     struct Parse_Variant_Direct
     {
         typedef PacketParserBase::data_iterator data_iterator;
@@ -72,20 +72,27 @@ namespace detail {
         }
         
         unsigned variant(data_iterator i, state_type s) const {
-            return chooser(i,s).value();
+            return Translator::fromChooser(chooser(i,s).value());
         }
 
         void variant(unsigned v, data_iterator i, state_type s) {
-            chooser(i,s).value(v);
+            chooser(i,s).value(Translator::toChooser(v));
         }
     };
 
+    /** \brief Internal: Identity chooser translator */
+    struct Parse_Variant_IdentityTranslator {
+        static unsigned fromChooser(unsigned value) { return value; }
+        static unsigned toChooser(unsigned value) { return value; }
+    };
+
 #   define SENF_PARSER_VARIANT_(r, data, elem) ,elem
 
-#   define SENF_PARSER_VARIANT_I(field, name, chooser, types)                                     \
+#   define SENF_PARSER_VARIANT_I(field, name, chooser, translator, types)                         \
         typedef senf::Parse_Variant_Direct<                                                       \
             BOOST_PP_CAT(chooser, _t),                                                            \
-            SENF_PARSER_CURRENT_FIXED_OFFSET() - SENF_PARSER_FIXED_OFFSET(chooser)                \
+            SENF_PARSER_CURRENT_FIXED_OFFSET() - SENF_PARSER_FIXED_OFFSET(chooser),               \
+            translator                                                                            \
             BOOST_PP_SEQ_FOR_EACH( SENF_PARSER_VARIANT_, _, types )                               \
             >::parser BOOST_PP_CAT(name, _variant_t);                                             \
         field( name, BOOST_PP_CAT(name, _variant_t) )
diff --git a/Packets/ParseVariant.test.cc b/Packets/ParseVariant.test.cc
index e795e49a920dd19b87c45367b0486315997abf5a..41935d55f613924be283ff1c78dd845659a89f66 100644
--- a/Packets/ParseVariant.test.cc
+++ b/Packets/ParseVariant.test.cc
@@ -38,7 +38,7 @@
 BOOST_AUTO_UNIT_TEST(parseVariant)
 {
     typedef senf::Parse_Array<10, senf::Parse_UInt8> Array10;
-    typedef senf::Parse_Variant_Direct< senf::Parse_UInt8, 1, 
+    typedef senf::Parse_Variant_Direct< senf::Parse_UInt8, 1, senf::detail::Parse_Variant_IdentityTranslator,
         senf::VoidPacketParser,
         Array10, 
         senf:: Parse_UInt32