diff --git a/pyopencl/cffi_cl.py b/pyopencl/cffi_cl.py
index dc1adcf19682c2142e13c029d9f913203e736ac0..1198b1c10531b6f8395fc5bd2736881686628068 100644
--- a/pyopencl/cffi_cl.py
+++ b/pyopencl/cffi_cl.py
@@ -332,6 +332,13 @@ class _Program(object):
         
         _handle_error(_lib.program__build(self.ptr, _ffi.new('char[]', options), len(ptr_devices), _ffi.cast('void**', ptr_devices)))
 
+
+    def get_build_info(self, device, param):
+        info = _ffi.new('generic_info *')
+        _handle_error(_lib.program__get_build_info(self.ptr, device.ptr, param, info))
+        return _generic_info_to_python(info)
+        
+
     def get_info(self, param):
         if param == program_info.DEVICES:
             # todo: refactor, same code as in get_devices 
@@ -347,8 +354,12 @@ class _Program(object):
             ptr_binaries = _CArrays(_ffi.new('char***'))
             _handle_error(_lib.program__get_info__binaries(self.ptr, ptr_binaries.ptr, ptr_binaries.size))
             return map(_ffi.string, ptr_binaries)
-        print param
-        raise NotImplementedError()
+
+        info = _ffi.new('generic_info *')
+        _handle_error(_lib.program__get_info(self.ptr, param, info))
+        
+        return _generic_info_to_python(info)
+
         
 class Platform(EQUALITY_TESTS):
     def __init__(self):
@@ -385,8 +396,15 @@ def _create_platform(ptr):
 def _generic_info_to_python(info):
     if info.type == _lib.generic_info_type_chars:
         return _ffi.string(info.value._chars)
+    if info.type == _lib.generic_info_type_array:
+        ar = _ffi.cast('%s[%s]' % (_ffi.string(info.array_element_type), info.value._array.size), info.value._array.array)
+        return list(ar)
+        
     for type_ in ('cl_uint',
                   'cl_mem_object_type',
+                  'cl_build_status',
+                  'cl_program_binary_type',
+                  'size_t',
                   ):
         if info.type == getattr(_lib, 'generic_info_type_%s' % type_):
             return getattr(info.value, '_%s' % type_)
diff --git a/src/c_wrapper/wrap_cl.cpp b/src/c_wrapper/wrap_cl.cpp
index d2f1f148dffdc61653835b2e0adff4f3952a5e8b..eb0dea0ac3d06ecfade28910d1851c9ce3edfa5a 100644
--- a/src/c_wrapper/wrap_cl.cpp
+++ b/src/c_wrapper/wrap_cl.cpp
@@ -96,16 +96,29 @@
   return info;								\
 }
 
-
-#define PYOPENCL_RETURN_NEW_EVENT(evt) \
-    try \
-    { \
-      return new event(evt, false); \
-    } \
-    catch (...) \
-    { \
-      clReleaseEvent(evt); \
-      throw; \
+#define PYOPENCL_GET_ARRAY_INFO(TYPE, VEC)	\
+  {						\
+    MALLOC(TYPE, ar, VEC.size());		\
+    for(uint32_t i = 0; i < VEC.size(); ++i) {	\
+      ar[i] = VEC[i];				\
+    }						\
+    generic_info info;				\
+    info.type = generic_info_type_array;	\
+    info.value._array.array = ar;		\
+    info.value._array.size = VEC.size();	\
+    info.array_element_type = #TYPE;		\
+    return info;				\
+  }
+  
+#define PYOPENCL_RETURN_NEW_EVENT(evt)		\
+  try						\
+    {						\
+      return new event(evt, false);		\
+    }						\
+  catch (...)					\
+    {						\
+      clReleaseEvent(evt);			\
+      throw;					\
     }
 
 
@@ -1376,19 +1389,19 @@ class buffer : public memory_object
       }
     
 
-      //py::object get_info(cl_program_info param_name) const
-//       {
-//         switch (param_name)
-//         {
-//           case CL_PROGRAM_REFERENCE_COUNT:
-//             PYOPENCL_GET_INTEGRAL_INFO(Program, m_program, param_name,
-//                 cl_uint);
-//           case CL_PROGRAM_CONTEXT:
-//             PYOPENCL_GET_OPAQUE_INFO(Program, m_program, param_name,
-//                 cl_context, context);
-//           case CL_PROGRAM_NUM_DEVICES:
-//             PYOPENCL_GET_INTEGRAL_INFO(Program, m_program, param_name,
-//                 cl_uint);
+      generic_info get_info(cl_program_info param_name) const
+      {
+        switch (param_name)
+        {
+          case CL_PROGRAM_REFERENCE_COUNT:
+            PYOPENCL_GET_INTEGRAL_INFO(Program, m_program, param_name,
+                cl_uint);
+          // case CL_PROGRAM_CONTEXT:
+          //   PYOPENCL_GET_OPAQUE_INFO(Program, m_program, param_name,
+          //       cl_context, context);
+          case CL_PROGRAM_NUM_DEVICES:
+            PYOPENCL_GET_INTEGRAL_INFO(Program, m_program, param_name,
+                cl_uint);
 //           case CL_PROGRAM_DEVICES:
 //             {
 //               std::vector<cl_device_id> result;
@@ -1400,14 +1413,14 @@ class buffer : public memory_object
 //                       new pyopencl::device(did)));
 //               return py_result;
 //             }
-//           case CL_PROGRAM_SOURCE:
-//             PYOPENCL_GET_STR_INFO(Program, m_program, param_name);
-//           case CL_PROGRAM_BINARY_SIZES:
-//             {
-//               std::vector<size_t> result;
-//               PYOPENCL_GET_VEC_INFO(Program, m_program, param_name, result);
-//               PYOPENCL_RETURN_VECTOR(size_t, result);
-//             }
+          case CL_PROGRAM_SOURCE:
+            PYOPENCL_GET_STR_INFO(Program, m_program, param_name);
+          case CL_PROGRAM_BINARY_SIZES:
+            {
+              std::vector<size_t> result;
+              PYOPENCL_GET_VEC_INFO(Program, m_program, param_name, result);
+              PYOPENCL_GET_ARRAY_INFO(size_t, result);
+            }
 //           case CL_PROGRAM_BINARIES:
 //             // {{{
 //             {
@@ -1450,46 +1463,45 @@ class buffer : public memory_object
 //               return py_result;
 //             }
 //             // }}}
-// #if PYOPENCL_CL_VERSION >= 0x1020
-//           case CL_PROGRAM_NUM_KERNELS:
-//             PYOPENCL_GET_INTEGRAL_INFO(Program, m_program, param_name,
-//                 size_t);
-//           case CL_PROGRAM_KERNEL_NAMES:
-//             PYOPENCL_GET_STR_INFO(Program, m_program, param_name);
-// #endif
+#if PYOPENCL_CL_VERSION >= 0x1020
+          case CL_PROGRAM_NUM_KERNELS:
+            PYOPENCL_GET_INTEGRAL_INFO(Program, m_program, param_name,
+                size_t);
+          case CL_PROGRAM_KERNEL_NAMES:
+            PYOPENCL_GET_STR_INFO(Program, m_program, param_name);
+#endif
 
-//           default:
-//             throw error("Program.get_info", CL_INVALID_VALUE);
-//         }
-//       }
+          default:
+            throw error("Program.get_info", CL_INVALID_VALUE);
+        }
+      }
 
-//       py::object get_build_info(
-//           device const &dev,
-//           cl_program_build_info param_name) const
-//       {
-//         switch (param_name)
-//         {
-// #define PYOPENCL_FIRST_ARG m_program, dev.data() // hackety hack
-//           case CL_PROGRAM_BUILD_STATUS:
-//             PYOPENCL_GET_INTEGRAL_INFO(ProgramBuild,
-//                 PYOPENCL_FIRST_ARG, param_name,
-//                 cl_build_status);
-//           case CL_PROGRAM_BUILD_OPTIONS:
-//           case CL_PROGRAM_BUILD_LOG:
-//             PYOPENCL_GET_STR_INFO(ProgramBuild,
-//                 PYOPENCL_FIRST_ARG, param_name);
-// #if PYOPENCL_CL_VERSION >= 0x1020
-//           case CL_PROGRAM_BINARY_TYPE:
-//             PYOPENCL_GET_INTEGRAL_INFO(ProgramBuild,
-//                 PYOPENCL_FIRST_ARG, param_name,
-//                 cl_program_binary_type);
-// #endif
-// #undef PYOPENCL_FIRST_ARG
+    generic_info get_build_info(device const &dev,
+				cl_program_build_info param_name) const
+    {
+      switch (param_name)
+        {
+#define PYOPENCL_FIRST_ARG m_program, dev.data() // hackety hack
+	case CL_PROGRAM_BUILD_STATUS:
+	  PYOPENCL_GET_INTEGRAL_INFO(ProgramBuild,
+				     PYOPENCL_FIRST_ARG, param_name,
+				     cl_build_status);
+ 	case CL_PROGRAM_BUILD_OPTIONS:
+	case CL_PROGRAM_BUILD_LOG:
+	  PYOPENCL_GET_STR_INFO(ProgramBuild,
+				PYOPENCL_FIRST_ARG, param_name);
+#if PYOPENCL_CL_VERSION >= 0x1020
+	case CL_PROGRAM_BINARY_TYPE:
+	  PYOPENCL_GET_INTEGRAL_INFO(ProgramBuild,
+				     PYOPENCL_FIRST_ARG, param_name,
+				     cl_program_binary_type);
+#endif
+#undef PYOPENCL_FIRST_ARG
 
-//           default:
-//             throw error("Program.get_build_info", CL_INVALID_VALUE);
-//         }
-//       }
+	default:
+	  throw error("Program.get_build_info", CL_INVALID_VALUE);
+        }
+    }
 
       void build(char *options, cl_uint num_devices, void **ptr_devices)
       { 
@@ -2084,6 +2096,15 @@ inline event *enqueue_nd_range_kernel(
     return 0;
   }
 
+  
+  ::error *program__get_build_info(void *ptr_program, void *ptr_device, cl_program_build_info param, generic_info *out) {
+    C_HANDLE_ERROR(
+		   *out = static_cast<program*>(ptr_program)->get_build_info(*static_cast<device*>(ptr_device),
+									     param);
+		   )
+    return 0;
+  }
+
   ::error *program__get_info__devices(void *ptr_program, void **ptr_devices, uint32_t *num_devices) {
     typedef std::vector<cl_device_id> vec;
 
@@ -2109,6 +2130,15 @@ inline event *enqueue_nd_range_kernel(
 		   )
     return 0;
   }
+
+  
+  ::error *program__get_info(void *ptr_program, cl_program_info param, generic_info *out) {
+    C_HANDLE_ERROR(
+    *out = static_cast<program*>(ptr_program)->get_info(param);
+		   )
+    return 0;
+  }
+
   
 
   long device__hash(void *ptr_device) {
diff --git a/src/c_wrapper/wrap_cl_core.h b/src/c_wrapper/wrap_cl_core.h
index 0a35b58479c6121bc444f97820c91656458e2465..fd68f5ea70e55a3e66beb0646e8bdcfe39591c8d 100644
--- a/src/c_wrapper/wrap_cl_core.h
+++ b/src/c_wrapper/wrap_cl_core.h
@@ -3,15 +3,25 @@ typedef enum { KND_UNKNOWN, KND_SOURCE, KND_BINARY } program_kind_type;
 typedef enum {
   generic_info_type_cl_uint,
   generic_info_type_cl_mem_object_type,
+  generic_info_type_cl_build_status,
+  generic_info_type_cl_program_binary_type,
+  generic_info_type_size_t,
   generic_info_type_chars,
+  generic_info_type_array,
 } generic_info_type_t;
 
 typedef struct {
   generic_info_type_t type;
+  const char *array_element_type;
   union value_t {
     cl_uint _cl_uint;
     cl_mem_object_type _cl_mem_object_type;
+    cl_build_status _cl_build_status;
+    cl_program_binary_type _cl_program_binary_type;
+    size_t _size_t;
     char *_chars;
+    
+    struct { void *array; uint32_t size; } _array;
   } value;
 } generic_info;
 
@@ -38,6 +48,8 @@ error *_create_program_with_source(void **ptr_program, void *ptr_context, char *
 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 *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);
+error *program__get_info(void *ptr_program, cl_program_info param, generic_info *out);
 error *program__get_info__devices(void *ptr_program, void **ptr_devices, uint32_t *num_devices);
 error *program__get_info__binaries(void *ptr_program, char ***ptr_binaries, uint32_t *num_binaries);
 long program__hash(void *ptr_program);