diff --git a/internal/ceres/program_test.cc b/internal/ceres/program_test.cc
new file mode 100644
index 0000000..6cb8e9e
--- /dev/null
+++ b/internal/ceres/program_test.cc
@@ -0,0 +1,422 @@
+// Ceres Solver - A fast non-linear least squares minimizer
+// Copyright 2015 Google Inc. All rights reserved.
+// http://ceres-solver.org/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+//   this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above copyright notice,
+//   this list of conditions and the following disclaimer in the documentation
+//   and/or other materials provided with the distribution.
+// * Neither the name of Google Inc. nor the names of its contributors may be
+//   used to endorse or promote products derived from this software without
+//   specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: sameeragarwal@google.com (Sameer Agarwal)
+
+#include "ceres/program.h"
+
+#include <cmath>
+#include <limits>
+#include <memory>
+#include <vector>
+
+#include "ceres/internal/integer_sequence_algorithm.h"
+#include "ceres/problem_impl.h"
+#include "ceres/residual_block.h"
+#include "ceres/sized_cost_function.h"
+#include "ceres/triplet_sparse_matrix.h"
+#include "gtest/gtest.h"
+
+namespace ceres {
+namespace internal {
+
+using std::string;
+using std::vector;
+
+// A cost function that simply returns its argument.
+class UnaryIdentityCostFunction : public SizedCostFunction<1, 1> {
+ public:
+  virtual bool Evaluate(double const* const* parameters,
+                        double* residuals,
+                        double** jacobians) const {
+    residuals[0] = parameters[0][0];
+    if (jacobians != nullptr && jacobians[0] != nullptr) {
+      jacobians[0][0] = 1.0;
+    }
+    return true;
+  }
+};
+
+// Templated base class for the CostFunction signatures.
+template <int kNumResiduals, int... Ns>
+class MockCostFunctionBase : public SizedCostFunction<kNumResiduals, Ns...> {
+ public:
+  virtual bool Evaluate(double const* const* parameters,
+                        double* residuals,
+                        double** jacobians) const {
+    const int kNumParameters = Sum<integer_sequence<int, Ns...>>::Value;
+
+    for (int i = 0; i < kNumResiduals; ++i) {
+      residuals[i] = kNumResiduals + kNumParameters;
+    }
+    return true;
+  }
+};
+
+class UnaryCostFunction : public MockCostFunctionBase<2, 1> {};
+class BinaryCostFunction : public MockCostFunctionBase<2, 1, 1> {};
+class TernaryCostFunction : public MockCostFunctionBase<2, 1, 1, 1> {};
+
+TEST(Program, RemoveFixedBlocksNothingConstant) {
+  ProblemImpl problem;
+  double x;
+  double y;
+  double z;
+
+  problem.AddParameterBlock(&x, 1);
+  problem.AddParameterBlock(&y, 1);
+  problem.AddParameterBlock(&z, 1);
+  problem.AddResidualBlock(new UnaryCostFunction(), nullptr, &x);
+  problem.AddResidualBlock(new BinaryCostFunction(), nullptr, &x, &y);
+  problem.AddResidualBlock(new TernaryCostFunction(), nullptr, &x, &y, &z);
+
+  vector<double*> removed_parameter_blocks;
+  double fixed_cost = 0.0;
+  string message;
+  std::unique_ptr<Program> reduced_program(problem.program().CreateReducedProgram(
+          &removed_parameter_blocks, &fixed_cost, &message));
+
+  EXPECT_EQ(reduced_program->NumParameterBlocks(), 3);
+  EXPECT_EQ(reduced_program->NumResidualBlocks(), 3);
+  EXPECT_EQ(removed_parameter_blocks.size(), 0);
+  EXPECT_EQ(fixed_cost, 0.0);
+}
+
+TEST(Program, RemoveFixedBlocksAllParameterBlocksConstant) {
+  ProblemImpl problem;
+  double x = 1.0;
+
+  problem.AddParameterBlock(&x, 1);
+  problem.AddResidualBlock(new UnaryCostFunction(), nullptr, &x);
+  problem.SetParameterBlockConstant(&x);
+
+  vector<double*> removed_parameter_blocks;
+  double fixed_cost = 0.0;
+  string message;
+  std::unique_ptr<Program> reduced_program(
+      problem.program().CreateReducedProgram(
+          &removed_parameter_blocks, &fixed_cost, &message));
+
+  EXPECT_EQ(reduced_program->NumParameterBlocks(), 0);
+  EXPECT_EQ(reduced_program->NumResidualBlocks(), 0);
+  EXPECT_EQ(removed_parameter_blocks.size(), 1);
+  EXPECT_EQ(removed_parameter_blocks[0], &x);
+  EXPECT_EQ(fixed_cost, 9.0);
+}
+
+
+TEST(Program, RemoveFixedBlocksNoResidualBlocks) {
+  ProblemImpl problem;
+  double x;
+  double y;
+  double z;
+
+  problem.AddParameterBlock(&x, 1);
+  problem.AddParameterBlock(&y, 1);
+  problem.AddParameterBlock(&z, 1);
+
+  vector<double*> removed_parameter_blocks;
+  double fixed_cost = 0.0;
+  string message;
+  std::unique_ptr<Program> reduced_program(
+      problem.program().CreateReducedProgram(
+          &removed_parameter_blocks, &fixed_cost, &message));
+  EXPECT_EQ(reduced_program->NumParameterBlocks(), 0);
+  EXPECT_EQ(reduced_program->NumResidualBlocks(), 0);
+  EXPECT_EQ(removed_parameter_blocks.size(), 3);
+  EXPECT_EQ(fixed_cost, 0.0);
+}
+
+TEST(Program, RemoveFixedBlocksOneParameterBlockConstant) {
+  ProblemImpl problem;
+  double x;
+  double y;
+  double z;
+
+  problem.AddParameterBlock(&x, 1);
+  problem.AddParameterBlock(&y, 1);
+  problem.AddParameterBlock(&z, 1);
+
+  problem.AddResidualBlock(new UnaryCostFunction(), nullptr, &x);
+  problem.AddResidualBlock(new BinaryCostFunction(), nullptr, &x, &y);
+  problem.SetParameterBlockConstant(&x);
+
+  vector<double*> removed_parameter_blocks;
+  double fixed_cost = 0.0;
+  string message;
+  std::unique_ptr<Program> reduced_program(
+      problem.program().CreateReducedProgram(
+          &removed_parameter_blocks, &fixed_cost, &message));
+  EXPECT_EQ(reduced_program->NumParameterBlocks(), 1);
+  EXPECT_EQ(reduced_program->NumResidualBlocks(), 1);
+}
+
+TEST(Program, RemoveFixedBlocksNumEliminateBlocks) {
+  ProblemImpl problem;
+  double x;
+  double y;
+  double z;
+
+  problem.AddParameterBlock(&x, 1);
+  problem.AddParameterBlock(&y, 1);
+  problem.AddParameterBlock(&z, 1);
+  problem.AddResidualBlock(new UnaryCostFunction(), nullptr, &x);
+  problem.AddResidualBlock(new TernaryCostFunction(), nullptr, &x, &y, &z);
+  problem.AddResidualBlock(new BinaryCostFunction(), nullptr, &x, &y);
+  problem.SetParameterBlockConstant(&x);
+
+  vector<double*> removed_parameter_blocks;
+  double fixed_cost = 0.0;
+  string message;
+  std::unique_ptr<Program> reduced_program(
+      problem.program().CreateReducedProgram(
+          &removed_parameter_blocks, &fixed_cost, &message));
+  EXPECT_EQ(reduced_program->NumParameterBlocks(), 2);
+  EXPECT_EQ(reduced_program->NumResidualBlocks(), 2);
+}
+
+TEST(Program, RemoveFixedBlocksFixedCost) {
+  ProblemImpl problem;
+  double x = 1.23;
+  double y = 4.56;
+  double z = 7.89;
+
+  problem.AddParameterBlock(&x, 1);
+  problem.AddParameterBlock(&y, 1);
+  problem.AddParameterBlock(&z, 1);
+  problem.AddResidualBlock(new UnaryIdentityCostFunction(), nullptr, &x);
+  problem.AddResidualBlock(new TernaryCostFunction(), nullptr, &x, &y, &z);
+  problem.AddResidualBlock(new BinaryCostFunction(), nullptr, &x, &y);
+  problem.SetParameterBlockConstant(&x);
+
+  ResidualBlock *expected_removed_block =
+      problem.program().residual_blocks()[0];
+  std::unique_ptr<double[]> scratch(
+      new double[expected_removed_block->NumScratchDoublesForEvaluate()]);
+  double expected_fixed_cost;
+  expected_removed_block->Evaluate(true,
+                                   &expected_fixed_cost,
+                                   nullptr,
+                                   nullptr,
+                                   scratch.get());
+
+
+  vector<double*> removed_parameter_blocks;
+  double fixed_cost = 0.0;
+  string message;
+  std::unique_ptr<Program> reduced_program(
+      problem.program().CreateReducedProgram(
+          &removed_parameter_blocks, &fixed_cost, &message));
+
+  EXPECT_EQ(reduced_program->NumParameterBlocks(), 2);
+  EXPECT_EQ(reduced_program->NumResidualBlocks(), 2);
+  EXPECT_DOUBLE_EQ(fixed_cost, expected_fixed_cost);
+}
+
+TEST(Program, CreateJacobianBlockSparsityTranspose) {
+  ProblemImpl problem;
+  double x[2];
+  double y[3];
+  double z;
+
+  problem.AddParameterBlock(x, 2);
+  problem.AddParameterBlock(y, 3);
+  problem.AddParameterBlock(&z, 1);
+
+  problem.AddResidualBlock(new MockCostFunctionBase<2, 2>(), nullptr, x);
+  problem.AddResidualBlock(new MockCostFunctionBase<3, 1, 2>(), nullptr, &z, x);
+  problem.AddResidualBlock(new MockCostFunctionBase<4, 1, 3>(), nullptr, &z, y);
+  problem.AddResidualBlock(new MockCostFunctionBase<5, 1, 3>(), nullptr, &z, y);
+  problem.AddResidualBlock(new MockCostFunctionBase<1, 2, 1>(), nullptr, x, &z);
+  problem.AddResidualBlock(new MockCostFunctionBase<2, 1, 3>(), nullptr, &z, y);
+  problem.AddResidualBlock(new MockCostFunctionBase<2, 2, 1>(), nullptr, x, &z);
+  problem.AddResidualBlock(new MockCostFunctionBase<1, 3>(), nullptr, y);
+
+  TripletSparseMatrix expected_block_sparse_jacobian(3, 8, 14);
+  {
+    int* rows = expected_block_sparse_jacobian.mutable_rows();
+    int* cols = expected_block_sparse_jacobian.mutable_cols();
+    double* values = expected_block_sparse_jacobian.mutable_values();
+    rows[0] = 0;
+    cols[0] = 0;
+
+    rows[1] = 2;
+    cols[1] = 1;
+    rows[2] = 0;
+    cols[2] = 1;
+
+    rows[3] = 2;
+    cols[3] = 2;
+    rows[4] = 1;
+    cols[4] = 2;
+
+    rows[5] = 2;
+    cols[5] = 3;
+    rows[6] = 1;
+    cols[6] = 3;
+
+    rows[7] = 0;
+    cols[7] = 4;
+    rows[8] = 2;
+    cols[8] = 4;
+
+    rows[9] = 2;
+    cols[9] = 5;
+    rows[10] = 1;
+    cols[10] = 5;
+
+    rows[11] = 0;
+    cols[11] = 6;
+    rows[12] = 2;
+    cols[12] = 6;
+
+    rows[13] = 1;
+    cols[13] = 7;
+    std::fill(values, values + 14, 1.0);
+    expected_block_sparse_jacobian.set_num_nonzeros(14);
+  }
+
+  Program* program = problem.mutable_program();
+  program->SetParameterOffsetsAndIndex();
+
+  std::unique_ptr<TripletSparseMatrix> actual_block_sparse_jacobian(
+      program->CreateJacobianBlockSparsityTranspose());
+
+  Matrix expected_dense_jacobian;
+  expected_block_sparse_jacobian.ToDenseMatrix(&expected_dense_jacobian);
+
+  Matrix actual_dense_jacobian;
+  actual_block_sparse_jacobian->ToDenseMatrix(&actual_dense_jacobian);
+  EXPECT_EQ((expected_dense_jacobian - actual_dense_jacobian).norm(), 0.0);
+}
+
+template <int kNumResiduals, int kNumParameterBlocks>
+class NumParameterBlocksCostFunction : public CostFunction {
+ public:
+  NumParameterBlocksCostFunction() {
+    set_num_residuals(kNumResiduals);
+    for (int i = 0; i < kNumParameterBlocks; ++i) {
+      mutable_parameter_block_sizes()->push_back(1);
+    }
+  }
+
+  virtual ~NumParameterBlocksCostFunction() {
+  }
+
+  virtual bool Evaluate(double const* const* parameters,
+                        double* residuals,
+                        double** jacobians) const {
+    return true;
+  }
+};
+
+TEST(Program, ReallocationInCreateJacobianBlockSparsityTranspose) {
+  // CreateJacobianBlockSparsityTranspose starts with a conservative
+  // estimate of the size of the sparsity pattern. This test ensures
+  // that when those estimates are violated, the reallocation/resizing
+  // logic works correctly.
+
+  ProblemImpl problem;
+  double x[20];
+
+  vector<double*> parameter_blocks;
+  for (int i = 0; i < 20; ++i) {
+    problem.AddParameterBlock(x + i, 1);
+    parameter_blocks.push_back(x + i);
+  }
+
+  problem.AddResidualBlock(new NumParameterBlocksCostFunction<1, 20>(),
+                           nullptr,
+                           parameter_blocks.data(),
+                           static_cast<int>(parameter_blocks.size()));
+
+  TripletSparseMatrix expected_block_sparse_jacobian(20, 1, 20);
+  {
+    int* rows = expected_block_sparse_jacobian.mutable_rows();
+    int* cols = expected_block_sparse_jacobian.mutable_cols();
+    for (int i = 0; i < 20; ++i) {
+      rows[i] = i;
+      cols[i] = 0;
+    }
+
+    double* values = expected_block_sparse_jacobian.mutable_values();
+    std::fill(values, values + 20, 1.0);
+    expected_block_sparse_jacobian.set_num_nonzeros(20);
+  }
+
+  Program* program = problem.mutable_program();
+  program->SetParameterOffsetsAndIndex();
+
+  std::unique_ptr<TripletSparseMatrix> actual_block_sparse_jacobian(
+      program->CreateJacobianBlockSparsityTranspose());
+
+  Matrix expected_dense_jacobian;
+  expected_block_sparse_jacobian.ToDenseMatrix(&expected_dense_jacobian);
+
+  Matrix actual_dense_jacobian;
+  actual_block_sparse_jacobian->ToDenseMatrix(&actual_dense_jacobian);
+  EXPECT_EQ((expected_dense_jacobian - actual_dense_jacobian).norm(), 0.0);
+}
+
+TEST(Program, ProblemHasNanParameterBlocks) {
+  ProblemImpl problem;
+  double x[2];
+  x[0] = 1.0;
+  x[1] = std::numeric_limits<double>::quiet_NaN();
+  problem.AddResidualBlock(new MockCostFunctionBase<1, 2>(), nullptr, x);
+  string error;
+  EXPECT_FALSE(problem.program().ParameterBlocksAreFinite(&error));
+  EXPECT_NE(error.find("has at least one invalid value"),
+            string::npos) << error;
+}
+
+TEST(Program, InfeasibleParameterBlock) {
+  ProblemImpl problem;
+  double x[] = {0.0, 0.0};
+  problem.AddResidualBlock(new MockCostFunctionBase<1, 2>(), nullptr, x);
+  problem.SetParameterLowerBound(x, 0, 2.0);
+  problem.SetParameterUpperBound(x, 0, 1.0);
+  string error;
+  EXPECT_FALSE(problem.program().IsFeasible(&error));
+  EXPECT_NE(error.find("infeasible bound"), string::npos) << error;
+}
+
+TEST(Program, InfeasibleConstantParameterBlock) {
+  ProblemImpl problem;
+  double x[] = {0.0, 0.0};
+  problem.AddResidualBlock(new MockCostFunctionBase<1, 2>(), nullptr, x);
+  problem.SetParameterLowerBound(x, 0, 1.0);
+  problem.SetParameterUpperBound(x, 0, 2.0);
+  problem.SetParameterBlockConstant(x);
+  string error;
+  EXPECT_FALSE(problem.program().IsFeasible(&error));
+  EXPECT_NE(error.find("infeasible value"), string::npos) << error;
+}
+
+}  // namespace internal
+}  // namespace ceres
