diff --git a/pyopencl/__init__.py b/pyopencl/__init__.py
index e5a20a50090afe9cf1208490017c1325f7d5e41e..b5c5687535adb65790810d76cda4ca12c0af60f4 100644
--- a/pyopencl/__init__.py
+++ b/pyopencl/__init__.py
@@ -152,17 +152,14 @@ class Program(object):
 
         if os.environ.get("PYOPENCL_NO_CACHE") and self._prg is None:
             self._prg = _cl._Program(self._context, self._source)
-
         if self._prg is not None:
             # uncached
-
             self._build_and_catch_errors(
                     lambda: self._prg.build(" ".join(options), devices),
                     options=options)
 
         else:
             # cached
-
             from pyopencl.cache import create_built_program_from_source_cached
             self._prg = self._build_and_catch_errors(
                     lambda: create_built_program_from_source_cached(
diff --git a/pyopencl/cache.py b/pyopencl/cache.py
index 10ea16e03053df9292619bbdea68ccabffb858fb..349a8ec343d9c900434b841280b0e7f496f7eaa1 100644
--- a/pyopencl/cache.py
+++ b/pyopencl/cache.py
@@ -248,7 +248,6 @@ def get_cache_key(device, options, src):
 def retrieve_from_cache(cache_dir, cache_key):
     class _InvalidInfoFile(RuntimeError):
         pass
-
     from os.path import join, isdir
     module_cache_dir = join(cache_dir, cache_key)
     if not isdir(module_cache_dir):
@@ -390,7 +389,6 @@ def _create_built_program_from_source_cached(ctx, src, options, devices, cache_d
 
     result = None
     already_built = False
-
     if to_be_built_indices:
         # defeat implementation caches:
         from uuid import uuid4
@@ -434,7 +432,6 @@ def _create_built_program_from_source_cached(ctx, src, options, devices, cache_d
                     cache_key = cache_keys[i]
                     device = devices[i]
                     binary = binaries[i]
-
                     mod_cache_dir_m = ModuleCacheDirManager(cleanup_m,
                             join(cache_dir, cache_key))
                     info_path = mod_cache_dir_m.sub("info")
@@ -478,7 +475,6 @@ def create_built_program_from_source_cached(ctx, src, options=[], devices=None,
             already_built = False
 
     except Exception, e:
-        raise
         from pyopencl import Error
         if (isinstance(e, Error)
                 and e.code == _cl.status_code.BUILD_PROGRAM_FAILURE):
diff --git a/pyopencl/cffi_cl.py b/pyopencl/cffi_cl.py
index 451c71e515cfb3b8c9df109366dcbe8d30587b21..5f8a3cd41ff828359f77d616808189f0f0581559 100644
--- a/pyopencl/cffi_cl.py
+++ b/pyopencl/cffi_cl.py
@@ -302,10 +302,18 @@ class _Program(_Common):
             
         ptr_program = _ffi.new('void **')
         ptr_devices = _ffi.new('void*[]', [device.ptr for device in devices])
-        ptr_binaries = _ffi.new('char*[]', len(binaries))
-        for i, binary in enumerate(binaries):
-            ptr_binaries[i] = _ffi.new('char[]', binary)
-        _handle_error(_lib._create_program_with_binary(ptr_program, context.ptr, len(ptr_devices), ptr_devices, len(ptr_binaries), ptr_binaries))
+        ptr_binaries = [_ffi.new('char[]', binary) for binary in binaries]
+        binary_sizes = _ffi.new('size_t[]', map(len, binaries))
+
+        _handle_error(_lib._create_program_with_binary(
+            ptr_program,
+            context.ptr,
+            len(ptr_devices),
+            ptr_devices,
+            len(ptr_binaries),
+            _ffi.new('char*[]', ptr_binaries),
+            binary_sizes))
+        
         self.ptr = ptr_program[0]
 
     def kind(self):
@@ -314,13 +322,17 @@ class _Program(_Common):
         return kind[0]
 
     def _build(self, options=None, devices=None):
-        if devices is None: raise NotImplementedError()
-        # TODO: if devices is None, create them
         if options is None:
             options = ""
-        ptr_devices = _ffi.new('void*[]', [device.ptr for device in devices])
+        #if devices is None: devices = self.get_info(0x1163)
+        if devices is None:
+            num_devices = 0
+            ptr_devices = _ffi.NULL
+        else:
+            ptr_devices = _ffi.new('void*[]', [device.ptr for device in devices])
+            num_devices = len(devices)
         
-        _handle_error(_lib.program__build(self.ptr, _ffi.new('char[]', options), len(ptr_devices), _ffi.cast('void**', ptr_devices)))
+        _handle_error(_lib.program__build(self.ptr, _ffi.new('char[]', options), num_devices, _ffi.cast('void**', ptr_devices)))
 
 
     def get_build_info(self, device, param):
@@ -376,7 +388,12 @@ def _generic_info_to_python(info):
         ret = map(_ffi.string, value)
         _lib._free2(info.value, len(value))
     elif type_.endswith(']'):
-        ret = list(value)
+        if type_.startswith('char['):
+            ret = ''.join(a[0] for a in value)
+        elif type_.startswith('generic_info['):
+            ret = list(map(_generic_info_to_python, value))
+        else:
+            ret = list(value)
     else:
         ret = value[0]
     _lib._free(info.value)
diff --git a/src/c_wrapper/wrap_cl.cpp b/src/c_wrapper/wrap_cl.cpp
index bddd84e6614d2fdd8aadd94c9cf8458c169e7ba9..85021d7fe202f54dfd57cfd61634352d76d64e17 100644
--- a/src/c_wrapper/wrap_cl.cpp
+++ b/src/c_wrapper/wrap_cl.cpp
@@ -861,14 +861,13 @@ generic_info get_info(cl_device_info param_name) const
       if (py_dev)
 	dev = py_dev->data();
       else
-        {
-	  // TODO
-          // std::vector<cl_device_id> devs;
-          // PYOPENCL_GET_VEC_INFO(Context, ctx.data(), CL_CONTEXT_DEVICES, devs);
-          // if (devs.size() == 0)
-          //   throw pyopencl::error("CommandQueue", CL_INVALID_VALUE,
-          //       "context doesn't have any devices? -- don't know which one to default to");
-          // dev = devs[0];
+	{
+          std::vector<cl_device_id> devs;
+          PYOPENCL_GET_VEC_INFO(Context, ctx.data(), CL_CONTEXT_DEVICES, devs);
+          if (devs.size() == 0)
+            throw pyopencl::error("CommandQueue", CL_INVALID_VALUE,
+                "context doesn't have any devices? -- don't know which one to default to");
+	  dev = devs[0];
         }
 
       cl_int status_code;
@@ -1450,16 +1449,20 @@ generic_info get_info(cl_device_info param_name) const
 	  {
 	    std::vector<size_t> sizes;
 	    PYOPENCL_GET_VEC_INFO(Program, m_program, CL_PROGRAM_BINARY_SIZES, sizes);
-
 	    std::vector<char *> result_ptrs(sizes.size());
 	    for (unsigned i = 0; i < sizes.size(); ++i) {
-	      result_ptrs[i] = new char[sizes[i]+1];
-	      result_ptrs[i][sizes[i]] = '\0';
+	      result_ptrs[i] = new char[sizes[i]];
+	    }
+	    std::vector<generic_info> gis(sizes.size());
+	    for(unsigned i = 0; i < sizes.size(); ++i) {
+	      gis[i].opaque_class = CLASS_NONE;
+	      gis[i].type =  _copy_str(std::string("char[") + tostring(sizes[i]) + "]");
+	      gis[i].value = result_ptrs[i];
 	    }
 	    PYOPENCL_CALL_GUARDED(clGetProgramInfo,
-				  (m_program, CL_PROGRAM_BINARIES, sizes.size()*sizeof(char *),
-				   &result_ptrs.front(), 0)); 
-	    PYOPENCL_GET_ARRAY_INFO(char*, result_ptrs)
+	    			  (m_program, CL_PROGRAM_BINARIES, sizes.size()*sizeof(char *),
+	    			   &result_ptrs.front(), 0));
+	    PYOPENCL_GET_ARRAY_INFO(generic_info, gis);
 	  }
 	  
 #if PYOPENCL_CL_VERSION >= 0x1020
@@ -1918,37 +1921,32 @@ generic_info get_info(cl_device_info param_name) const
   }
 
   inline
-  program *create_program_with_binary(
-				      context &ctx,
+  program *create_program_with_binary(context &ctx,
 				      cl_uint num_devices, 
 				      void **ptr_devices,
 				      cl_uint num_binaries,
-				      char **binaries)
+				      char **binaries,
+				      size_t *binary_sizes)
   {
     std::vector<cl_device_id> devices;
-    std::vector<size_t> sizes;
-    std::vector<cl_int> binary_statuses;
-
+    std::vector<cl_int> binary_statuses(num_devices);
     for (cl_uint i = 0; i < num_devices; ++i)
       {
 	devices.push_back(static_cast<device*>(ptr_devices[i])->data());
-	sizes.push_back(strlen(const_cast<const char*>(binaries[i])));
       }
-    binary_statuses.resize(num_devices);
     cl_int status_code;
     PYOPENCL_PRINT_CALL_TRACE("clCreateProgramWithBinary");
-    cl_program result = clCreateProgramWithBinary(
-						  ctx.data(), num_devices,
+    cl_program result = clCreateProgramWithBinary(ctx.data(), num_devices,
 						  devices.empty( ) ? NULL : &devices.front(),
-						  sizes.empty( ) ? NULL : &sizes.front(),
-						  reinterpret_cast<const unsigned char**>(const_cast<const char**>(binaries)), // todo: valid cast?
+						  binary_sizes,
+						  reinterpret_cast<const unsigned char**>(const_cast<const char**>(binaries)),
 						  binary_statuses.empty( ) ? NULL : &binary_statuses.front(),
 						  &status_code);
-    if (status_code != CL_SUCCESS)
-      throw pyopencl::error("clCreateProgramWithBinary", status_code);
-    
+
     // for (cl_uint i = 0; i < num_devices; ++i)
     //   std::cout << i << ":" << binary_statuses[i] << std::endl;
+    if (status_code != CL_SUCCESS)
+      throw pyopencl::error("clCreateProgramWithBinary", status_code);
 
     try
       {
@@ -2056,10 +2054,10 @@ generic_info get_info(cl_device_info param_name) const
       return 0;
   }
 
-  ::error *_create_program_with_binary(void **ptr_program, void *ptr_context, cl_uint num_devices, void **ptr_devices, cl_uint num_binaries, char **binaries) {
+  ::error *_create_program_with_binary(void **ptr_program, void *ptr_context, cl_uint num_devices, void **ptr_devices, cl_uint num_binaries, char **binaries, size_t *binary_sizes) {
     context *ctx = static_cast<context*>(ptr_context);
     C_HANDLE_ERROR(
-		   *ptr_program = create_program_with_binary(*ctx, num_devices, ptr_devices, num_binaries, binaries);
+		   *ptr_program = create_program_with_binary(*ctx, num_devices, ptr_devices, num_binaries, reinterpret_cast<char **>(binaries), binary_sizes);
 		   )
       return 0;
   }
diff --git a/src/c_wrapper/wrap_cl_core.h b/src/c_wrapper/wrap_cl_core.h
index 0473ffd5ef38b23db20be5b5bb6a3f427753058f..47e18a49f49b383182c2384cf6dd18b0715392f4 100644
--- a/src/c_wrapper/wrap_cl_core.h
+++ b/src/c_wrapper/wrap_cl_core.h
@@ -33,7 +33,7 @@ error *_create_context(void **ptr_ctx, cl_context_properties *properties, cl_uin
 error *_create_command_queue(void **ptr_command_queue, void *ptr_context, void *ptr_device, cl_command_queue_properties properties);
 error *_create_buffer(void **ptr_buffer, void *ptr_context, cl_mem_flags flags, size_t size, void *hostbuf);
 error *_create_program_with_source(void **ptr_program, void *ptr_context, char *src);
-error *_create_program_with_binary(void **ptr_program, void *ptr_context, cl_uint num_devices, void **ptr_devices, cl_uint num_binaries, char **binaries);
+error *_create_program_with_binary(void **ptr_program, void *ptr_context, cl_uint num_devices, void **ptr_devices, cl_uint num_binaries, char **binaries, size_t *binary_sizes);
 error *program__build(void *ptr_program, char *options, cl_uint num_devices, void **ptr_devices);
 error *program__kind(void *ptr_program, int *kind);
 error *program__get_build_info(void *ptr_program, void *ptr_device, cl_program_build_info param, generic_info *out);