diff --git a/casadi-bindings.cabal b/casadi-bindings.cabal
--- a/casadi-bindings.cabal
+++ b/casadi-bindings.cabal
@@ -1,5 +1,5 @@
 name:                casadi-bindings
-version:             2.2.0.4
+version:             2.2.0.5
 synopsis:            mid-level bindings to CasADi
 category:            Numerical, Math
 description:
@@ -61,6 +61,11 @@
                        casadi-bindings-internal == 0.1.2.1,
                        casadi-bindings-core     == 2.2.0.2
   default-language:    Haskell2010
+
+  C-sources:           cbits/handwritten.cpp
+  extra-libraries:     stdc++
+  pkgconfig-depends:   casadi
+  cc-options: -Wall -Wno-sign-compare
 
 source-repository head
   type: git
diff --git a/cbits/handwritten.cpp b/cbits/handwritten.cpp
new file mode 100644
--- /dev/null
+++ b/cbits/handwritten.cpp
@@ -0,0 +1,31 @@
+#include <casadi/casadi.hpp>
+#include <cmath>
+#include <stdexcept>
+#include <iostream>
+
+extern "C"
+casadi::GenericType *
+custom_generic_dictionary(std::string ** err_msg,
+                          std::vector< std::string* >& keys,
+                          std::vector< casadi::GenericType* >& vals);
+
+casadi::GenericType *
+custom_generic_dictionary(std::string ** err_msg,
+                          std::vector< std::string* >& keys,
+                          std::vector< casadi::GenericType* >& vals) {
+    try {
+        const int nk = keys.size();
+        const int nv = vals.size();
+        if (nk != nv) throw "dictionary key/value length mismatch";
+        
+        casadi::Dictionary dict;
+        for (int k = 0; k < nk; k++)
+            dict.insert(std::pair<std::string,casadi::GenericType>(*(keys[k]), *(vals[k])));
+
+        return new casadi::GenericType(dict);
+
+    } catch (std::exception& ex) {
+         *err_msg = new std::string(ex.what());
+         return 0;
+    }
+}
diff --git a/src/Casadi/GenericC.hs b/src/Casadi/GenericC.hs
--- a/src/Casadi/GenericC.hs
+++ b/src/Casadi/GenericC.hs
@@ -1,12 +1,25 @@
 {-# OPTIONS_GHC -Wall -fno-warn-orphans -fno-cse #-}
+{-# Language GADTs #-}
 {-# Language FlexibleInstances #-}
 
 module Casadi.GenericC
        ( GenericC(..)
+       , Opt(..)
        , getDescription
        ) where
 
 import Data.Vector ( Vector )
+import qualified Data.Vector as V
+import Foreign.Marshal ( new, free )
+import Foreign.Storable ( peek )
+import Foreign.Ptr ( Ptr, nullPtr )
+
+import Casadi.Internal.FormatException ( formatException )
+import Casadi.Internal.MarshalTypes ( StdVec, StdString )
+import Casadi.Internal.Marshal ( withMarshal )
+import Casadi.Internal.WrapReturn ( WrapReturn(..) )
+
+import Casadi.Core.Data ( GenericType' )
 import Casadi.Core.Classes.Function ( Function )
 import Casadi.Core.Classes.GenericType
 import Casadi.Core.Classes.DerivativeGenerator ( DerivativeGenerator )
@@ -21,6 +34,9 @@
   mkGeneric :: a -> IO GenericType
   fromGeneric :: GenericType -> IO (Maybe a)
 
+data Opt where
+  Opt :: GenericC a => a -> Opt
+
 getDescription :: GenericType -> IO String
 getDescription = genericType_get_description
 
@@ -57,6 +73,12 @@
 instance GenericC DerivativeGenerator where
   mkGeneric = genericType__1
   fromGeneric = const $ return $ error "no fromGeneric for DerivativeGenerator"
+instance GenericC [(String,Opt)] where
+  mkGeneric kvs = do
+    let (ks,vs') = unzip kvs
+    vs <- mapM (\(Opt x) -> mkGeneric x) vs'
+    mkGenericDictionary (V.fromList ks) (V.fromList vs)
+  fromGeneric = const $ return $ error "no fromGeneric for [(String,Opt)]"
 
 ifThenGet :: (a -> IO Bool) -> (a -> IO b) -> a -> IO (Maybe b)
 ifThenGet isOpt getOpt g = do
@@ -64,3 +86,19 @@
   if isopt
     then fmap Just (getOpt g)
     else return Nothing
+
+-- direct wrapper
+foreign import ccall unsafe "custom_generic_dictionary" c_custom_generic_dictionary
+  :: Ptr (Ptr StdString) -> Ptr (StdVec (Ptr StdString)) -> Ptr (StdVec (Ptr GenericType'))
+     -> IO (Ptr GenericType')
+
+mkGenericDictionary :: Vector String -> Vector GenericType -> IO GenericType
+mkGenericDictionary x0 x1 =
+  withMarshal x0 $ \x0' ->
+  withMarshal x1 $ \x1' ->
+  do
+    errStrPtrP <- new nullPtr
+    ret <- c_custom_generic_dictionary errStrPtrP x0' x1'
+    errStrPtr <- peek errStrPtrP
+    free errStrPtrP
+    if errStrPtr == nullPtr then wrapReturn ret else wrapReturn errStrPtr >>= (error . formatException)
diff --git a/src/Casadi/Option.hs b/src/Casadi/Option.hs
--- a/src/Casadi/Option.hs
+++ b/src/Casadi/Option.hs
@@ -13,9 +13,6 @@
     optionsFunctionality_hasOption, optionsFunctionality_getOption)
 import Casadi.GenericC
 
-data Opt where
-  Opt :: GenericC a => a -> Opt
-
 setOption :: (OptionsFunctionalityClass a, GenericC b) => a -> String -> b -> IO ()
 setOption f name val = do
   gval <- mkGeneric val
