     std::vector<result_type> result;
 
     // Probe hash table with first left column
-    // TODO Make this an outer join!
     std::vector<col0_type> const & probe_column = std::get<0>(left_columns);
     for(size_t left_index = 0; left_index < probe_column.size(); ++left_index)
     {
-      auto found = the_map.find(probe_column[left_index]);
-
-      // First column matches, check the rest
-      if(found != the_map.end()){
-        auto right_index = found->second;
-
-        // Check if left_columns[left_index] == right_columns[right_index]
+
+      // Find all keys that match probe_key
+      const auto probe_key = probe_column[left_index];
+      auto range = the_map.equal_range(probe_key);
+
+      // Every element in the range identifies a row in the right columns where
+      // the first column matches. Need to check if all other columns also match
+      for(auto i =  range.first; i != range.second; ++i)
+      {
+        const auto right_index = i->second;
+
+        // If all of the columns in right_columns[right_index] == all of the columns in left_columns[left_index]
+        // Then this index pair is added to the result as a matching pair of row indices
         if( true == rows_match(num_columns, left_index, right_index))
           result.emplace_back(left_index, right_index);
       }
     }
 
     // Sort the result
-    std::sort(result.begin(), result.end());
+    if(sort)
+    {
+      std::sort(result.begin(), result.end());
+    }
+
+    if(print)
+    {
+      std::cout << "Result size: " << result.size() << std::endl;
+      std::cout << "left index, right index" << std::endl;
+      std::copy(result.begin(), result.end(), std::ostream_iterator<result_type>(std::cout, ""));
+      std::cout << "\n";
+    }
 
     return result;
   }
-
   //gdf_error gdf_multi_left_join_generic(int num_cols, gdf_column **leftcol, gdf_column **rightcol, gdf_join_result_type **out_result)
-  
 };
+
+
+typedef ::testing::Types<InputTypes<int,int,int>> Implementations;
+
+TYPED_TEST_CASE(InnerJoinTest, Implementations);
+
+TYPED_TEST(InnerJoinTest, debug)
+{
+  this->create_input(3,5,2,5,2, true);
+  std::vector<result_type> result = this->compute_reference_solution(3, true);
+}

    // Use first right column as the build column
    std::vector<col0_type> const & build_column = std::get<0>(right_columns);

    // Build hash table
    for(size_t right_index = 0; right_index < build_column.size(); ++right_index)
    {
      the_map.insert(std::make_pair(build_column[right_index], right_index));

    if(num_columns >= 1){
      auto const & first_left_column = std::get<0>(left_columns);
      auto const & first_right_column = std::get<0>(right_columns);
      if(first_left_column[left_index] == first_right_column[right_index]){
        match = true;
      } 
