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.3.0.1
+version:             2.4.1.0
 synopsis:            mid-level bindings to CasADi
 category:            Numerical, Math
 description:
@@ -44,16 +44,16 @@
                        Casadi.DMatrix
                        Casadi.Function
                        Casadi.GenericC
-                       Casadi.IOSchemes
+                       Casadi.IOScheme
                        Casadi.MX
                        Casadi.MXFunction
                        Casadi.Option
                        Casadi.Overloading
-                       Casadi.SharedObject
                        Casadi.Slice
                        Casadi.Sparsity
                        Casadi.SX
                        Casadi.SXFunction
+  other-modules:       Casadi.SharedObject
   build-depends:       base >=4.6 && <5,
                        linear,
                        vector,
@@ -61,8 +61,8 @@
                        cereal,
                        binary,
                        vector-binary-instances,
-                       casadi-bindings-internal == 0.1.3.0,
-                       casadi-bindings-core     == 2.3.0.1
+                       casadi-bindings-internal == 0.1.3.1,
+                       casadi-bindings-core     == 2.4.1.0
   default-language:    Haskell2010
 
   C-sources:           cbits/handwritten.cpp
diff --git a/cbits/handwritten.cpp b/cbits/handwritten.cpp
--- a/cbits/handwritten.cpp
+++ b/cbits/handwritten.cpp
@@ -1,31 +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;
-    }
-}
+//#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/CMatrix.hs b/src/Casadi/CMatrix.hs
--- a/src/Casadi/CMatrix.hs
+++ b/src/Casadi/CMatrix.hs
@@ -6,8 +6,10 @@
        ) where
 
 import qualified Data.Vector as V
+import Data.Map ( Map )
 
 import Casadi.Core.Classes.DMatrix ( DMatrix )
+import Casadi.Core.Classes.GenericType ( GenericType )
 
 import Casadi.Overloading ( Fmod, ArcTan2, SymOrd, Erf )
 import Casadi.Sparsity ( Sparsity )
@@ -33,7 +35,8 @@
   ones :: (Int,Int) -> a
   zeros :: (Int,Int) -> a
   zerosSp :: Sparsity -> a
-  solve :: a -> a -> a
+  solve :: a -> a -> String -> Map String GenericType -> a
+  solve' :: a -> a -> a
   indexed :: a -> Slice -> Slice -> a
   sparsity :: a -> Sparsity
   getNZ :: a -> Slice -> a
@@ -48,6 +51,7 @@
   fromDVector :: V.Vector Double -> a
   fromDouble :: Double -> a
   allocEmpty :: IO a
+{-# DEPRECATED solve' "use the new solve, this one is going away" #-}
 
 
 vertslice :: CMatrix a => a -> V.Vector Int -> V.Vector a
diff --git a/src/Casadi/DMatrix.hs b/src/Casadi/DMatrix.hs
--- a/src/Casadi/DMatrix.hs
+++ b/src/Casadi/DMatrix.hs
@@ -46,7 +46,7 @@
 {-# NOINLINE fromSparseData #-}
 
 dsparsify :: DMatrix -> DMatrix
-dsparsify x = unsafePerformIO (dmatrix_zz_sparsify__0 x)
+dsparsify x = unsafePerformIO (C.casadi_sparsify__2 x)
 {-# NOINLINE dsparsify #-}
 
 dnonzeros :: DMatrix -> V.Vector Double
@@ -58,21 +58,21 @@
   {-# NOINLINE show #-}
 
 instance Eq DMatrix where
-  x == y = unsafePerformIO (dmatrix_zz_isEqual__0 x y)
+  x == y = unsafePerformIO (C.casadi_isEqual__2 x y)
   {-# NOINLINE (==) #-}
 
 instance CMatrix DMatrix where
-  veccat x = unsafePerformIO (dmatrix_zz_veccat x)
+  veccat x = unsafePerformIO (C.casadi_veccat__1 x)
   {-# NOINLINE veccat #-}
   ----  vertsplit = vertslice
-  vertsplit x ks = unsafePerformIO (dmatrix_zz_vertsplit x ks)
+  vertsplit x ks = unsafePerformIO (C.casadi_vertsplit__5 x ks)
   {-# NOINLINE vertsplit #-}
-  vertcat x = unsafePerformIO (dmatrix_zz_vertcat x)
+  vertcat x = unsafePerformIO (C.casadi_vertcat__1 x)
   {-# NOINLINE vertcat #-}
   --  horzsplit = horzslice
-  horzsplit x ks = unsafePerformIO (dmatrix_zz_horzsplit x ks)
+  horzsplit x ks = unsafePerformIO (C.casadi_horzsplit__5 x ks)
   {-# NOINLINE horzsplit #-}
-  horzcat x = unsafePerformIO (dmatrix_zz_horzcat x)
+  horzcat x = unsafePerformIO (C.casadi_horzcat__1 x)
   {-# NOINLINE horzcat #-}
   size1 x = unsafePerformIO (dmatrix_size1 x)
   {-# NOINLINE size1 #-}
@@ -80,30 +80,32 @@
   {-# NOINLINE size2 #-}
   numel x = unsafePerformIO (dmatrix_numel__1 x)
   {-# NOINLINE numel #-}
-  mm x y = unsafePerformIO (dmatrix_zz_mtimes__1 x y)
+  mm x y = unsafePerformIO (C.casadi_mul__3 x y)
   {-# NOINLINE mm #-}
-  innerProd x y = unsafePerformIO (dmatrix_zz_inner_prod x y)
+  innerProd x y = unsafePerformIO (C.casadi_inner_prod__1 x y)
   {-# NOINLINE innerProd #-}
   trans x = unsafePerformIO (dmatrix_T x)
   {-# NOINLINE trans #-}
-  diag x = unsafePerformIO (dmatrix_zz_diag x)
+  diag x = unsafePerformIO (C.casadi_diag__1 x)
   {-# NOINLINE diag #-}
   eye n = unsafePerformIO (dmatrix_eye n)
   {-# NOINLINE eye #-}
-  ones (r,c) = unsafePerformIO (dmatrix_ones__3 r c)
+  ones (r,c) = unsafePerformIO (dmatrix_ones__4 r c)
   {-# NOINLINE ones #-}
-  zeros (r,c) = unsafePerformIO (dmatrix_zeros__3 r c)
+  zeros (r,c) = unsafePerformIO (dmatrix_zeros__4 r c)
   {-# NOINLINE zeros #-}
-  zerosSp sp = unsafePerformIO (dmatrix_zeros__0 sp)
+  zerosSp sp = unsafePerformIO (dmatrix_zeros__1 sp)
   {-# NOINLINE zerosSp #-}
-  solve x y = unsafePerformIO (C.solve__3 x y)
+  solve x y s m = unsafePerformIO (C.casadi_solve__4 x y s m)
   {-# NOINLINE solve #-}
+  solve' x y = unsafePerformIO (C.casadi_solve__5 x y)
+  {-# NOINLINE solve' #-}
   indexed m spx spy = unsafePerformIO $ do
     ret <- allocEmpty :: IO DMatrix
     dmatrix_get__3 m ret False spx spy
     return ret
   {-# NOINLINE indexed #-}
-  sparsity x = unsafePerformIO (dmatrix_sparsityRef x)
+  sparsity x = unsafePerformIO (dmatrix_getSparsity x)
   {-# NOINLINE sparsity #-}
   getNZ m sp = unsafePerformIO $ do
     ret <- allocEmpty :: IO DMatrix
@@ -111,16 +113,16 @@
     return ret
   {-# NOINLINE getNZ #-}
   setNZ m y s = dmatrix_setNZ__1 m y False s
-  triu x = unsafePerformIO (dmatrix_zz_triu__0 x)
+  triu x = unsafePerformIO (C.casadi_triu__2 x)
   {-# NOINLINE triu #-}
-  tril x = unsafePerformIO (dmatrix_zz_tril__0 x)
+  tril x = unsafePerformIO (C.casadi_tril__2 x)
   {-# NOINLINE tril #-}
-  triu2symm  x = unsafePerformIO (dmatrix_zz_triu2symm x)
+  triu2symm x = unsafePerformIO (C.casadi_triu2symm__1 x)
   {-# NOINLINE triu2symm #-}
-  tril2symm x = unsafePerformIO (dmatrix_zz_tril2symm x)
+  tril2symm x = unsafePerformIO (C.casadi_tril2symm__1 x)
   {-# NOINLINE tril2symm #-}
   copy m = dmatrix__7 m
-  densify x = unsafePerformIO (dmatrix_zz_densify x)
+  densify x = unsafePerformIO (C.casadi_densify__1 x)
   {-# NOINLINE densify #-}
   fromDMatrix = id
   fromDVector x = unsafePerformIO (dmatrix__2 (V.singleton x) >>= dmatrix_T)
@@ -131,21 +133,21 @@
 
 
 instance Num DMatrix where
-  (+) x y = unsafePerformIO (dmatrix_zz_plus x y)
+  (+) x y = unsafePerformIO (C.casadi_plus__1 x y)
   {-# NOINLINE (+) #-}
-  (-) x y = unsafePerformIO (dmatrix_zz_minus x y)
+  (-) x y = unsafePerformIO (C.casadi_minus__1 x y)
   {-# NOINLINE (-) #-}
-  (*) x y = unsafePerformIO (dmatrix_zz_times x y)
+  (*) x y = unsafePerformIO (C.casadi_times__1 x y)
   {-# NOINLINE (*) #-}
   fromInteger x = fromDouble (fromInteger x :: Double)
   {-# NOINLINE fromInteger #-}
-  abs x = unsafePerformIO (dmatrix_zz_abs x)
+  abs x = unsafePerformIO (C.casadi_abs__1 x)
   {-# NOINLINE abs #-}
-  signum x = unsafePerformIO (dmatrix_zz_sign x)
+  signum x = unsafePerformIO (C.casadi_sign__1 x)
   {-# NOINLINE signum #-}
 
 instance Fractional DMatrix where
-  (/) x y = unsafePerformIO (dmatrix___truediv____0 x y)
+  (/) x y = unsafePerformIO (C.casadi_rdivide__1 x y)
   {-# NOINLINE (/) #-}
   fromRational x = fromDouble (fromRational x :: Double)
   {-# NOINLINE fromRational #-}
@@ -153,55 +155,55 @@
 instance Floating DMatrix where
   pi = fromDouble (pi :: Double)
   {-# NOINLINE pi #-}
-  (**) x y = unsafePerformIO (dmatrix_zz_power x y)
+  (**) x y = unsafePerformIO (C.casadi_power__1 x y)
   {-# NOINLINE (**) #-}
-  exp x   = unsafePerformIO (dmatrix_zz_exp x)
+  exp x   = unsafePerformIO (C.casadi_exp__1 x)
   {-# NOINLINE exp #-}
-  log x   = unsafePerformIO (dmatrix_zz_log x)
+  log x   = unsafePerformIO (C.casadi_log__1 x)
   {-# NOINLINE log #-}
-  sin x   = unsafePerformIO (dmatrix_zz_sin x)
+  sin x   = unsafePerformIO (C.casadi_sin__1 x)
   {-# NOINLINE sin #-}
-  cos x   = unsafePerformIO (dmatrix_zz_cos x)
+  cos x   = unsafePerformIO (C.casadi_cos__1 x)
   {-# NOINLINE cos #-}
-  tan x   = unsafePerformIO (dmatrix_zz_tan x)
+  tan x   = unsafePerformIO (C.casadi_tan__1 x)
   {-# NOINLINE tan #-}
-  asin x  = unsafePerformIO (dmatrix_zz_asin x)
+  asin x  = unsafePerformIO (C.casadi_asin__1 x)
   {-# NOINLINE asin #-}
-  atan x  = unsafePerformIO (dmatrix_zz_atan x)
+  atan x  = unsafePerformIO (C.casadi_atan__1 x)
   {-# NOINLINE atan #-}
-  acos x  = unsafePerformIO (dmatrix_zz_acos x)
+  acos x  = unsafePerformIO (C.casadi_acos__1 x)
   {-# NOINLINE acos #-}
-  sinh x  = unsafePerformIO (dmatrix_zz_sinh x)
+  sinh x  = unsafePerformIO (C.casadi_sinh__1 x)
   {-# NOINLINE sinh #-}
-  cosh x  = unsafePerformIO (dmatrix_zz_cosh x)
+  cosh x  = unsafePerformIO (C.casadi_cosh__1 x)
   {-# NOINLINE cosh #-}
-  tanh x  = unsafePerformIO (dmatrix_zz_tanh x)
+  tanh x  = unsafePerformIO (C.casadi_tanh__1 x)
   {-# NOINLINE tanh #-}
-  asinh x = unsafePerformIO (dmatrix_zz_asinh x)
+  asinh x = unsafePerformIO (C.casadi_asinh__1 x)
   {-# NOINLINE asinh #-}
-  atanh x = unsafePerformIO (dmatrix_zz_atanh x)
+  atanh x = unsafePerformIO (C.casadi_atanh__1 x)
   {-# NOINLINE atanh #-}
-  acosh x = unsafePerformIO (dmatrix_zz_acosh x)
+  acosh x = unsafePerformIO (C.casadi_acosh__1 x)
   {-# NOINLINE acosh #-}
 
 instance Fmod DMatrix where
-  fmod x y = unsafePerformIO (dmatrix_zz_mod x y)
+  fmod x y = unsafePerformIO (C.casadi_mod__1 x y)
   {-# NOINLINE fmod #-}
 
 instance ArcTan2 DMatrix where
-  arctan2 x y = unsafePerformIO (dmatrix_zz_atan2 x y)
+  arctan2 x y = unsafePerformIO (C.casadi_atan2__1 x y)
   {-# NOINLINE arctan2 #-}
 
 instance SymOrd DMatrix where
-  x `leq` y = unsafePerformIO (dmatrix_zz_le x y)
+  x `leq` y = unsafePerformIO (C.casadi_le__1 x y)
   {-# NOINLINE leq #-}
-  x `geq` y = unsafePerformIO (dmatrix_zz_ge x y)
+  x `geq` y = unsafePerformIO (C.casadi_ge__1 x y)
   {-# NOINLINE geq #-}
-  x  `eq` y = unsafePerformIO (dmatrix_zz_eq x y)
+  x  `eq` y = unsafePerformIO (C.casadi_eq__1 x y)
   {-# NOINLINE eq #-}
 
 instance Erf DMatrix where
-  erf x = unsafePerformIO (dmatrix_zz_erf x)
+  erf x = unsafePerformIO (C.casadi_erf__1 x)
   {-# NOINLINE erf #-}
-  erfinv x = unsafePerformIO (dmatrix_zz_erfinv x)
+  erfinv x = unsafePerformIO (C.casadi_erfinv__1 x)
   {-# NOINLINE erfinv #-}
diff --git a/src/Casadi/Function.hs b/src/Casadi/Function.hs
--- a/src/Casadi/Function.hs
+++ b/src/Casadi/Function.hs
@@ -1,56 +1,67 @@
 {-# OPTIONS_GHC -Wall -fno-cse -fno-warn-orphans #-}
 
 module Casadi.Function
-       ( C.Function, callMX, callSX, evalDMatrix
+       ( C.Function, AlwaysInline(..), NeverInline(..)
+       , callMX, callMX', callSX, callSX', evalDMatrix, evalDMatrix'
        , jacobian, gradient, derivative
-       , generateCode, externalFunction
+       , generateCode, externalFunction, externalFunction'
        ) where
 
+import Data.Map ( Map )
+import qualified Data.Traversable as T
 import Data.Vector ( Vector )
-import qualified Data.Vector as V
 import System.IO.Unsafe ( unsafePerformIO )
-import Control.Monad ( zipWithM_ )
 
-import qualified Casadi.Core.Classes.IOInterfaceFunction as C
 import qualified Casadi.Core.Classes.Function as C
 import qualified Casadi.Core.Classes.ExternalFunction as C
-import qualified Casadi.Core.CustomWrappers as C
+import qualified Casadi.Core.Classes.CodeGenerator as C
+--import qualified Casadi.Core.CustomWrappers as C
 
 import Casadi.SX ( SX )
 import Casadi.MX ( MX )
 import Casadi.DMatrix ( DMatrix )
+import Casadi.GenericC ( GenericC ( mkGeneric ), Opt, GenericType )
 import Casadi.SharedObject ( castSharedObject )
 
+newtype AlwaysInline = AlwaysInline Bool
+newtype NeverInline = NeverInline Bool
+
 instance Show C.Function where
   show x = show (castSharedObject x)
   {-# NOINLINE show #-}
 
 -- | call an MXFunction on symbolic inputs, getting symbolic outputs
-callMX :: C.FunctionClass f => f -> Vector MX -> Vector MX
-callMX f ins = unsafePerformIO (C.function_operator_call__0 f ins)
+callMX :: C.FunctionClass f => f -> Vector MX -> AlwaysInline -> NeverInline -> Vector MX
+callMX f ins (AlwaysInline alwaysInline) (NeverInline neverInline) =
+  unsafePerformIO (C.function_operator_call__11 f ins alwaysInline neverInline)
 {-# NOINLINE callMX #-}
 
+-- | call an MXFunction on symbolic inputs, getting symbolic outputs
+callMX' :: C.FunctionClass f => f -> Map String MX -> AlwaysInline -> NeverInline -> Map String MX
+callMX' f ins (AlwaysInline alwaysInline) (NeverInline neverInline) =
+  unsafePerformIO (C.function_operator_call__2 f ins alwaysInline neverInline)
+{-# NOINLINE callMX' #-}
+
 -- | call an SXFunction on symbolic inputs, getting symbolic outputs
-callSX :: C.FunctionClass f => f -> Vector SX -> Vector SX
-callSX f ins = unsafePerformIO $ (C.function_operator_call__3 f ins)
+callSX :: C.FunctionClass f => f -> Vector SX -> AlwaysInline -> NeverInline -> Vector SX
+callSX f ins (AlwaysInline alwaysInline) (NeverInline neverInline) =
+  unsafePerformIO (C.function_operator_call__14 f ins alwaysInline neverInline)
 {-# NOINLINE callSX #-}
 
--- | evaluate an SXFunction with 1 input and 1 output
-evalDMatrix :: (C.FunctionClass f, C.IOInterfaceFunctionClass f)
-               => f -> Vector DMatrix -> IO (Vector DMatrix)
-evalDMatrix sxf inputs = do
-  -- set inputs
-  zipWithM_ (C.ioInterfaceFunction_setInput__2 sxf) (V.toList inputs) [0..]
-
-  -- eval
-  C.function_evaluate sxf
+-- | call an SXFunction on symbolic inputs, getting symbolic outputs
+callSX' :: C.FunctionClass f => f -> Map String SX -> AlwaysInline -> NeverInline -> Map String SX
+callSX' f ins (AlwaysInline alwaysInline) (NeverInline neverInline) =
+  unsafePerformIO (C.function_operator_call__5 f ins alwaysInline neverInline)
+{-# NOINLINE callSX' #-}
 
-  -- get outputs
-  numOut <- C.ioInterfaceFunction_getNumOutputs sxf
-  outputs <- mapM (C.ioInterfaceFunction_output__2 sxf) (take numOut [0..])
+-- | evaluate a Function with many inputs, many outputs
+evalDMatrix :: C.FunctionClass f => f -> Vector DMatrix -> IO (Vector DMatrix)
+evalDMatrix = C.function_operator_call__15
 
-  -- return vectorized outputs
-  return (V.fromList outputs)
+-- | evaluate a Function with many inputs, many outputs
+evalDMatrix' :: C.FunctionClass f =>
+                f -> Map String DMatrix -> IO (Map String DMatrix)
+evalDMatrix' = C.function_operator_call__6
 
 jacobian :: C.FunctionClass a => a -> Int -> Int -> Bool -> Bool -> IO C.Function
 jacobian = C.function_jacobian__14
@@ -61,9 +72,17 @@
 derivative :: C.FunctionClass a => a -> Int -> Int -> IO C.Function
 derivative = C.function_derivative
 
-generateCode :: C.FunctionClass a => a -> Bool -> String
-generateCode f x = unsafePerformIO (C.function_custom_generateCode f x)
+generateCode :: C.FunctionClass a => a -> Map String Opt -> String
+generateCode f opts0 = unsafePerformIO $ do
+  opts <- T.mapM mkGeneric opts0 :: IO (Map String GenericType)
+  cg <- C.codeGenerator__1 opts
+  C.codeGenerator_add__1 cg (C.castFunction f)
+  C.codeGenerator_generate__0 cg
 {-# NOINLINE generateCode #-}
 
-externalFunction :: String -> IO C.Function
-externalFunction name = fmap C.castFunction $ C.externalFunction__0 name
+externalFunction :: String -> Map String GenericType -> IO C.Function
+externalFunction name opts = fmap C.castFunction $ C.externalFunction__5 name opts
+
+externalFunction' :: String -> String -> Map String GenericType -> IO C.Function
+externalFunction' name binName opts =
+  fmap C.castFunction $ C.externalFunction__3 name binName opts
diff --git a/src/Casadi/GenericC.hs b/src/Casadi/GenericC.hs
--- a/src/Casadi/GenericC.hs
+++ b/src/Casadi/GenericC.hs
@@ -1,25 +1,21 @@
 {-# OPTIONS_GHC -Wall -fno-warn-orphans -fno-cse #-}
 {-# Language GADTs #-}
 {-# Language FlexibleInstances #-}
+{-# Language ScopedTypeVariables #-}
 
+-- todo(greg): merge this with Casadi.Option
 module Casadi.GenericC
        ( GenericC(..)
+       , GenericType
        , Opt(..)
        , getDescription
        ) where
 
+import qualified Data.Traversable as T
 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 Data.Map ( Map )
+import System.IO.Unsafe ( unsafePerformIO )
 
-import Casadi.Core.Data ( GenericType' )
 import Casadi.Core.Classes.Function ( Function )
 import Casadi.Core.Classes.GenericType
 import Casadi.Core.Classes.DerivativeGenerator ( DerivativeGenerator )
@@ -36,6 +32,8 @@
 
 data Opt where
   Opt :: GenericC a => a -> Opt
+instance Show Opt where
+  show (Opt x) = show (unsafePerformIO (mkGeneric x))
 
 getDescription :: GenericType -> IO String
 getDescription = genericType_get_description
@@ -71,14 +69,19 @@
   mkGeneric = genericType__3
   fromGeneric = ifThenGet genericType_isFunction genericType_toFunction
 instance GenericC DerivativeGenerator where
-  mkGeneric = genericType__1
+  mkGeneric = genericType__2
   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)]"
+instance GenericC Opt where
+  mkGeneric (Opt o) = mkGeneric o
+  fromGeneric = const $ return $ error "no fromGeneric for Opt"
+instance GenericC a => GenericC (Map String a) where
+  mkGeneric dict = T.mapM mkGeneric dict >>= genericType__0
+  fromGeneric gdict = do
+    mDict <- ifThenGet genericType_isDict genericType_toDict gdict
+    case mDict of
+     Nothing -> return Nothing
+     Just dict -> do
+       T.sequenceA <$> T.mapM fromGeneric dict
 
 ifThenGet :: (a -> IO Bool) -> (a -> IO b) -> a -> IO (Maybe b)
 ifThenGet isOpt getOpt g = do
@@ -86,19 +89,3 @@
   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/IOScheme.hs b/src/Casadi/IOScheme.hs
new file mode 100644
--- /dev/null
+++ b/src/Casadi/IOScheme.hs
@@ -0,0 +1,67 @@
+{-# OPTIONS_GHC -Wall #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+
+module Casadi.IOScheme
+       ( InputOutputScheme(..)
+       , mxFunctionWithSchemes
+       , sxFunctionWithSchemes
+       ) where
+
+import Control.Monad ( unless )
+import qualified Data.Map as M
+import qualified Data.Set as S
+import Data.Vector ( Vector )
+import qualified Data.Vector as V
+import Text.Printf ( printf )
+
+import Casadi.Core.Classes.SXFunction
+import Casadi.Core.Classes.MXFunction
+import Casadi.Core.Enums ( InputOutputScheme(..) )
+import qualified Casadi.Core.Tools as C
+
+import Casadi.MX ( MX )
+import Casadi.MXFunction ( mxFunction' )
+import Casadi.Option ( Opt )
+import Casadi.SX ( SX )
+import Casadi.SXFunction ( sxFunction' )
+
+mxFunctionWithSchemes ::
+  String
+  -> (InputOutputScheme, M.Map String MX)
+  -> (InputOutputScheme, M.Map String MX)
+  -> M.Map String Opt
+  -> IO MXFunction
+mxFunctionWithSchemes name (inputScheme, inputs) (outputScheme, outputs) opts = do
+  input' <- schemeToMapVec inputScheme inputs
+  output' <- schemeToMapVec outputScheme outputs
+  mxFunction' name input' output' opts
+
+sxFunctionWithSchemes ::
+  String
+  -> (InputOutputScheme, M.Map String SX)
+  -> (InputOutputScheme, M.Map String SX)
+  -> M.Map String Opt
+  -> IO SXFunction
+sxFunctionWithSchemes name (inputScheme, inputs) (outputScheme, outputs) opts = do
+  input' <- schemeToMapVec inputScheme inputs
+  output' <- schemeToMapVec outputScheme outputs
+  sxFunction' name input' output' opts
+
+schemeToMapVec ::
+  forall a
+  . Num a
+  => InputOutputScheme -> M.Map String a -> IO (M.Map String a, Vector String)
+schemeToMapVec scheme symMap = do
+  len <- C.getSchemeSize scheme
+  let indices = take len [0..]
+  
+  indicesNames <- mapM (C.getSchemeEntryName scheme) indices :: IO [String]
+
+  let namesSet = S.fromList indicesNames
+      extraEntries = M.keysSet symMap S.\\ namesSet
+
+  _ <- unless (S.null extraEntries) $ error $ printf
+    "scheme %s has entries %s, but you gave keys %s\n"
+    (show scheme) (show namesSet) (show extraEntries)
+
+  return (symMap, V.fromList indicesNames)
diff --git a/src/Casadi/IOSchemes.hs b/src/Casadi/IOSchemes.hs
deleted file mode 100644
--- a/src/Casadi/IOSchemes.hs
+++ /dev/null
@@ -1,63 +0,0 @@
-{-# OPTIONS_GHC -Wall #-}
-{-# Language ScopedTypeVariables #-}
-
-module Casadi.IOSchemes
-       ( mkSchemeSX
-       , mkSchemeMX
-       , mkSchemeCRSSparsity
-       ) where
-
-import qualified Data.Map as M
-import qualified Data.Set as S
-import qualified Data.Foldable as F
-import qualified Data.Vector as V
-
-import Casadi.Core.Classes.Sparsity -- ( Sparsity, sparsity' )
-import Casadi.Core.Classes.SX -- ( SX, sx )
-import Casadi.Core.Classes.MX -- ( MX, mx )
-import Casadi.Core.Classes.IOScheme -- ( ioScheme', ioScheme_size, ioScheme_entry )
-import Casadi.Core.Enums ( InputOutputScheme(..) )
-
-mkScheme :: forall a . IO a -> InputOutputScheme -> [(String,a)] -> IO (V.Vector a)
-mkScheme newEmpty schemeEnum userVals = do
-  sch <- ioScheme__22 schemeEnum
-  size <- ioScheme_size sch
-  let ks = take size [(0::Int)..]
-  entries <- mapM (ioScheme_entry sch) ks
-  let entrySet :: S.Set String
-      entrySet = S.fromList entries
-
-      -- map of user input {String:a}, already checked for duplicates
-      userMap :: M.Map String a
-      userMap = M.fromListWithKey err userVals
-      err k _ _ = error $ "mkScheme: " ++ show schemeEnum ++ ": you gave key \"" ++ k ++ "\" more than once"
-
-      userSet :: S.Set String
-      userSet = M.keysSet userMap
-
-  case F.toList (S.difference userSet entrySet) of
-    [] -> return ()
-    xs ->  error $ "mkScheme: " ++ show schemeEnum ++ ": you gave keys " ++ show xs ++ " which aren't valid, valid entries:\n" ++ show entries
-
-  let getElem str = case M.lookup str userMap of
-        Nothing -> newEmpty -- new empty
-        Just x -> return x
-
---  name <- ioScheme_name sch
---  print size
---  print name
---  ioScheme_entryNames sch >>= putStrLn
---  mapM (ioScheme_entry sch) ks >>= print
---  mapM (ioScheme_entryEnum sch) ks >>= print
---  mapM (ioScheme_entryLabel sch) ks >>= print
-
-  fmap V.fromList $ mapM getElem entries
-
-mkSchemeSX :: InputOutputScheme -> [(String,SX)] -> IO (V.Vector SX)
-mkSchemeSX = mkScheme sx__10
-
-mkSchemeMX :: InputOutputScheme -> [(String,MX)] -> IO (V.Vector MX)
-mkSchemeMX = mkScheme mx__7
-
-mkSchemeCRSSparsity :: InputOutputScheme -> [(String,Sparsity)] -> IO (V.Vector Sparsity)
-mkSchemeCRSSparsity = mkScheme sparsity__2
diff --git a/src/Casadi/MX.hs b/src/Casadi/MX.hs
--- a/src/Casadi/MX.hs
+++ b/src/Casadi/MX.hs
@@ -2,7 +2,7 @@
 
 module Casadi.MX
        ( MX
-       , sym, symV, symM, gradient, jacobian -- , hessian
+       , sym, symV, symM, gradient, jacobian, hessian
        , expand
        ) where
 
@@ -22,7 +22,7 @@
   conjugate = id
 
 instance Eq MX where
-  x == y = unsafePerformIO (mx_zz_isEqual__0 x y)
+  x == y = unsafePerformIO (C.casadi_isEqual__6 x y)
   {-# NOINLINE (==) #-}
 
 instance Show MX where
@@ -30,49 +30,49 @@
   {-# NOINLINE show #-}
 
 sym :: String -> IO MX
-sym x = fmap castMX (mx_sym__5 x)
+sym x = fmap castMX (mx_sym__6 x)
 
 symV :: String -> Int -> IO MX
-symV x y = fmap castMX (mx_sym__6 x y)
+symV x y = fmap castMX (mx_sym__7 x y)
 
 symM :: String -> Int -> Int -> IO MX
-symM x y z = fmap castMX (mx_sym__7 x y z)
+symM x y z = fmap castMX (mx_sym__8 x y z)
 
 -- | @jacobian exp x@ is the jacobian of exp w.r.t. x
 gradient :: MX -> MX -> MX
-gradient x y = unsafePerformIO (C.gradient__0 x y)
+gradient x y = unsafePerformIO (C.casadi_gradient__3 x y)
 {-# NOINLINE gradient #-}
 
 -- | @jacobian exp x@ is the jacobian of exp w.r.t. x
 jacobian :: MX -> MX -> MX
-jacobian x y = unsafePerformIO (C.jacobian__0 x y)
+jacobian x y = unsafePerformIO (C.casadi_jacobian__3 x y)
 {-# NOINLINE jacobian #-}
 
 expand :: Vector MX -> Vector MX
-expand x = unsafePerformIO (C.matrix_expand__0 x)
+expand x = unsafePerformIO (C.casadi_matrix_expand__3 x)
 {-# NOINLINE expand #-}
 
 ---- | @hessian exp x@ is the jacobian of exp w.r.t. x
---hessian :: MX -> MX -> MX
---hessian x y = unsafePerformIO (C.hessian x y)
---{-# NOINLINE hessian #-}
+hessian :: MX -> MX -> MX -> MX
+hessian x y z = unsafePerformIO (C.casadi_hessian__3 x y z)
+{-# NOINLINE hessian #-}
 
 --sparsify :: MX -> MX
---sparsify x = unsafePerformIO (mx_zz_sparsify__0 x)
+--sparsify x = unsafePerformIO (C.casadi_sparsify__0__3 x)
 --{-# NOINLINE sparsify #-}
 
 instance CMatrix MX where
-  veccat x = unsafePerformIO (mx_zz_veccat x)
+  veccat x = unsafePerformIO (C.casadi_veccat__3 x)
   {-# NOINLINE veccat #-}
   --  vertsplit = vertslice
-  vertsplit x ks = unsafePerformIO (mx_zz_vertsplit x ks)
+  vertsplit x ks = unsafePerformIO (C.casadi_vertsplit__11 x ks)
   {-# NOINLINE vertsplit #-}
-  vertcat x = unsafePerformIO (mx_zz_vertcat x)
+  vertcat x = unsafePerformIO (C.casadi_vertcat__3 x)
   {-# NOINLINE vertcat #-}
   --  horzsplit = horzslice
-  horzsplit x ks = unsafePerformIO (mx_zz_horzsplit x ks)
+  horzsplit x ks = unsafePerformIO (C.casadi_horzsplit__11 x ks)
   {-# NOINLINE horzsplit #-}
-  horzcat x = unsafePerformIO (mx_zz_horzcat x)
+  horzcat x = unsafePerformIO (C.casadi_horzcat__3 x)
   {-# NOINLINE horzcat #-}
   size1 x = unsafePerformIO (mx_size1 x)
   {-# NOINLINE size1 #-}
@@ -80,30 +80,32 @@
   {-# NOINLINE size2 #-}
   numel x = unsafePerformIO (mx_numel__1 x)
   {-# NOINLINE numel #-}
-  mm x y = unsafePerformIO (mx_zz_mtimes__1 x y)
+  mm x y = unsafePerformIO (C.casadi_mul__7 x y)
   {-# NOINLINE mm #-}
-  innerProd x y = unsafePerformIO (mx_zz_inner_prod x y)
+  innerProd x y = unsafePerformIO (C.casadi_inner_prod__3 x y)
   {-# NOINLINE innerProd #-}
   trans x = unsafePerformIO (mx_T x)
   {-# NOINLINE trans #-}
-  diag x = unsafePerformIO (mx_zz_diag x)
+  diag x = unsafePerformIO (C.casadi_diag__3 x)
   {-# NOINLINE diag #-}
   eye n = unsafePerformIO (mx_eye n)
   {-# NOINLINE eye #-}
-  ones (r,c) = unsafePerformIO (mx_ones__3 r c)
+  ones (r,c) = unsafePerformIO (mx_ones__4 r c)
   {-# NOINLINE ones #-}
-  zeros (r,c) = unsafePerformIO (mx_zeros__3 r c)
+  zeros (r,c) = unsafePerformIO (mx_zeros__4 r c)
   {-# NOINLINE zeros #-}
-  zerosSp sp = unsafePerformIO (mx_zeros__0 sp)
+  zerosSp sp = unsafePerformIO (mx_zeros__1 sp)
   {-# NOINLINE zerosSp #-}
-  solve a b = unsafePerformIO (C.solve__0 a b)
+  solve x y s m = unsafePerformIO (C.casadi_solve__10 x y s m)
   {-# NOINLINE solve #-}
+  solve' x y = unsafePerformIO (C.casadi_solve__11 x y)
+  {-# NOINLINE solve' #-}
   indexed m spx spy = unsafePerformIO $ do
     ret <- allocEmpty :: IO MX
     mx_get__3 m ret False spx spy
     return ret
   {-# NOINLINE indexed #-}
-  sparsity x = unsafePerformIO (mx_sparsityRef x)
+  sparsity x = unsafePerformIO (mx_getSparsity x)
   {-# NOINLINE sparsity #-}
   getNZ m sp = unsafePerformIO $ do
     ret <- allocEmpty :: IO MX
@@ -111,16 +113,16 @@
     return ret
   {-# NOINLINE getNZ #-}
   setNZ m y s = mx_setNZ__1 m y False s
-  triu x = unsafePerformIO (mx_zz_triu__0 x)
+  triu x = unsafePerformIO (C.casadi_triu__6 x)
   {-# NOINLINE triu #-}
-  tril x = unsafePerformIO (mx_zz_tril__0 x)
+  tril x = unsafePerformIO (C.casadi_tril__6 x)
   {-# NOINLINE tril #-}
-  triu2symm x = unsafePerformIO (mx_zz_triu2symm x)
+  triu2symm x = unsafePerformIO (C.casadi_triu2symm__3 x)
   {-# NOINLINE triu2symm #-}
-  tril2symm x = unsafePerformIO (mx_zz_tril2symm x)
+  tril2symm x = unsafePerformIO (C.casadi_tril2symm__3 x)
   {-# NOINLINE tril2symm #-}
   copy m = mx__2 m
-  densify x = unsafePerformIO (mx_zz_densify x)
+  densify x = unsafePerformIO (C.casadi_densify__3 x)
   {-# NOINLINE densify #-}
   fromDMatrix x = unsafePerformIO (mx__0 x)
   {-# NOINLINE fromDMatrix #-}
@@ -132,21 +134,21 @@
 
 
 instance Num MX where
-  (+) x y = unsafePerformIO (mx_zz_plus x y)
+  (+) x y = unsafePerformIO (C.casadi_plus__3 x y)
   {-# NOINLINE (+) #-}
-  (-) x y = unsafePerformIO (mx_zz_minus x y)
+  (-) x y = unsafePerformIO (C.casadi_minus__3 x y)
   {-# NOINLINE (-) #-}
-  (*) x y = unsafePerformIO (mx_zz_times x y)
+  (*) x y = unsafePerformIO (C.casadi_times__3 x y)
   {-# NOINLINE (*) #-}
   fromInteger x = fromDouble (fromInteger x :: Double)
   {-# NOINLINE fromInteger #-}
-  abs x = unsafePerformIO (mx_zz_abs x)
+  abs x = unsafePerformIO (C.casadi_abs__3 x)
   {-# NOINLINE abs #-}
-  signum x = unsafePerformIO (mx_zz_sign x)
+  signum x = unsafePerformIO (C.casadi_sign__3 x)
   {-# NOINLINE signum #-}
 
 instance Fractional MX where
-  (/) x y = unsafePerformIO (mx___truediv____0 x y)
+  (/) x y = unsafePerformIO (C.casadi_rdivide__3 x y)
   {-# NOINLINE (/) #-}
   fromRational x = fromDouble (fromRational x :: Double)
   {-# NOINLINE fromRational #-}
@@ -154,55 +156,55 @@
 instance Floating MX where
   pi = fromDouble (pi :: Double)
   {-# NOINLINE pi #-}
-  (**) x y = unsafePerformIO (mx_zz_power x y)
+  (**) x y = unsafePerformIO (C.casadi_power__3 x y)
   {-# NOINLINE (**) #-}
-  exp x   = unsafePerformIO (mx_zz_exp x)
+  exp x   = unsafePerformIO (C.casadi_exp__3 x)
   {-# NOINLINE exp #-}
-  log x   = unsafePerformIO (mx_zz_log x)
+  log x   = unsafePerformIO (C.casadi_log__3 x)
   {-# NOINLINE log #-}
-  sin x   = unsafePerformIO (mx_zz_sin x)
+  sin x   = unsafePerformIO (C.casadi_sin__3 x)
   {-# NOINLINE sin #-}
-  cos x   = unsafePerformIO (mx_zz_cos x)
+  cos x   = unsafePerformIO (C.casadi_cos__3 x)
   {-# NOINLINE cos #-}
-  tan x   = unsafePerformIO (mx_zz_tan x)
+  tan x   = unsafePerformIO (C.casadi_tan__3 x)
   {-# NOINLINE tan #-}
-  asin x  = unsafePerformIO (mx_zz_asin x)
+  asin x  = unsafePerformIO (C.casadi_asin__3 x)
   {-# NOINLINE asin #-}
-  atan x  = unsafePerformIO (mx_zz_atan x)
+  atan x  = unsafePerformIO (C.casadi_atan__3 x)
   {-# NOINLINE atan #-}
-  acos x  = unsafePerformIO (mx_zz_acos x)
+  acos x  = unsafePerformIO (C.casadi_acos__3 x)
   {-# NOINLINE acos #-}
-  sinh x  = unsafePerformIO (mx_zz_sinh x)
+  sinh x  = unsafePerformIO (C.casadi_sinh__3 x)
   {-# NOINLINE sinh #-}
-  cosh x  = unsafePerformIO (mx_zz_cosh x)
+  cosh x  = unsafePerformIO (C.casadi_cosh__3 x)
   {-# NOINLINE cosh #-}
-  tanh x  = unsafePerformIO (mx_zz_tanh x)
+  tanh x  = unsafePerformIO (C.casadi_tanh__3 x)
   {-# NOINLINE tanh #-}
-  asinh x = unsafePerformIO (mx_zz_asinh x)
+  asinh x = unsafePerformIO (C.casadi_asinh__3 x)
   {-# NOINLINE asinh #-}
-  atanh x = unsafePerformIO (mx_zz_atanh x)
+  atanh x = unsafePerformIO (C.casadi_atanh__3 x)
   {-# NOINLINE atanh #-}
-  acosh x = unsafePerformIO (mx_zz_acosh x)
+  acosh x = unsafePerformIO (C.casadi_acosh__3 x)
   {-# NOINLINE acosh #-}
 
 instance Fmod MX where
-  fmod x y = unsafePerformIO (mx_zz_mod x y)
+  fmod x y = unsafePerformIO (C.casadi_mod__3 x y)
   {-# NOINLINE fmod #-}
 
 instance ArcTan2 MX where
-  arctan2 x y = unsafePerformIO (mx_zz_atan2 x y)
+  arctan2 x y = unsafePerformIO (C.casadi_atan2__3 x y)
   {-# NOINLINE arctan2 #-}
 
 instance SymOrd MX where
-  x `leq` y = unsafePerformIO (mx_zz_le x y)
+  x `leq` y = unsafePerformIO (C.casadi_le__3 x y)
   {-# NOINLINE leq #-}
-  x `geq` y = unsafePerformIO (mx_zz_ge x y)
+  x `geq` y = unsafePerformIO (C.casadi_ge__3 x y)
   {-# NOINLINE geq #-}
-  x  `eq` y = unsafePerformIO (mx_zz_eq x y)
+  x  `eq` y = unsafePerformIO (C.casadi_eq__3 x y)
   {-# NOINLINE eq #-}
 
 instance Erf MX where
-  erf x = unsafePerformIO (mx_zz_erf x)
+  erf x = unsafePerformIO (C.casadi_erf__3 x)
   {-# NOINLINE erf #-}
-  erfinv x = unsafePerformIO (mx_zz_erfinv x)
+  erfinv x = unsafePerformIO (C.casadi_erfinv__3 x)
   {-# NOINLINE erfinv #-}
diff --git a/src/Casadi/MXFunction.hs b/src/Casadi/MXFunction.hs
--- a/src/Casadi/MXFunction.hs
+++ b/src/Casadi/MXFunction.hs
@@ -3,23 +3,39 @@
 module Casadi.MXFunction
        ( C.MXFunction
        , mxFunction
+       , mxFunction'
        , mxFunctionFromFunction
        ) where
 
+import qualified Data.Traversable as T
 import Data.Vector ( Vector )
+import Data.Map ( Map )
 
 import qualified Casadi.Core.Classes.Function as C
+import Casadi.Core.Classes.GenericType ( GenericType )
 import qualified Casadi.Core.Classes.MXFunction as C
 
 import Casadi.MX ( MX )
+import Casadi.GenericC ( GenericC( mkGeneric ), Opt )
 import Casadi.SharedObject ( castSharedObject )
 
 instance Show C.MXFunction where
   show x = show (castSharedObject x)
   {-# NOINLINE show #-}
 
-mxFunction :: Vector MX -> Vector MX -> IO C.MXFunction
-mxFunction = C.mxFunction__0
+mxFunction :: String -> Vector MX -> Vector MX -> Map String Opt
+              -> IO C.MXFunction
+mxFunction n x y opts0 = do
+  opts <- T.mapM mkGeneric opts0 :: IO (Map String GenericType)
+  C.mxFunction__7 n x y opts
 
+mxFunction' ::
+  String -> (Map String MX, Vector String) -> (Map String MX, Vector String)
+  -> Map String Opt
+  -> IO C.MXFunction
+mxFunction' n x y opts0 = do
+  opts <- T.mapM mkGeneric opts0 :: IO (Map String GenericType)
+  C.mxFunction__1 n x y opts
+
 mxFunctionFromFunction :: C.Function -> IO C.MXFunction
-mxFunctionFromFunction = C.mxFunction__1
+mxFunctionFromFunction = C.mxFunction__8
diff --git a/src/Casadi/Option.hs b/src/Casadi/Option.hs
--- a/src/Casadi/Option.hs
+++ b/src/Casadi/Option.hs
@@ -1,22 +1,19 @@
 {-# OPTIONS_GHC -Wall #-}
 {-# Language GADTs #-}
 
+-- todo(greg): merge this with Casadi.GenericC
 module Casadi.Option
        ( Opt(..)
        , GenericC(..)
-       , setOption
+       , GenericType
        , getOption
        ) where
 
 import Casadi.Core.Classes.OptionsFunctionality
-  ( OptionsFunctionalityClass, optionsFunctionality_setOption,
-    optionsFunctionality_hasOption, optionsFunctionality_getOption)
+  ( OptionsFunctionalityClass
+  , optionsFunctionality_hasOption, optionsFunctionality_getOption
+  )
 import Casadi.GenericC
-
-setOption :: (OptionsFunctionalityClass a, GenericC b) => a -> String -> b -> IO ()
-setOption f name val = do
-  gval <- mkGeneric val
-  optionsFunctionality_setOption f name gval
 
 getOption :: (OptionsFunctionalityClass a, GenericC b) => a -> String -> IO (Maybe b)
 getOption f name = do
diff --git a/src/Casadi/SX.hs b/src/Casadi/SX.hs
--- a/src/Casadi/SX.hs
+++ b/src/Casadi/SX.hs
@@ -21,53 +21,53 @@
   {-# NOINLINE show #-}
 
 instance Eq SX where
-  x == y = unsafePerformIO (sx_zz_isEqual__0 x y)
+  x == y = unsafePerformIO (C.casadi_isEqual__0 x y)
   {-# NOINLINE (==) #-}
 
 instance Conjugate SX where
   conjugate = id
 
 ssym :: String -> IO SX
-ssym = sx_sym__5
+ssym = sx_sym__6
 
 ssymV :: String -> Int -> IO SX
-ssymV = sx_sym__6
+ssymV = sx_sym__7
 
 ssymM :: String -> Int -> Int -> IO SX
-ssymM = sx_sym__7
+ssymM = sx_sym__8
 
 -- | @jacobian exp x@ is the jacobian of exp w.r.t. x
 sgradient :: SX -> SX -> SX
-sgradient x y = unsafePerformIO (C.gradient__1 x y)
+sgradient x y = unsafePerformIO (C.casadi_gradient__0 x y)
 {-# NOINLINE sgradient #-}
 
 -- | @jacobian exp x@ is the jacobian of exp w.r.t. x
 sjacobian :: SX -> SX -> SX
-sjacobian x y = unsafePerformIO (C.jacobian__1 x y)
+sjacobian x y = unsafePerformIO (C.casadi_jacobian__0 x y)
 {-# NOINLINE sjacobian #-}
 
 -- | @hessian exp x@ is the hessian of exp w.r.t. x
-shessian :: SX -> SX -> SX
-shessian x y = unsafePerformIO (C.hessian__3 x y)
+shessian :: SX -> SX -> SX -> SX
+shessian x y z = unsafePerformIO (C.casadi_hessian__0 x y z)
 {-# NOINLINE shessian #-}
 
 ssparsify :: SX -> SX
-ssparsify x = unsafePerformIO (sx_zz_sparsify__0 x)
+ssparsify x = unsafePerformIO (C.casadi_sparsify__0 x)
 {-# NOINLINE ssparsify #-}
 
 
 instance CMatrix SX where
-  veccat x = unsafePerformIO (sx_zz_veccat x)
+  veccat x = unsafePerformIO (C.casadi_veccat__0 x)
   {-# NOINLINE veccat #-}
   --  vertsplit = vertslice
-  vertsplit x ks = unsafePerformIO (sx_zz_vertsplit x ks)
+  vertsplit x ks = unsafePerformIO (C.casadi_vertsplit__2 x ks)
   {-# NOINLINE vertsplit #-}
-  vertcat x = unsafePerformIO (sx_zz_vertcat x)
+  vertcat x = unsafePerformIO (C.casadi_vertcat__0 x)
   {-# NOINLINE vertcat #-}
   --  horzsplit = horzslice
-  horzsplit x ks = unsafePerformIO (sx_zz_horzsplit x ks)
+  horzsplit x ks = unsafePerformIO (C.casadi_horzsplit__2 x ks)
   {-# NOINLINE horzsplit #-}
-  horzcat x = unsafePerformIO (sx_zz_horzcat x)
+  horzcat x = unsafePerformIO (C.casadi_horzcat__0 x)
   {-# NOINLINE horzcat #-}
   size1 x = unsafePerformIO (sx_size1 x)
   {-# NOINLINE size1 #-}
@@ -75,30 +75,32 @@
   {-# NOINLINE size2 #-}
   numel x = unsafePerformIO (sx_numel__1 x)
   {-# NOINLINE numel #-}
-  mm x y = unsafePerformIO (sx_zz_mtimes__1 x y)
+  mm x y = unsafePerformIO (C.casadi_mul__1 x y)
   {-# NOINLINE mm #-}
-  innerProd x y = unsafePerformIO (sx_zz_inner_prod x y)
+  innerProd x y = unsafePerformIO (C.casadi_inner_prod__0 x y)
   {-# NOINLINE innerProd #-}
   trans x = unsafePerformIO (sx_T x)
   {-# NOINLINE trans #-}
-  diag x = unsafePerformIO (sx_zz_diag x)
+  diag x = unsafePerformIO (C.casadi_diag__0 x)
   {-# NOINLINE diag #-}
   eye n = unsafePerformIO (sx_eye n)
   {-# NOINLINE eye #-}
-  ones (r,c) = unsafePerformIO (sx_ones__3 r c)
+  ones (r,c) = unsafePerformIO (sx_ones__4 r c)
   {-# NOINLINE ones #-}
-  zeros (r,c) = unsafePerformIO (sx_zeros__3 r c)
+  zeros (r,c) = unsafePerformIO (sx_zeros__4 r c)
   {-# NOINLINE zeros #-}
-  zerosSp sp = unsafePerformIO (sx_zeros__0 sp)
+  zerosSp sp = unsafePerformIO (sx_zeros__1 sp)
   {-# NOINLINE zerosSp #-}
-  solve a b = unsafePerformIO (C.solve__2 a b)
+  solve x y s m = unsafePerformIO (C.casadi_solve__1 x y s m)
   {-# NOINLINE solve #-}
+  solve' x y = unsafePerformIO (C.casadi_solve__2 x y)
+  {-# NOINLINE solve' #-}
   indexed m spx spy = unsafePerformIO $ do
     ret <- allocEmpty :: IO SX
     sx_get__3 m ret False spx spy
     return ret
   {-# NOINLINE indexed #-}
-  sparsity x = unsafePerformIO (sx_sparsityRef x)
+  sparsity x = unsafePerformIO (sx_getSparsity x)
   {-# NOINLINE sparsity #-}
   getNZ m sp = unsafePerformIO $ do
     ret <- allocEmpty :: IO SX
@@ -106,16 +108,16 @@
     return ret
   {-# NOINLINE getNZ #-}
   setNZ m y s = sx_setNZ__1 m y False s
-  triu x = unsafePerformIO (sx_zz_triu__0 x)
+  triu x = unsafePerformIO (C.casadi_triu__0 x)
   {-# NOINLINE triu #-}
-  tril x = unsafePerformIO (sx_zz_tril__0 x)
+  tril x = unsafePerformIO (C.casadi_tril__0 x)
   {-# NOINLINE tril #-}
-  triu2symm x = unsafePerformIO (sx_zz_triu2symm x)
+  triu2symm x = unsafePerformIO (C.casadi_triu2symm__0 x)
   {-# NOINLINE triu2symm #-}
-  tril2symm x = unsafePerformIO (sx_zz_tril2symm x)
+  tril2symm x = unsafePerformIO (C.casadi_tril2symm__0 x)
   {-# NOINLINE tril2symm #-}
   copy m = sx__9 m
-  densify x = unsafePerformIO (sx_zz_densify x)
+  densify x = unsafePerformIO (C.casadi_densify__0 x)
   {-# NOINLINE densify #-}
   fromDMatrix x = unsafePerformIO (sx__1 x)
   {-# NOINLINE fromDMatrix #-}
@@ -127,21 +129,21 @@
 
 
 instance Num SX where
-  (+) x y = unsafePerformIO (sx_zz_plus x y)
+  (+) x y = unsafePerformIO (C.casadi_plus__0 x y)
   {-# NOINLINE (+) #-}
-  (-) x y = unsafePerformIO (sx_zz_minus x y)
+  (-) x y = unsafePerformIO (C.casadi_minus__0 x y)
   {-# NOINLINE (-) #-}
-  (*) x y = unsafePerformIO (sx_zz_times x y)
+  (*) x y = unsafePerformIO (C.casadi_times__0 x y)
   {-# NOINLINE (*) #-}
   fromInteger x = fromDouble (fromInteger x :: Double)
   {-# NOINLINE fromInteger #-}
-  abs x = unsafePerformIO (sx_zz_abs x)
+  abs x = unsafePerformIO (C.casadi_abs__0 x)
   {-# NOINLINE abs #-}
-  signum x = unsafePerformIO (sx_zz_sign x)
+  signum x = unsafePerformIO (C.casadi_sign__0 x)
   {-# NOINLINE signum #-}
 
 instance Fractional SX where
-  (/) x y = unsafePerformIO (sx___truediv____0 x y)
+  (/) x y = unsafePerformIO (C.casadi_rdivide__0 x y)
   {-# NOINLINE (/) #-}
   fromRational x = fromDouble (fromRational x :: Double)
   {-# NOINLINE fromRational #-}
@@ -149,55 +151,55 @@
 instance Floating SX where
   pi = fromDouble (pi :: Double)
   {-# NOINLINE pi #-}
-  (**) x y = unsafePerformIO (sx_zz_power x y)
+  (**) x y = unsafePerformIO (C.casadi_power__0 x y)
   {-# NOINLINE (**) #-}
-  exp x   = unsafePerformIO (sx_zz_exp x)
+  exp x   = unsafePerformIO (C.casadi_exp__0 x)
   {-# NOINLINE exp #-}
-  log x   = unsafePerformIO (sx_zz_log x)
+  log x   = unsafePerformIO (C.casadi_log__0 x)
   {-# NOINLINE log #-}
-  sin x   = unsafePerformIO (sx_zz_sin x)
+  sin x   = unsafePerformIO (C.casadi_sin__0 x)
   {-# NOINLINE sin #-}
-  cos x   = unsafePerformIO (sx_zz_cos x)
+  cos x   = unsafePerformIO (C.casadi_cos__0 x)
   {-# NOINLINE cos #-}
-  tan x   = unsafePerformIO (sx_zz_tan x)
+  tan x   = unsafePerformIO (C.casadi_tan__0 x)
   {-# NOINLINE tan #-}
-  asin x  = unsafePerformIO (sx_zz_asin x)
+  asin x  = unsafePerformIO (C.casadi_asin__0 x)
   {-# NOINLINE asin #-}
-  atan x  = unsafePerformIO (sx_zz_atan x)
+  atan x  = unsafePerformIO (C.casadi_atan__0 x)
   {-# NOINLINE atan #-}
-  acos x  = unsafePerformIO (sx_zz_acos x)
+  acos x  = unsafePerformIO (C.casadi_acos__0 x)
   {-# NOINLINE acos #-}
-  sinh x  = unsafePerformIO (sx_zz_sinh x)
+  sinh x  = unsafePerformIO (C.casadi_sinh__0 x)
   {-# NOINLINE sinh #-}
-  cosh x  = unsafePerformIO (sx_zz_cosh x)
+  cosh x  = unsafePerformIO (C.casadi_cosh__0 x)
   {-# NOINLINE cosh #-}
-  tanh x  = unsafePerformIO (sx_zz_tanh x)
+  tanh x  = unsafePerformIO (C.casadi_tanh__0 x)
   {-# NOINLINE tanh #-}
-  asinh x = unsafePerformIO (sx_zz_asinh x)
+  asinh x = unsafePerformIO (C.casadi_asinh__0 x)
   {-# NOINLINE asinh #-}
-  atanh x = unsafePerformIO (sx_zz_atanh x)
+  atanh x = unsafePerformIO (C.casadi_atanh__0 x)
   {-# NOINLINE atanh #-}
-  acosh x = unsafePerformIO (sx_zz_acosh x)
+  acosh x = unsafePerformIO (C.casadi_acosh__0 x)
   {-# NOINLINE acosh #-}
 
 instance Fmod SX where
-  fmod x y = unsafePerformIO (sx_zz_mod x y)
+  fmod x y = unsafePerformIO (C.casadi_mod__0 x y)
   {-# NOINLINE fmod #-}
 
 instance ArcTan2 SX where
-  arctan2 x y = unsafePerformIO (sx_zz_atan2 x y)
+  arctan2 x y = unsafePerformIO (C.casadi_atan2__0 x y)
   {-# NOINLINE arctan2 #-}
 
 instance SymOrd SX where
-  x `leq` y = unsafePerformIO (sx_zz_le x y)
+  x `leq` y = unsafePerformIO (C.casadi_le__0 x y)
   {-# NOINLINE leq #-}
-  x `geq` y = unsafePerformIO (sx_zz_ge x y)
+  x `geq` y = unsafePerformIO (C.casadi_ge__0 x y)
   {-# NOINLINE geq #-}
-  x  `eq` y = unsafePerformIO (sx_zz_eq x y)
+  x  `eq` y = unsafePerformIO (C.casadi_eq__0 x y)
   {-# NOINLINE eq #-}
 
 instance Erf SX where
-  erf x = unsafePerformIO (sx_zz_erf x)
+  erf x = unsafePerformIO (C.casadi_erf__0 x)
   {-# NOINLINE erf #-}
-  erfinv x = unsafePerformIO (sx_zz_erfinv x)
+  erfinv x = unsafePerformIO (C.casadi_erfinv__0 x)
   {-# NOINLINE erfinv #-}
diff --git a/src/Casadi/SXFunction.hs b/src/Casadi/SXFunction.hs
--- a/src/Casadi/SXFunction.hs
+++ b/src/Casadi/SXFunction.hs
@@ -3,28 +3,44 @@
 module Casadi.SXFunction
        ( C.SXFunction
        , sxFunction
+       , sxFunction'
        , sxFunctionFromFunction
        , sxFunctionFromMXFunction
        ) where
 
+import qualified Data.Traversable as T
 import Data.Vector ( Vector )
+import Data.Map ( Map )
 
 import qualified Casadi.Core.Classes.Function as C
+import Casadi.Core.Classes.GenericType ( GenericType )
 import qualified Casadi.Core.Classes.SXFunction as C
 import qualified Casadi.Core.Classes.MXFunction as C
 
-import Casadi.SX ( SX )
+import Casadi.GenericC ( GenericC( mkGeneric ), Opt )
 import Casadi.SharedObject ( castSharedObject )
+import Casadi.SX ( SX )
 
 instance Show C.SXFunction where
   show x = show (castSharedObject x)
   {-# NOINLINE show #-}
 
-sxFunction :: Vector SX -> Vector SX -> IO C.SXFunction
-sxFunction = C.sxFunction__0
+sxFunction :: String -> Vector SX -> Vector SX -> Map String Opt
+              -> IO C.SXFunction
+sxFunction n x y opts0 = do
+  opts <- T.mapM mkGeneric opts0 :: IO (Map String GenericType)
+  C.sxFunction__7 n x y opts
 
+sxFunction' ::
+  String -> (Map String SX, Vector String) -> (Map String SX, Vector String)
+  -> Map String Opt
+  -> IO C.SXFunction
+sxFunction' n x y opts0 = do
+  opts <- T.mapM mkGeneric opts0 :: IO (Map String GenericType)
+  C.sxFunction__1 n x y opts
+
 sxFunctionFromFunction :: C.Function -> IO C.SXFunction
-sxFunctionFromFunction = C.sxFunction__1
+sxFunctionFromFunction = C.sxFunction__8
 
 sxFunctionFromMXFunction :: C.MXFunction -> IO C.SXFunction
-sxFunctionFromMXFunction = C.sxFunction__2
+sxFunctionFromMXFunction = C.sxFunction__9
diff --git a/src/Casadi/SharedObject.hs b/src/Casadi/SharedObject.hs
--- a/src/Casadi/SharedObject.hs
+++ b/src/Casadi/SharedObject.hs
@@ -1,16 +1,12 @@
 {-# OPTIONS_GHC -Wall -fno-warn-orphans -fno-cse #-}
 
 module Casadi.SharedObject
-       ( soInit
-       , C.castSharedObject
+       ( C.castSharedObject
        ) where
 
 import System.IO.Unsafe ( unsafePerformIO )
 
 import qualified Casadi.Core.Classes.SharedObject as C
-
-soInit :: C.SharedObjectClass a => a -> IO ()
-soInit = C.sharedObject_init__0
 
 instance Show C.SharedObject where
   show x = unsafePerformIO (C.sharedObject_getDescription x)
diff --git a/src/Casadi/Slice.hs b/src/Casadi/Slice.hs
--- a/src/Casadi/Slice.hs
+++ b/src/Casadi/Slice.hs
@@ -19,5 +19,5 @@
 
 -- | Slice()
 slice' :: Slice
-slice' = unsafePerformIO slice__6
+slice' = unsafePerformIO slice__7
 {-# NOINLINE slice' #-}
diff --git a/src/Casadi/Sparsity.hs b/src/Casadi/Sparsity.hs
--- a/src/Casadi/Sparsity.hs
+++ b/src/Casadi/Sparsity.hs
@@ -71,7 +71,7 @@
 {-# NOINLINE sparse #-}
 
 dense :: Int -> Int -> Sparsity
-dense nr nc = unsafePerformIO (sparsity_dense__1 nr nc)
+dense nr nc = unsafePerformIO (sparsity_dense__2 nr nc)
 {-# NOINLINE dense #-}
 
 compress :: Sparsity -> V.Vector Int
