diff --git a/casadi-bindings-internal.cabal b/casadi-bindings-internal.cabal
--- a/casadi-bindings-internal.cabal
+++ b/casadi-bindings-internal.cabal
@@ -1,56 +1,37 @@
 name:                casadi-bindings-internal
-version:             0.1.1
+version:             0.1.6.1
 license:             LGPL-3
 license-file:        LICENSE
 category:            Numerical, Math
-copyright:           (c) 2013-2014 Greg Horn
+copyright:           (c) 2013-2018 Greg Horn
 author:              Greg Horn
 maintainer:          gregmainland@gmail.com
 build-type:          Simple
 cabal-version:       >=1.10
 synopsis:            low level bindings to CasADi
-description:
-    Debian/Ubuntu instructions
-    .
-    Version numbers correspond to the C++ library version numbers except the very last number which may indicate breaking changes.
-    .
-    This only works on Debian/Ubuntu at the moment (sorry).
-    .
-    Install libcasadi from a .deb package here: https://github.com/casadi/casadi/releases, I use libcasadi-shared. (Get the version corresponding to the current casadi-bindings version, for example casadi-bindings-1.9.0.0 is libcasadi 1.9.0)
-    .
-    Then,
-    - `cabal update; cabal install casadi-bindings`
-    .
-    Temporary note: there is something wrong with casadi and ipopt related to http://list.coin-or.org/pipermail/ipopt/2014-April/003670.html, and https://github.com/casadi/casadi/issues/1075. At the moment this .cabal package works for me as is, but YMMV
+description:         see <http://hackage.haskell.org/package/casadi-bindings http://hackage.haskell.org/package/casadi-bindings> for all instructions
 homepage:            http://github.com/ghorn/casadi-bindings
 
 
-extra-tmp-files:     Casadi/Callback_stub.h
-
 library
-  build-depends:       base >=4.6 && <5, vector >=0.10
-
-  default-language:    Haskell2010
-  hs-source-dirs: src
+  build-depends:     base >=4.6 && <5, vector >=0.10, containers
 
-  extra-libraries:  stdc++
+  default-language:  Haskell2010
+  hs-source-dirs:    src
 
-  pkgconfig-depends: casadi_core
+  extra-libraries:   stdc++ casadi
 
-  ghc-prof-options: -O2 -prof -fprof-auto -fprof-cafs -rtsopts
-  ghc-options: -O2
-  cc-options: -Wall -Wno-delete-non-virtual-dtor
+  ghc-prof-options: -O2
+  ghc-options:      -O2
+  cc-options:       -Wall -Wno-delete-non-virtual-dtor -Wno-sign-compare -std=c++11
 
   C-sources:        cbits/hs_tools.cpp
-                    cbits/callback.cpp
 
   exposed-modules:  Casadi.Internal.Marshal
                     Casadi.Internal.MarshalTypes
                     Casadi.Internal.WrapReturn
                     Casadi.Internal.CppHelpers
                     Casadi.Internal.CToolsImports
-                    Casadi.Internal.CToolsInstances
-                    Casadi.Internal.Callback
                     Casadi.Internal.FormatException
 
 
diff --git a/cbits/callback.cpp b/cbits/callback.cpp
deleted file mode 100644
--- a/cbits/callback.cpp
+++ /dev/null
@@ -1,56 +0,0 @@
-#include <iostream>
-#include "casadi/core/core.hpp"
-#include "casadi/core/function/custom_function.hpp"
-#include "casadi/core/functor_internal.hpp"
-
-#include "HsFFI.h"
-
-using namespace std;
-using namespace casadi;
-
-extern "C" {
-typedef int (*hs_callback_t)(Function &f);
-}
-
-namespace casadi {
-  class FunctorHaskellInternal {
-    public:
-      FunctorHaskellInternal(hs_callback_t hscb)
-      {
-          hs_callback = hscb;
-      }
-      ~FunctorHaskellInternal() {
-          // free the haskell FunPtr
-          hs_free_fun_ptr(HsFunPtr(hs_callback));
-      }
-    protected:
-      hs_callback_t hs_callback;
-  };
-
-  class CallbackHaskellInternal : public CallbackInternal, FunctorHaskellInternal {
-    friend class CallbackHaskell;
-
-      CallbackHaskellInternal(hs_callback_t hscb) : FunctorHaskellInternal(hscb) {}
-    virtual int call(Function& fcn, void* user_data);
-    virtual CallbackHaskellInternal* clone() const { return new CallbackHaskellInternal(hs_callback); }
-  };
-
-  class CallbackHaskell : public Callback {
-    public:
-      CallbackHaskell(hs_callback_t hscb) { assignNode(new CallbackHaskellInternal(hscb)); }
-  };
-
-  int CallbackHaskellInternal::call(Function& fcn, void* user_data) {
-      return hs_callback(fcn);
-  }
-}
-
-extern "C" CallbackHaskell * new_callback_haskell(hs_callback_t hs_callback);
-CallbackHaskell * new_callback_haskell(hs_callback_t hs_callback){
-    return new CallbackHaskell(hs_callback);
-}
-
-extern "C" void delete_callback_haskell(casadi::CallbackHaskell* obj);
-void delete_callback_haskell(casadi::CallbackHaskell* obj){
-    delete obj;
-}
diff --git a/cbits/hs_tools.cpp b/cbits/hs_tools.cpp
--- a/cbits/hs_tools.cpp
+++ b/cbits/hs_tools.cpp
@@ -1,5 +1,6 @@
 #include <iostream>
 #include <vector>
+#include <map>
 #include "string.h"
 
 using namespace std;
@@ -23,7 +24,87 @@
     delete x;
 }
 
+////////////////// std::pair /////////////////
+extern "C" std::pair<void*,void*> * hs_new_stdpair(void * x, void * y);
+std::pair<void*,void*> * hs_new_stdpair(void * x, void * y) {
+    return new std::pair<void*,void*>(x, y);
+}
+extern "C" void * hs_stdpair_fst(std::pair<void*,void*> * stdpair);
+void * hs_stdpair_fst(std::pair<void*,void*> * stdpair) {
+    return stdpair->first;
+}
+extern "C" void * hs_stdpair_snd(std::pair<void*,void*> * stdpair);
+void * hs_stdpair_snd(std::pair<void*,void*> * stdpair) {
+    return stdpair->second;
+}
+extern "C" void hs_delete_stdpair(std::pair<void*,void*> * pair);
+void hs_delete_stdpair(std::pair<void*,void*> * pair){
+    delete pair;
+}
 
+extern "C" std::pair<long long,long long> * hs_new_stdpair_long_long(long long x, long long y);
+std::pair<long long,long long> * hs_new_stdpair_long_long(long long x, long long y) {
+    return new std::pair<long long,long long>(x, y);
+}
+extern "C" long long hs_stdpair_fst_long_long(std::pair<long long,long long> * stdpair);
+long long hs_stdpair_fst_long_long(std::pair<long long,long long> * stdpair) {
+    return stdpair->first;
+}
+extern "C" long long hs_stdpair_snd_long_long(std::pair<long long,long long> * stdpair);
+long long hs_stdpair_snd_long_long(std::pair<long long,long long> * stdpair) {
+    return stdpair->second;
+}
+extern "C" void hs_delete_stdpair_long_long(std::pair<long long,long long> * pair);
+void hs_delete_stdpair_long_long(std::pair<long long,long long> * pair){
+    delete pair;
+}
+
+
+////////////////// std::map /////////////////
+extern "C" std::map<string,void*> * hs_new_dict(std::vector<std::string*> * keys,
+                                                std::vector<void*> * vals);
+std::map<string,void*> * hs_new_dict(std::vector<std::string*> * keys, std::vector<void*> * vals) {
+    std::map<std::string,void*> * ret = new std::map<std::string,void*>;
+    for (int k = 0; k < keys->size(); k++) {
+        std::string key = *((*keys)[k]);
+        void * val = (*vals)[k];
+        std::pair<std::string, void*> keyVal(key, val);
+        ret->insert(keyVal);
+    }
+    return ret;
+}
+
+extern "C" int hs_dict_size(std::map<std::string, void*> * map);
+int hs_dict_size(std::map<std::string, void*> * map) {
+    return map->size();
+}
+
+extern "C" void hs_dict_copy(std::map<std::string, void*> * map,
+                             std::string * keys[],
+                             void * vals[]);
+void hs_dict_copy(std::map<std::string, void*> * map,
+                  std::string * keys[],
+                  void * vals[]) {
+    int k = 0;
+    for(std::map<std::string, void*>::iterator it = map->begin(); it != map->end(); it++) {
+        std::string * key = new std::string(it->first);
+        void * val = it->second;
+        keys[k] = key;
+        vals[k] = val;
+        k++;
+    }
+}
+
+extern "C" void * hs_lookup_dict(std::map<std::string, void*> * map, std::string* key);
+void * hs_lookup_dict(std::map<std::string, void*> * map, std::string* key) {
+    return map->at(*key);
+}
+
+extern "C" void hs_delete_dict(std::map<std::string,void*> *);
+void hs_delete_dict(std::map<std::string,void*> * dict) {
+    delete dict;
+}
+
 ////////////////////////// copying vectors to arrays /////////////////////
 template <typename T>
 void hs_copy_vec_T(vector<T> * vec, T outputs[]){
@@ -52,6 +133,8 @@
     int hs_size_vec_##name(vector<type> * vec){ return vec->size(); }
 
 WRITE_STUFF(int,int)
+typedef long long longlong;
+WRITE_STUFF(llong,longlong)
 WRITE_STUFF(voidp, void*)
 WRITE_STUFF(uchar, unsigned char)
 WRITE_STUFF(double, double)
diff --git a/src/Casadi/Internal/CToolsImports.hs b/src/Casadi/Internal/CToolsImports.hs
--- a/src/Casadi/Internal/CToolsImports.hs
+++ b/src/Casadi/Internal/CToolsImports.hs
@@ -8,6 +8,41 @@
 
 import Casadi.Internal.MarshalTypes
 
+--------------------------- stdpair -----------------------------------
+foreign import ccall unsafe "hs_new_stdpair" c_newStdPair
+  :: Ptr a -> Ptr b -> IO (Ptr (StdPair (Ptr a) (Ptr b)))
+foreign import ccall unsafe "hs_stdpair_fst" c_stdPairFst
+  :: Ptr (StdPair (Ptr a) (Ptr b)) -> IO (Ptr a)
+foreign import ccall unsafe "hs_stdpair_snd" c_stdPairSnd
+  :: Ptr (StdPair (Ptr a) (Ptr b)) -> IO (Ptr b)
+foreign import ccall unsafe "hs_delete_stdpair" c_deleteStdPair
+  :: Ptr (StdPair (Ptr a) (Ptr b)) -> IO ()
+
+foreign import ccall unsafe "hs_new_stdpair_long_long" c_newStdPairLLong
+  :: CLLong -> CLLong -> IO (Ptr (StdPair CLLong CLLong))
+foreign import ccall unsafe "hs_stdpair_fst_long_long" c_stdPairFstLLong
+  :: Ptr (StdPair CLLong CLLong) -> IO CLLong
+foreign import ccall unsafe "hs_stdpair_snd_long_long" c_stdPairSndLLong
+  :: Ptr (StdPair CLLong CLLong) -> IO CLLong
+foreign import ccall unsafe "hs_delete_stdpair_long_long" c_deleteStdPairLLong
+  :: Ptr (StdPair CLLong CLLong) -> IO ()
+
+--------------------------- stdmap -----------------------------------
+foreign import ccall unsafe "hs_new_dict" c_newDict
+  :: Ptr (StdVec (Ptr StdString)) -> Ptr (StdVec (Ptr a)) -> IO (Ptr (StdMap StdString (Ptr a)))
+
+foreign import ccall unsafe "hs_dict_size" c_dictSize
+  :: Ptr (StdMap StdString (Ptr a)) -> IO CInt
+
+foreign import ccall unsafe "hs_lookup_dict" c_lookupDict
+  :: Ptr (StdMap StdString (Ptr a)) -> Ptr StdString -> IO (Ptr a)
+
+foreign import ccall unsafe "hs_dict_copy" c_dictCopy
+  :: Ptr (StdMap StdString (Ptr a)) -> Ptr (Ptr StdString) -> Ptr (Ptr a) -> IO ()
+
+foreign import ccall unsafe "hs_delete_dict" c_deleteDict
+  :: Ptr (StdMap StdString (Ptr a)) -> IO ()
+
 --------------------------- ("int","CInt",Nothing,["Int","Bool"]) -----------------------------------
 foreign import ccall unsafe "hs_new_vec_int" c_newVecCInt
   :: Ptr CInt -> CInt -> IO (Ptr (StdVec CInt))
@@ -17,6 +52,16 @@
   :: Ptr (StdVec CInt) -> Ptr CInt -> IO ()
 foreign import ccall unsafe "hs_size_vec_int" c_sizeVecCInt
   :: Ptr (StdVec CInt) -> IO CInt
+
+
+foreign import ccall unsafe "hs_new_vec_llong" c_newVecLLong
+  :: Ptr CLLong -> CInt -> IO (Ptr (StdVec CLLong))
+foreign import ccall unsafe "hs_delete_vec_llong" c_deleteVecLLong
+  :: Ptr (StdVec CLLong) -> IO ()
+foreign import ccall unsafe "hs_copy_vec_llong" c_copyVecCLLong
+  :: Ptr (StdVec CLLong) -> Ptr CLLong -> IO ()
+foreign import ccall unsafe "hs_size_vec_llong" c_sizeVecCLLong
+  :: Ptr (StdVec CLLong) -> IO CInt
 
 --------------------------- ("voidp","VoidP",Just "(Ptr a)",[]) -----------------------------------
 foreign import ccall unsafe "hs_new_vec_voidp" c_newVecVoidP
diff --git a/src/Casadi/Internal/CToolsInstances.hs b/src/Casadi/Internal/CToolsInstances.hs
deleted file mode 100644
--- a/src/Casadi/Internal/CToolsInstances.hs
+++ /dev/null
@@ -1,43 +0,0 @@
-{-# OPTIONS_GHC -Wall -fno-warn-orphans #-}
-{-# Language FlexibleInstances #-}
-{-# Language MultiParamTypeClasses #-}
-
-module Casadi.Internal.CToolsInstances where
-
-import Foreign.C.Types
-import Foreign.Ptr ( Ptr )
-import qualified Data.Vector as V
-
-import Casadi.Internal.MarshalTypes
-import Casadi.Internal.Marshal
-import Casadi.Internal.CToolsImports
-
-
--- ("int","CInt",Nothing,["Int","Bool"])
-instance Marshal (V.Vector CInt) (Ptr (StdVec CInt)) where
-  marshal = newStorableVec c_newVecCInt
-  marshalFree = const c_deleteVecCInt
-instance Marshal (V.Vector Int) (Ptr (StdVec CInt)) where
-  marshal = newStorableVec c_newVecCInt . (V.map hsToC)
-  marshalFree = const c_deleteVecCInt
-instance Marshal (V.Vector Bool) (Ptr (StdVec CInt)) where
-  marshal = newStorableVec c_newVecCInt . (V.map hsToC)
-  marshalFree = const c_deleteVecCInt
-
--- ("voidp","VoidP",Just "(Ptr a)",[])
-instance Marshal (V.Vector (Ptr a)) (Ptr (StdVec (Ptr a))) where
-  marshal = newStorableVec c_newVecVoidP
-  marshalFree = const c_deleteVecVoidP
-
--- ("uchar","CUChar",Nothing,[])
-instance Marshal (V.Vector CUChar) (Ptr (StdVec CUChar)) where
-  marshal = newStorableVec c_newVecCUChar
-  marshalFree = const c_deleteVecCUChar
-
--- ("double","CDouble",Nothing,["Double"])
-instance Marshal (V.Vector CDouble) (Ptr (StdVec CDouble)) where
-  marshal = newStorableVec c_newVecCDouble
-  marshalFree = const c_deleteVecCDouble
-instance Marshal (V.Vector Double) (Ptr (StdVec CDouble)) where
-  marshal = newStorableVec c_newVecCDouble . (V.map hsToC)
-  marshalFree = const c_deleteVecCDouble
diff --git a/src/Casadi/Internal/Callback.hs b/src/Casadi/Internal/Callback.hs
deleted file mode 100644
--- a/src/Casadi/Internal/Callback.hs
+++ /dev/null
@@ -1,23 +0,0 @@
-{-# OPTIONS_GHC -Wall #-}
-{-# Language ScopedTypeVariables #-}
-{-# Language FlexibleContexts #-}
-
-module Casadi.Internal.Callback
-       ( c_newCallbackHaskell
-       , mkCallback
-       ) where
-
-
-import Foreign.C.Types
-import Foreign.Ptr ( Ptr, FunPtr )
---import Foreign.ForeignPtr ( ForeignPtr, newForeignPtr_ )
-
---import Casadi.Symbolic.Data
---import Casadi.Internal.Marshal ( withMarshal )
---import Casadi.Internal.WrapReturn ( WrapReturn(..) )
-
-type CasadiCallback' function' = Ptr function' -> IO CInt
-foreign import ccall "wrapper" mkCallback :: CasadiCallback' function' -> IO (FunPtr (CasadiCallback' function'))
-
-foreign import ccall safe "new_callback_haskell" c_newCallbackHaskell
-  :: FunPtr (CasadiCallback' function') -> IO (Ptr callback')
diff --git a/src/Casadi/Internal/Marshal.hs b/src/Casadi/Internal/Marshal.hs
--- a/src/Casadi/Internal/Marshal.hs
+++ b/src/Casadi/Internal/Marshal.hs
@@ -3,6 +3,7 @@
 {-# Language MultiParamTypeClasses #-}
 {-# Language FlexibleInstances #-}
 {-# Language FlexibleContexts #-}
+{-# Language InstanceSigs #-}
 
 module Casadi.Internal.Marshal
        ( Marshal(..)
@@ -14,15 +15,17 @@
 
 import Control.Monad ( when )
 import qualified Data.Vector as V
+import qualified Data.Map as M
 import Foreign.C.Types
 import Foreign.C.String ( withCString )
 import Foreign.Ptr ( Ptr )
 import Foreign.Marshal ( withArrayLen )
 import Foreign.Storable ( Storable )
 
-import Casadi.Internal.CToolsImports ( c_deleteVecVoidP )
+import Casadi.Internal.CToolsImports
+--import Casadi.Internal.CToolsImports ( c_deleteVecVoidP )
 import Casadi.Internal.CppHelpers ( newStdVec, readStdVec, c_newStdString, c_deleteStdString )
-import Casadi.Internal.MarshalTypes ( StdVec, StdString, StdPair )
+import Casadi.Internal.MarshalTypes ( StdMap, StdPair, StdVec, StdString )
 
 class Marshal a b where
   marshal :: a -> IO b
@@ -43,6 +46,8 @@
   hsToC = fromIntegral -- really should check min/max bounds here
 instance HsToC Int CLong where
   hsToC = fromIntegral
+instance HsToC Int CLLong where
+  hsToC = fromIntegral
 instance HsToC Bool CInt where
   hsToC False = 0
   hsToC True = 1
@@ -57,6 +62,8 @@
   marshal = return . hsToC
 instance Marshal Int CLong where
   marshal = return . hsToC
+instance Marshal Int CLLong where
+  marshal = return . hsToC
 instance Marshal Bool CInt where
   marshal = return . hsToC
 instance Marshal Double CDouble where
@@ -65,6 +72,100 @@
   marshal = return . hsToC
 instance Marshal CSize CSize where
   marshal = return . hsToC
+
+-- ("int","CInt",Nothing,["Int","Bool"])
+instance Marshal (V.Vector CInt) (Ptr (StdVec CInt)) where
+  marshal = newStorableVec c_newVecCInt
+  marshalFree = const c_deleteVecCInt
+instance Marshal (V.Vector Int) (Ptr (StdVec CInt)) where
+  marshal = newStorableVec c_newVecCInt . (V.map hsToC)
+  marshalFree = const c_deleteVecCInt
+instance Marshal (V.Vector Int) (Ptr (StdVec CLLong)) where
+  marshal = newStorableVec c_newVecLLong . V.map hsToC
+  marshalFree = const c_deleteVecLLong
+instance Marshal (V.Vector Bool) (Ptr (StdVec CInt)) where
+  marshal = newStorableVec c_newVecCInt . (V.map hsToC)
+  marshalFree = const c_deleteVecCInt
+
+-- ("voidp","VoidP",Just "(Ptr a)",[])
+instance Marshal (V.Vector (Ptr a)) (Ptr (StdVec (Ptr a))) where
+  marshal = newStorableVec c_newVecVoidP
+  marshalFree = const c_deleteVecVoidP
+
+-- ("uchar","CUChar",Nothing,[])
+instance Marshal (V.Vector CUChar) (Ptr (StdVec CUChar)) where
+  marshal = newStorableVec c_newVecCUChar
+  marshalFree = const c_deleteVecCUChar
+
+-- ("double","CDouble",Nothing,["Double"])
+instance Marshal (V.Vector CDouble) (Ptr (StdVec CDouble)) where
+  marshal = newStorableVec c_newVecCDouble
+  marshalFree = const c_deleteVecCDouble
+instance Marshal (V.Vector Double) (Ptr (StdVec CDouble)) where
+  marshal = newStorableVec c_newVecCDouble . (V.map hsToC)
+  marshalFree = const c_deleteVecCDouble
+
+-- stdpair
+instance (Marshal a (Ptr pa), Marshal b (Ptr pb))
+         => Marshal (a, b) (Ptr (StdPair (Ptr pa) (Ptr pb))) where
+  marshal (x,y) = do
+    px <- marshal x
+    py <- marshal y
+    c_newStdPair px py
+  marshalFree (x,y) stdpair = do
+    px <- c_stdPairFst stdpair
+    py <- c_stdPairSnd stdpair
+    marshalFree x px
+    marshalFree y py
+    c_deleteStdPair stdpair
+
+-- stdpair
+instance (Marshal a CLLong, Marshal b CLLong)
+         => Marshal (a, b) (Ptr (StdPair CLLong CLLong)) where
+  marshal (x,y) = do
+    px <- marshal x
+    py <- marshal y
+    c_newStdPairLLong px py
+  marshalFree (x,y) stdpair = do
+    cx <- c_stdPairFstLLong stdpair
+    cy <- c_stdPairSndLLong stdpair
+    marshalFree x cx
+    marshalFree y cy
+    c_deleteStdPairLLong stdpair
+
+-- stdmap
+instance (Marshal a (Ptr pa))
+         => Marshal (M.Map String a) (Ptr (StdMap StdString (Ptr pa))) where
+  marshal m = do
+    let (keys, vals) = unzip (M.toAscList m)
+        vecKeys = V.fromList keys
+    vecKeyPtrs <- V.mapM marshal vecKeys :: IO (V.Vector (Ptr StdString))
+    vecValPtrs <- V.mapM marshal (V.fromList vals) :: IO (V.Vector (Ptr pa))
+
+    stdVecKeys <- newStdVec vecKeyPtrs
+                  :: IO (Ptr (StdVec (Ptr StdString)))
+    stdVecVals <- newStdVec vecValPtrs
+                  :: IO (Ptr (StdVec (Ptr pa)))
+
+    dict <- c_newDict stdVecKeys stdVecVals
+
+    c_deleteVecVoidP stdVecKeys
+    c_deleteVecVoidP stdVecVals
+
+    V.zipWithM_ marshalFree vecKeys vecKeyPtrs
+
+    return dict
+
+  marshalFree m dict = do
+    let (keys, vals) = unzip (M.toAscList m)
+        vecKeys = V.fromList keys
+    vecKeyPtrs <- V.mapM marshal vecKeys :: IO (V.Vector (Ptr StdString))
+    vecVals <- V.mapM (c_lookupDict dict) vecKeyPtrs :: IO (V.Vector (Ptr pa))
+
+    V.zipWithM_ marshalFree vecKeys vecKeyPtrs
+    V.zipWithM_ marshalFree (V.fromList vals) vecVals
+    c_deleteDict dict
+
 
 instance Marshal String (Ptr StdString) where
   marshal str = newStdString str
diff --git a/src/Casadi/Internal/MarshalTypes.hs b/src/Casadi/Internal/MarshalTypes.hs
--- a/src/Casadi/Internal/MarshalTypes.hs
+++ b/src/Casadi/Internal/MarshalTypes.hs
@@ -5,9 +5,11 @@
        , StdString
        , StdOstream
        , StdPair
+       , StdMap
        ) where
 
 data StdVec a
 data StdPair a b
+data StdMap a b
 data StdString
 data StdOstream
diff --git a/src/Casadi/Internal/WrapReturn.hs b/src/Casadi/Internal/WrapReturn.hs
--- a/src/Casadi/Internal/WrapReturn.hs
+++ b/src/Casadi/Internal/WrapReturn.hs
@@ -8,6 +8,7 @@
        ( WrapReturn(..)
        ) where
 
+import qualified Data.Map as M
 import qualified Data.Vector as V
 import Foreign.C.Types
 import Foreign.C.String
@@ -15,7 +16,7 @@
 import Foreign.Storable ( Storable )
 import Foreign.Marshal ( mallocArray, free, peekArray )
 
-import Casadi.Internal.MarshalTypes ( StdVec, StdString )
+import Casadi.Internal.MarshalTypes ( StdMap, StdVec, StdString, StdPair )
 
 import Casadi.Internal.CppHelpers ( readStdVec, c_lengthStdString, c_copyStdString, c_deleteStdString )
 import Casadi.Internal.CToolsImports
@@ -30,11 +31,54 @@
   wrapReturn = return . realToFrac
 instance WrapReturn CLong Int where
   wrapReturn = return . fromIntegral
+instance WrapReturn CLLong Int where
+  wrapReturn = return . fromIntegral
 instance WrapReturn CInt Bool where
   wrapReturn 0 = return False
   wrapReturn _ = return True
 
+instance WrapReturn (Ptr a) b => WrapReturn (Ptr (StdMap StdString (Ptr a))) (M.Map String b) where
+  wrapReturn stdMap = do
+    msize <- fmap fromIntegral (c_dictSize stdMap)
+    keyArray <- mallocArray msize :: IO (Ptr (Ptr StdString))
+    valArray <- mallocArray msize :: IO (Ptr (Ptr a))
 
+    c_dictCopy stdMap keyArray valArray
+    c_deleteDict stdMap
+
+    keys0 <- peekArray msize keyArray :: IO [Ptr StdString]
+    vals0 <- peekArray msize valArray :: IO [Ptr a]
+
+    free keyArray
+    free valArray
+
+    keys <- mapM wrapReturn keys0 :: IO [String]
+    vals <- mapM wrapReturn vals0 :: IO [b]
+
+    return $ M.fromList (zip keys vals)
+
+
+instance (WrapReturn (Ptr pa) a, WrapReturn (Ptr pb) b)
+         => WrapReturn (Ptr (StdPair (Ptr pa) (Ptr pb))) (a, b) where
+  wrapReturn stdPair = do
+    px <- c_stdPairFst stdPair
+    py <- c_stdPairSnd stdPair
+    x <- wrapReturn px
+    y <- wrapReturn py
+    c_deleteStdPair stdPair
+    return (x, y)
+
+instance (WrapReturn CLLong a, WrapReturn CLLong b)
+         => WrapReturn (Ptr (StdPair CLLong CLLong)) (a, b) where
+  wrapReturn stdPair = do
+    px <- c_stdPairFstLLong stdPair
+    py <- c_stdPairSndLLong stdPair
+    x <- wrapReturn px
+    y <- wrapReturn py
+    c_deleteStdPairLLong stdPair
+    return (x, y)
+
+
 instance WrapReturn (Ptr a) b => WrapReturn (Ptr (StdVec (Ptr a))) (V.Vector b) where
   wrapReturn cppvec = do
     vec <- readStdVec cppvec >>= (V.mapM wrapReturn) :: IO (V.Vector b)
@@ -67,7 +111,13 @@
   vecDel vecPtr
   fmap V.fromList (mapM cToHs ret)
 
+instance WrapReturn (Ptr (StdVec CLLong)) (V.Vector Int) where
+  wrapReturn = wrapReturnVec c_sizeVecCLLong c_copyVecCLLong c_deleteVecLLong wrapReturn
+
 instance WrapReturn (Ptr (StdVec CInt)) (V.Vector Int) where
+  wrapReturn = wrapReturnVec c_sizeVecCInt c_copyVecCInt c_deleteVecCInt wrapReturn
+
+instance WrapReturn (Ptr (StdVec CInt)) (V.Vector Bool) where
   wrapReturn = wrapReturnVec c_sizeVecCInt c_copyVecCInt c_deleteVecCInt wrapReturn
 
 instance WrapReturn (Ptr (StdVec CDouble)) (V.Vector Double) where
