diff --git a/examples/libmv_bundle_adjuster.cc b/examples/libmv_bundle_adjuster.cc
new file mode 100644
index 0000000..47d0cd7
--- /dev/null
+++ b/examples/libmv_bundle_adjuster.cc
@@ -0,0 +1,843 @@
+// Copyright (c) 2013 libmv authors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//
+// Author: mierle@gmail.com (Keir Mierle)
+//         sergey.vfx@gmail.com (Sergey Sharybin)
+//
+// This is an example application which contains bundle adjustment code used
+// in the Libmv library and Blender. It reads problems from files passed via
+// the command line and runs the bundle adjuster on the problem.
+//
+// File with problem a binary file, for which it is crucial to know in which
+// order bytes of float values are stored in. This information is provided
+// by a single character in the beginning of the file. There're two possible
+// values of this byte:
+//  - V, which means values in the file are stored with big endian type
+//  - v, which means values in the file are stored with little endian type
+//
+// The rest of the file contains data in the following order:
+//   - Space in which markers' coordinates are stored in
+//   - Camera intrinsics
+//   - Number of cameras
+//   - Cameras
+//   - Number of 3D points
+//   - 3D points
+//   - Number of markers
+//   - Markers
+//
+// Markers' space could either be normalized or image (pixels). This is defined
+// by the single character in the file. P means markers in the file is in image
+// space, and N means markers are in normalized space.
+//
+// Camera intrinsics are 8 described by 8 float 8.
+// This values goes in the following order:
+//
+//   - Focal length, principal point X, principal point Y, k1, k2, k3, p1, p2
+//
+// Every camera is described by:
+//
+//   - Image for which camera belongs to (single 4 bytes integer value).
+//   - Column-major camera rotation matrix, 9 float values.
+//   - Camera translation, 3-component vector of float values.
+//
+// Image number shall be greater or equal to zero. Order of cameras does not
+// matter and gaps are possible.
+//
+// Every 3D point is decribed by:
+//
+//  - Track number point belongs to (single 4 bytes integer value).
+//  - 3D position vector, 3-component vector of float values.
+//
+// Track number shall be greater or equal to zero. Order of tracks does not
+// matter and gaps are possible.
+//
+// Finally every marker is described by:
+//
+//  - Image marker belongs to single 4 bytes integer value).
+//  - Track marker belongs to single 4 bytes integer value).
+//  - 2D marker position vector, (two float values).
+//
+// Marker's space is used a default value for refine_intrinsics command line
+// flag. This means if there's no refine_intrinsics flag passed via command
+// line, camera intrinsics will be refined if markers in the problem are
+// stored in image space and camera intrinsics will not be refined if markers
+// are in normalized space.
+//
+// Passing refine_intrinsics command line flag defines explicitly whether
+// refinement of intrinsics will happen. Currently, only none and all
+// intrinsics refinement is supported.
+//
+// There're existing problem files dumped from blender stored in folder
+// ../data/libmv-ba-problems.
+
+#include <cstdio>
+#include <fcntl.h>
+#include <sstream>
+#include <string>
+#include <vector>
+
+#ifdef _MSC_VER
+#  include <io.h>
+#  define open _open
+#  define close _close
+typedef unsigned __int32 uint32_t;
+#else
+#include <stdint.h>
+#include <unistd.h>
+
+// O_BINARY is not defined on unix like platforms, as there is no
+// difference between binary and text files.
+#define O_BINARY 0
+
+#endif
+
+#include "ceres/ceres.h"
+#include "ceres/rotation.h"
+#include "gflags/gflags.h"
+#include "glog/logging.h"
+
+typedef Eigen::Matrix<double, 3, 3> Mat3;
+typedef Eigen::Matrix<double, 6, 1> Vec6;
+typedef Eigen::Vector3d Vec3;
+typedef Eigen::Vector4d Vec4;
+
+using std::vector;
+
+DEFINE_string(input, "", "Input File name");
+DEFINE_string(refine_intrinsics, "", "Camera intrinsics to be refined. "
+              "Options are: none, radial.");
+
+namespace {
+
+// A EuclideanCamera is the location and rotation of the camera
+// viewing an image.
+//
+// image identifies which image this camera represents.
+// R is a 3x3 matrix representing the rotation of the camera.
+// t is a translation vector representing its positions.
+struct EuclideanCamera {
+  EuclideanCamera() : image(-1) {}
+  EuclideanCamera(const EuclideanCamera &c) : image(c.image), R(c.R), t(c.t) {}
+
+  int image;
+  Mat3 R;
+  Vec3 t;
+};
+
+// A Point is the 3D location of a track.
+//
+// track identifies which track this point corresponds to.
+// X represents the 3D position of the track.
+struct EuclideanPoint {
+  EuclideanPoint() : track(-1) {}
+  EuclideanPoint(const EuclideanPoint &p) : track(p.track), X(p.X) {}
+  int track;
+  Vec3 X;
+};
+
+// A Marker is the 2D location of a tracked point in an image.
+//
+// x and y is the position of the marker in pixels from the top left corner
+// in the image identified by an image. All markers for to the same target
+// form a track identified by a common track number.
+struct Marker {
+  int image;
+  int track;
+  double x, y;
+};
+
+// Cameras intrinsics to be bundled.
+//
+// BUNDLE_RADIAL actually implies bundling of k1 and k2 coefficients only,
+// no bundling of k3 is possible at this moment.
+enum BundleIntrinsics {
+  BUNDLE_NO_INTRINSICS = 0,
+  BUNDLE_FOCAL_LENGTH = 1,
+  BUNDLE_PRINCIPAL_POINT = 2,
+  BUNDLE_RADIAL_K1 = 4,
+  BUNDLE_RADIAL_K2 = 8,
+  BUNDLE_RADIAL = 12,
+  BUNDLE_TANGENTIAL_P1 = 16,
+  BUNDLE_TANGENTIAL_P2 = 32,
+  BUNDLE_TANGENTIAL = 48,
+};
+
+// Denotes which blocks to keep constant during bundling.
+// For example it is useful to keep camera translations constant
+// when bundling tripod motions.
+enum BundleConstraints {
+  BUNDLE_NO_CONSTRAINTS = 0,
+  BUNDLE_NO_TRANSLATION = 1,
+};
+
+// The intrinsics need to get combined into a single parameter block; use these
+// enums to index instead of numeric constants.
+enum {
+  OFFSET_FOCAL_LENGTH,
+  OFFSET_PRINCIPAL_POINT_X,
+  OFFSET_PRINCIPAL_POINT_Y,
+  OFFSET_K1,
+  OFFSET_K2,
+  OFFSET_K3,
+  OFFSET_P1,
+  OFFSET_P2,
+};
+
+// Returns a pointer to the camera corresponding to a image.
+EuclideanCamera *CameraForImage(vector<EuclideanCamera> *all_cameras,
+                                const int image) {
+  if (image < 0 || image >= all_cameras->size()) {
+    return NULL;
+  }
+  EuclideanCamera *camera = &(*all_cameras)[image];
+  if (camera->image == -1) {
+    return NULL;
+  }
+  return camera;
+}
+
+const EuclideanCamera *CameraForImage(
+    const vector<EuclideanCamera> &all_cameras,
+    const int image) {
+  if (image < 0 || image >= all_cameras.size()) {
+    return NULL;
+  }
+  const EuclideanCamera *camera = &all_cameras[image];
+  if (camera->image == -1) {
+    return NULL;
+  }
+  return camera;
+}
+
+// Returns maximal image number at which marker exists.
+int MaxImage(const vector<Marker> &all_markers) {
+  if (all_markers.size() == 0) {
+    return -1;
+  }
+
+  int max_image = all_markers[0].image;
+  for (int i = 1; i < all_markers.size(); i++) {
+    max_image = std::max(max_image, all_markers[i].image);
+  }
+  return max_image;
+}
+
+// Returns a pointer to the point corresponding to a track.
+EuclideanPoint *PointForTrack(vector<EuclideanPoint> *all_points,
+                              const int track) {
+  if (track < 0 || track >= all_points->size()) {
+    return NULL;
+  }
+  EuclideanPoint *point = &(*all_points)[track];
+  if (point->track == -1) {
+    return NULL;
+  }
+  return point;
+}
+
+// Reader of binary file which makes sure possibly needed endian
+// conversion happens when loading values like floats and integers.
+//
+// File's endian type is reading from a first character of file, which
+// could either be V for big endian or v for little endian.  This
+// means you need to design file format assuming first character
+// denotes file endianness in this way.
+class EndianAwareFileReader {
+ public:
+  EndianAwareFileReader(void) : file_descriptor_(-1) {
+    // Get an endian type of the host machine.
+    union {
+      unsigned char bytes[4];
+      uint32_t value;
+    } endian_test = { { 0, 1, 2, 3 } };
+    host_endian_type_ = endian_test.value;
+    file_endian_type_ = host_endian_type_;
+  }
+
+  ~EndianAwareFileReader(void) {
+    if (file_descriptor_ > 0) {
+      close(file_descriptor_);
+    }
+  }
+
+  bool OpenFile(const std::string &file_name) {
+    file_descriptor_ = open(file_name.c_str(), O_RDONLY | O_BINARY);
+    if (file_descriptor_ < 0) {
+      return false;
+    }
+    // Get an endian tpye of data in the file.
+    unsigned char file_endian_type_flag = Read<unsigned char>();
+    if (file_endian_type_flag == 'V') {
+      file_endian_type_ = kBigEndian;
+    } else if (file_endian_type_flag == 'v') {
+      file_endian_type_ = kLittleEndian;
+    } else {
+      LOG(FATAL) << "Problem file is stored in unknown endian type.";
+    }
+    return true;
+  }
+
+  // Read value from the file, will switch endian if needed.
+  template <typename T>
+  T Read(void) const {
+    T value;
+    CHECK_GT(read(file_descriptor_, &value, sizeof(value)), 0);
+    // Switch endian type if file contains data in different type
+    // that current machine.
+    if (file_endian_type_ != host_endian_type_) {
+      value = SwitchEndian<T>(value);
+    }
+    return value;
+  }
+ private:
+  static const long int kLittleEndian = 0x03020100ul;
+  static const long int kBigEndian = 0x00010203ul;
+
+  // Switch endian type between big to little.
+  template <typename T>
+  T SwitchEndian(const T value) const {
+    if (sizeof(T) == 4) {
+      unsigned int temp_value = static_cast<unsigned int>(value);
+      return ((temp_value >> 24)) |
+             ((temp_value << 8) & 0x00ff0000) |
+             ((temp_value >> 8) & 0x0000ff00) |
+             ((temp_value << 24));
+    } else if (sizeof(T) == 1) {
+      return value;
+    } else {
+      LOG(FATAL) << "Entered non-implemented part of endian switching function.";
+    }
+  }
+
+  int host_endian_type_;
+  int file_endian_type_;
+  int file_descriptor_;
+};
+
+// Read 3x3 column-major matrix from the file
+void ReadMatrix3x3(const EndianAwareFileReader &file_reader,
+                   Mat3 *matrix) {
+  for (int i = 0; i < 9; i++) {
+    (*matrix)(i % 3, i / 3) = file_reader.Read<float>();
+  }
+}
+
+// Read 3-vector from file
+void ReadVector3(const EndianAwareFileReader &file_reader,
+                 Vec3 *vector) {
+  for (int i = 0; i < 3; i++) {
+    (*vector)(i) = file_reader.Read<float>();
+  }
+}
+
+// Reads a bundle adjustment problem from the file.
+//
+// file_name denotes from which file to read the problem.
+// camera_intrinsics will contain initial camera intrinsics values.
+//
+// all_cameras is a vector of all reconstructed cameras to be optimized,
+// vector element with number i will contain camera for image i.
+//
+// all_points is a vector of all reconstructed 3D points to be optimized,
+// vector element with number i will contain point for track i.
+//
+// all_markers is a vector of all tracked markers existing in
+// the problem. Only used for reprojection error calculation, stay
+// unchanged during optimization.
+//
+// Returns false if any kind of error happened during
+// reading.
+bool ReadProblemFromFile(const std::string &file_name,
+                         double camera_intrinsics[8],
+                         vector<EuclideanCamera> *all_cameras,
+                         vector<EuclideanPoint> *all_points,
+                         bool *is_image_space,
+                         vector<Marker> *all_markers) {
+  EndianAwareFileReader file_reader;
+  if (!file_reader.OpenFile(file_name)) {
+    return false;
+  }
+
+  // Read markers' space flag.
+  unsigned char is_image_space_flag = file_reader.Read<unsigned char>();
+  if (is_image_space_flag == 'P') {
+    *is_image_space = true;
+  } else if (is_image_space_flag == 'N') {
+    *is_image_space = false;
+  } else {
+    LOG(FATAL) << "Problem file contains markers stored in unknown space.";
+  }
+
+  // Read camera intrinsics.
+  for (int i = 0; i < 8; i++) {
+    camera_intrinsics[i] = file_reader.Read<float>();
+  }
+
+  // Read all cameras.
+  int number_of_cameras = file_reader.Read<int>();
+  for (int i = 0; i < number_of_cameras; i++) {
+    EuclideanCamera camera;
+
+    camera.image = file_reader.Read<int>();
+    ReadMatrix3x3(file_reader, &camera.R);
+    ReadVector3(file_reader, &camera.t);
+
+    if (camera.image >= all_cameras->size()) {
+      all_cameras->resize(camera.image + 1);
+    }
+
+    (*all_cameras)[camera.image].image = camera.image;
+    (*all_cameras)[camera.image].R = camera.R;
+    (*all_cameras)[camera.image].t = camera.t;
+  }
+
+  LOG(INFO) << "Read " << number_of_cameras << " cameras.";
+
+  // Read all reconstructed 3D points.
+  int number_of_points = file_reader.Read<int>();
+  for (int i = 0; i < number_of_points; i++) {
+    EuclideanPoint point;
+
+    point.track = file_reader.Read<int>();
+    ReadVector3(file_reader, &point.X);
+
+    if (point.track >= all_points->size()) {
+      all_points->resize(point.track + 1);
+    }
+
+    (*all_points)[point.track].track = point.track;
+    (*all_points)[point.track].X = point.X;
+  }
+
+  LOG(INFO) << "Read " << number_of_points << " points.";
+
+  // And finally read all markers.
+  int number_of_markers = file_reader.Read<int>();
+  for (int i = 0; i < number_of_markers; i++) {
+    Marker marker;
+
+    marker.image = file_reader.Read<int>();
+    marker.track = file_reader.Read<int>();
+    marker.x = file_reader.Read<float>();
+    marker.y = file_reader.Read<float>();
+
+    all_markers->push_back(marker);
+  }
+
+  LOG(INFO) << "Read " << number_of_markers << " markers.";
+
+  return true;
+}
+
+// Apply camera intrinsics to the normalized point to get image coordinates.
+// This applies the radial lens distortion to a point which is in normalized
+// camera coordinates (i.e. the principal point is at (0, 0)) to get image
+// coordinates in pixels. Templated for use with autodifferentiation.
+template <typename T>
+inline void ApplyRadialDistortionCameraIntrinsics(const T &focal_length_x,
+                                                  const T &focal_length_y,
+                                                  const T &principal_point_x,
+                                                  const T &principal_point_y,
+                                                  const T &k1,
+                                                  const T &k2,
+                                                  const T &k3,
+                                                  const T &p1,
+                                                  const T &p2,
+                                                  const T &normalized_x,
+                                                  const T &normalized_y,
+                                                  T *image_x,
+                                                  T *image_y) {
+  T x = normalized_x;
+  T y = normalized_y;
+
+  // Apply distortion to the normalized points to get (xd, yd).
+  T r2 = x*x + y*y;
+  T r4 = r2 * r2;
+  T r6 = r4 * r2;
+  T r_coeff = 1.0 + k1 * r2 + k2 * r4 + k3 * r6;
+  T xd = x * r_coeff + 2.0 * p1 * x * y + p2 * (r2 + 2.0 * x * x);
+  T yd = y * r_coeff + 2.0 * p2 * x * y + p1 * (r2 + 2.0 * y * y);
+
+  // Apply focal length and principal point to get the final image coordinates.
+  *image_x = focal_length_x * xd + principal_point_x;
+  *image_y = focal_length_y * yd + principal_point_y;
+}
+
+// Cost functor which computes reprojection error of 3D point X
+// on camera defined by angle-axis rotation and it's translation
+// (which are in the same block due to optimization reasons).
+//
+// This functor uses a radial distortion model.
+struct OpenCVReprojectionError {
+  OpenCVReprojectionError(const double observed_x, const double observed_y)
+      : observed_x(observed_x), observed_y(observed_y) {}
+
+  template <typename T>
+  bool operator()(const T* const intrinsics,
+                  const T* const R_t,  // Rotation denoted by angle axis
+                                       // followed with translation
+                  const T* const X,    // Point coordinates 3x1.
+                  T* residuals) const {
+    // Unpack the intrinsics.
+    const T& focal_length      = intrinsics[OFFSET_FOCAL_LENGTH];
+    const T& principal_point_x = intrinsics[OFFSET_PRINCIPAL_POINT_X];
+    const T& principal_point_y = intrinsics[OFFSET_PRINCIPAL_POINT_Y];
+    const T& k1                = intrinsics[OFFSET_K1];
+    const T& k2                = intrinsics[OFFSET_K2];
+    const T& k3                = intrinsics[OFFSET_K3];
+    const T& p1                = intrinsics[OFFSET_P1];
+    const T& p2                = intrinsics[OFFSET_P2];
+
+    // Compute projective coordinates: x = RX + t.
+    T x[3];
+
+    ceres::AngleAxisRotatePoint(R_t, X, x);
+    x[0] += R_t[3];
+    x[1] += R_t[4];
+    x[2] += R_t[5];
+
+    // Compute normalized coordinates: x /= x[2].
+    T xn = x[0] / x[2];
+    T yn = x[1] / x[2];
+
+    T predicted_x, predicted_y;
+
+    // Apply distortion to the normalized points to get (xd, yd).
+    // TODO(keir): Do early bailouts for zero distortion; these are expensive
+    // jet operations.
+    ApplyRadialDistortionCameraIntrinsics(focal_length,
+                                          focal_length,
+                                          principal_point_x,
+                                          principal_point_y,
+                                          k1, k2, k3,
+                                          p1, p2,
+                                          xn, yn,
+                                          &predicted_x,
+                                          &predicted_y);
+
+    // The error is the difference between the predicted and observed position.
+    residuals[0] = predicted_x - observed_x;
+    residuals[1] = predicted_y - observed_y;
+
+    return true;
+  }
+
+  const double observed_x;
+  const double observed_y;
+};
+
+// Print a message to the log which camera intrinsics are gonna to be optimized.
+void BundleIntrinsicsLogMessage(const int bundle_intrinsics) {
+  if (bundle_intrinsics == BUNDLE_NO_INTRINSICS) {
+    LOG(INFO) << "Bundling only camera positions.";
+  } else {
+    std::string bundling_message = "";
+
+#define APPEND_BUNDLING_INTRINSICS(name, flag) \
+    if (bundle_intrinsics & flag) { \
+      if (!bundling_message.empty()) { \
+        bundling_message += ", "; \
+      } \
+      bundling_message += name; \
+    } (void)0
+
+    APPEND_BUNDLING_INTRINSICS("f",      BUNDLE_FOCAL_LENGTH);
+    APPEND_BUNDLING_INTRINSICS("px, py", BUNDLE_PRINCIPAL_POINT);
+    APPEND_BUNDLING_INTRINSICS("k1",     BUNDLE_RADIAL_K1);
+    APPEND_BUNDLING_INTRINSICS("k2",     BUNDLE_RADIAL_K2);
+    APPEND_BUNDLING_INTRINSICS("p1",     BUNDLE_TANGENTIAL_P1);
+    APPEND_BUNDLING_INTRINSICS("p2",     BUNDLE_TANGENTIAL_P2);
+
+    LOG(INFO) << "Bundling " << bundling_message << ".";
+  }
+}
+
+// Print a message to the log containing all the camera intriniscs values.
+void PrintCameraIntrinsics(const char *text, const double *camera_intrinsics) {
+  std::ostringstream intrinsics_output;
+
+  intrinsics_output << "f=" << camera_intrinsics[OFFSET_FOCAL_LENGTH];
+
+  intrinsics_output <<
+    " cx=" << camera_intrinsics[OFFSET_PRINCIPAL_POINT_X] <<
+    " cy=" << camera_intrinsics[OFFSET_PRINCIPAL_POINT_Y];
+
+#define APPEND_DISTORTION_COEFFICIENT(name, offset) \
+  { \
+    if (camera_intrinsics[offset] != 0.0) { \
+      intrinsics_output << " " name "=" << camera_intrinsics[offset];  \
+    } \
+  } (void)0
+
+  APPEND_DISTORTION_COEFFICIENT("k1", OFFSET_K1);
+  APPEND_DISTORTION_COEFFICIENT("k2", OFFSET_K2);
+  APPEND_DISTORTION_COEFFICIENT("k3", OFFSET_K3);
+  APPEND_DISTORTION_COEFFICIENT("p1", OFFSET_P1);
+  APPEND_DISTORTION_COEFFICIENT("p2", OFFSET_P2);
+
+#undef APPEND_DISTORTION_COEFFICIENT
+
+  LOG(INFO) << text << intrinsics_output.str();
+}
+
+// Get a vector of camera's rotations denoted by angle axis
+// conjuncted with translations into single block
+//
+// Element with index i matches to a rotation+translation for
+// camera at image i.
+vector<Vec6> PackCamerasRotationAndTranslation(
+    const vector<Marker> &all_markers,
+    const vector<EuclideanCamera> &all_cameras) {
+  vector<Vec6> all_cameras_R_t;
+  int max_image = MaxImage(all_markers);
+
+  all_cameras_R_t.resize(max_image + 1);
+
+  for (int i = 0; i <= max_image; i++) {
+    const EuclideanCamera *camera = CameraForImage(all_cameras, i);
+
+    if (!camera) {
+      continue;
+    }
+
+    ceres::RotationMatrixToAngleAxis(&camera->R(0, 0),
+                                     &all_cameras_R_t[i](0));
+    all_cameras_R_t[i].tail<3>() = camera->t;
+  }
+
+  return all_cameras_R_t;
+}
+
+// Convert cameras rotations fro mangle axis back to rotation matrix.
+void UnpackCamerasRotationAndTranslation(
+    const vector<Marker> &all_markers,
+    const vector<Vec6> &all_cameras_R_t,
+    vector<EuclideanCamera> *all_cameras) {
+  int max_image = MaxImage(all_markers);
+
+  for (int i = 0; i <= max_image; i++) {
+    EuclideanCamera *camera = CameraForImage(all_cameras, i);
+
+    if (!camera) {
+      continue;
+    }
+
+    ceres::AngleAxisToRotationMatrix(&all_cameras_R_t[i](0),
+                                     &camera->R(0, 0));
+    camera->t = all_cameras_R_t[i].tail<3>();
+  }
+}
+
+void EuclideanBundleCommonIntrinsics(const vector<Marker> &all_markers,
+                                     const int bundle_intrinsics,
+                                     const int bundle_constraints,
+                                     double *camera_intrinsics,
+                                     vector<EuclideanCamera> *all_cameras,
+                                     vector<EuclideanPoint> *all_points) {
+  PrintCameraIntrinsics("Original intrinsics: ", camera_intrinsics);
+
+  ceres::Problem::Options problem_options;
+  ceres::Problem problem(problem_options);
+
+  // Convert cameras rotations to angle axis and merge with translation
+  // into single parameter block for maximal minimization speed
+  //
+  // Block for minimization has got the following structure:
+  //   <3 elements for angle-axis> <3 elements for translation>
+  vector<Vec6> all_cameras_R_t =
+    PackCamerasRotationAndTranslation(all_markers, *all_cameras);
+
+  // Parameterization used to restrict camera motion for modal solvers.
+  ceres::SubsetParameterization *constant_transform_parameterization = NULL;
+  if (bundle_constraints & BUNDLE_NO_TRANSLATION) {
+      std::vector<int> constant_translation;
+
+      // First three elements are rotation, last three are translation.
+      constant_translation.push_back(3);
+      constant_translation.push_back(4);
+      constant_translation.push_back(5);
+
+      constant_transform_parameterization =
+        new ceres::SubsetParameterization(6, constant_translation);
+  }
+
+  int num_residuals = 0;
+  bool have_locked_camera = false;
+  for (int i = 0; i < all_markers.size(); ++i) {
+    const Marker &marker = all_markers[i];
+    EuclideanCamera *camera = CameraForImage(all_cameras, marker.image);
+    EuclideanPoint *point = PointForTrack(all_points, marker.track);
+    if (camera == NULL || point == NULL) {
+      continue;
+    }
+
+    // Rotation of camera denoted in angle axis followed with
+    // camera translaiton.
+    double *current_camera_R_t = &all_cameras_R_t[camera->image](0);
+
+    problem.AddResidualBlock(new ceres::AutoDiffCostFunction<
+        OpenCVReprojectionError, 2, 8, 6, 3>(
+            new OpenCVReprojectionError(
+                marker.x,
+                marker.y)),
+        NULL,
+        camera_intrinsics,
+        current_camera_R_t,
+        &point->X(0));
+
+    // We lock the first camera to better deal with scene orientation ambiguity.
+    if (!have_locked_camera) {
+      problem.SetParameterBlockConstant(current_camera_R_t);
+      have_locked_camera = true;
+    }
+
+    if (bundle_constraints & BUNDLE_NO_TRANSLATION) {
+      problem.SetParameterization(current_camera_R_t,
+                                  constant_transform_parameterization);
+    }
+
+    num_residuals++;
+  }
+  LOG(INFO) << "Number of residuals: " << num_residuals;
+
+  if (!num_residuals) {
+    LOG(INFO) << "Skipping running minimizer with zero residuals";
+    return;
+  }
+
+  BundleIntrinsicsLogMessage(bundle_intrinsics);
+
+  if (bundle_intrinsics == BUNDLE_NO_INTRINSICS) {
+    // No camera intrinsics are being refined,
+    // set the whole parameter block as constant for best performance.
+    problem.SetParameterBlockConstant(camera_intrinsics);
+  } else {
+    // Set the camera intrinsics that are not to be bundled as
+    // constant using some macro trickery.
+
+    std::vector<int> constant_intrinsics;
+#define MAYBE_SET_CONSTANT(bundle_enum, offset) \
+    if (!(bundle_intrinsics & bundle_enum)) { \
+      constant_intrinsics.push_back(offset); \
+    }
+    MAYBE_SET_CONSTANT(BUNDLE_FOCAL_LENGTH,    OFFSET_FOCAL_LENGTH);
+    MAYBE_SET_CONSTANT(BUNDLE_PRINCIPAL_POINT, OFFSET_PRINCIPAL_POINT_X);
+    MAYBE_SET_CONSTANT(BUNDLE_PRINCIPAL_POINT, OFFSET_PRINCIPAL_POINT_Y);
+    MAYBE_SET_CONSTANT(BUNDLE_RADIAL_K1,       OFFSET_K1);
+    MAYBE_SET_CONSTANT(BUNDLE_RADIAL_K2,       OFFSET_K2);
+    MAYBE_SET_CONSTANT(BUNDLE_TANGENTIAL_P1,   OFFSET_P1);
+    MAYBE_SET_CONSTANT(BUNDLE_TANGENTIAL_P2,   OFFSET_P2);
+#undef MAYBE_SET_CONSTANT
+
+    // Always set K3 constant, it's not used at the moment.
+    constant_intrinsics.push_back(OFFSET_K3);
+
+    ceres::SubsetParameterization *subset_parameterization =
+      new ceres::SubsetParameterization(8, constant_intrinsics);
+
+    problem.SetParameterization(camera_intrinsics, subset_parameterization);
+  }
+
+  // Configure the solver.
+  ceres::Solver::Options options;
+  options.use_nonmonotonic_steps = true;
+  options.preconditioner_type = ceres::SCHUR_JACOBI;
+  options.linear_solver_type = ceres::ITERATIVE_SCHUR;
+  options.use_inner_iterations = true;
+  options.max_num_iterations = 100;
+  options.minimizer_progress_to_stdout = true;
+
+  // Solve!
+  ceres::Solver::Summary summary;
+  ceres::Solve(options, &problem, &summary);
+
+  std::cout << "Final report:\n" << summary.FullReport();
+
+  // Copy rotations and translations back.
+  UnpackCamerasRotationAndTranslation(all_markers,
+                                      all_cameras_R_t,
+                                      all_cameras);
+
+  PrintCameraIntrinsics("Final intrinsics: ", camera_intrinsics);
+}
+}  // namespace
+
+int main(int argc, char **argv) {
+  CERES_GFLAGS_NAMESPACE::ParseCommandLineFlags(&argc, &argv, true);
+  google::InitGoogleLogging(argv[0]);
+
+  if (FLAGS_input.empty()) {
+    LOG(ERROR) << "Usage: libmv_bundle_adjuster --input=blender_problem";
+    return EXIT_FAILURE;
+  }
+
+  double camera_intrinsics[8];
+  vector<EuclideanCamera> all_cameras;
+  vector<EuclideanPoint> all_points;
+  bool is_image_space;
+  vector<Marker> all_markers;
+
+  if (!ReadProblemFromFile(FLAGS_input,
+                           camera_intrinsics,
+                           &all_cameras,
+                           &all_points,
+                           &is_image_space,
+                           &all_markers)) {
+    LOG(ERROR) << "Error reading problem file";
+    return EXIT_FAILURE;
+  }
+
+  // If there's no refine_intrinsics passed via command line
+  // (in this case FLAGS_refine_intrinsics will be an empty string)
+  // we use problem's settings to detect whether intrinsics
+  // shall be refined or not.
+  //
+  // Namely, if problem has got markers stored in image (pixel)
+  // space, we do full intrinsics refinement. If markers are
+  // stored in normalized space, and refine_intrinsics is not
+  // set, no refining will happen.
+  //
+  // Using command line argument refine_intrinsics will explicitly
+  // declare which intrinsics need to be refined and in this case
+  // refining flags does not depend on problem at all.
+  int bundle_intrinsics = BUNDLE_NO_INTRINSICS;
+  if (FLAGS_refine_intrinsics.empty()) {
+    if (is_image_space) {
+      bundle_intrinsics = BUNDLE_FOCAL_LENGTH | BUNDLE_RADIAL;
+    }
+  } else {
+    if (FLAGS_refine_intrinsics == "radial") {
+      bundle_intrinsics = BUNDLE_FOCAL_LENGTH | BUNDLE_RADIAL;
+    } else if (FLAGS_refine_intrinsics != "none") {
+      LOG(ERROR) << "Unsupported value for refine-intrinsics";
+      return EXIT_FAILURE;
+    }
+  }
+
+  // Run the bundler.
+  EuclideanBundleCommonIntrinsics(all_markers,
+                                  bundle_intrinsics,
+                                  BUNDLE_NO_CONSTRAINTS,
+                                  camera_intrinsics,
+                                  &all_cameras,
+                                  &all_points);
+
+  return EXIT_SUCCESS;
+}
