diff --git a/include/usgscsm/Utilities.h b/include/usgscsm/Utilities.h
index a7b1b7606506fec497df472358e9705ee187b6e8..4776edf480d3b74a76cfa80a117ed595a219afb5 100644
--- a/include/usgscsm/Utilities.h
+++ b/include/usgscsm/Utilities.h
@@ -4,23 +4,28 @@
 #include <vector>
 #include <math.h>
 #include <tuple>
+#include <string>
+
+#include <json.hpp>
+
+#include <Warning.h>
 
 // methods pulled out of los2ecf and computeViewingPixel
 
-// for now, put everything in here. 
+// for now, put everything in here.
 // TODO: later, consider if it makes sense to pull sample/line offsets out
 // Compute distorted focalPlane coordinates in mm
 std::tuple<double, double> computeDistortedFocalPlaneCoordinates(
   const double& line,
   const double& sample,
   const double& sampleOrigin,
-  const double& lineOrigin, 
+  const double& lineOrigin,
   const double& sampleSumming,
   const double& startingSample,
   const double& lineOffset,
   const double iTransS[],
   const double iTransL[]);
-    
+
 void calculateRotationMatrixFromQuaternions(
   double quaternions[4],
   double cameraToBody[9]);
@@ -40,9 +45,44 @@ void createCameraLookVector(
 
 //void calculateAttitudeCorrection(
 //  const double& time,
-//  
+//
 //  double attCorr[9]);
 //
 
-#endif
+// Methods for checking/accessing the ISD
+
+double metric_conversion(double val, std::string from, std::string to="m");
+std::string getSensorModelName(nlohmann::json isd, csm::WarningList *list=nullptr);
+std::string getImageId(nlohmann::json isd, csm::WarningList *list=nullptr);
+std::string getSensorName(nlohmann::json isd, csm::WarningList *list=nullptr);
+std::string getPlatformName(nlohmann::json isd, csm::WarningList *list=nullptr);
+int getTotalLines(nlohmann::json isd, csm::WarningList *list=nullptr);
+int getTotalSamples(nlohmann::json isd, csm::WarningList *list=nullptr);
+double getStartingTime(nlohmann::json isd, csm::WarningList *list=nullptr);
+double getCenterTime(nlohmann::json isd, csm::WarningList *list=nullptr);
+std::vector<double> getIntegrationStartLines(nlohmann::json isd, csm::WarningList *list=nullptr);
+std::vector<double> getIntegrationStartTimes(nlohmann::json isd, csm::WarningList *list=nullptr);
+std::vector<double> getIntegrationTimes(nlohmann::json isd, csm::WarningList *list=nullptr);
+int getSampleSumming(nlohmann::json isd, csm::WarningList *list=nullptr);
+int getLineSumming(nlohmann::json isd, csm::WarningList *list=nullptr);
+double getFocalLength(nlohmann::json isd, csm::WarningList *list=nullptr);
+double getFocalLengthEpsilon(nlohmann::json isd, csm::WarningList *list=nullptr);
+std::vector<double> getFocal2PixelLines(nlohmann::json isd, csm::WarningList *list=nullptr);
+std::vector<double> getFocal2PixelSamples(nlohmann::json isd, csm::WarningList *list=nullptr);
+double getDetectorCenterLine(nlohmann::json isd, csm::WarningList *list=nullptr);
+double getDetectorCenterSample(nlohmann::json isd, csm::WarningList *list=nullptr);
+double getDetectorStartingLine(nlohmann::json isd, csm::WarningList *list=nullptr);
+double getDetectorStartingSample(nlohmann::json isd, csm::WarningList *list=nullptr);
+double getMinHeight(nlohmann::json isd, csm::WarningList *list=nullptr);
+double getMaxHeight(nlohmann::json isd, csm::WarningList *list=nullptr);
+double getSemiMajorRadius(nlohmann::json isd, csm::WarningList *list=nullptr);
+double getSemiMinorRadius(nlohmann::json isd, csm::WarningList *list=nullptr);
+std::vector<double> getTransverseDistortionX(nlohmann::json isd, csm::WarningList *list=nullptr);
+std::vector<double> getTransverseDistortionY(nlohmann::json isd, csm::WarningList *list=nullptr);
+std::vector<double> getRadialDistortion(nlohmann::json isd, csm::WarningList *list=nullptr);
+std::vector<double> getSunPositions(nlohmann::json isd, csm::WarningList *list=nullptr);
+std::vector<double> getSensorPositions(nlohmann::json isd, csm::WarningList *list=nullptr);
+std::vector<double> getSensorVelocities(nlohmann::json isd, csm::WarningList *list=nullptr);
+std::vector<double> getSensorOrientations(nlohmann::json isd, csm::WarningList *list=nullptr);
 
+#endif
diff --git a/src/UsgsAstroFrameSensorModel.cpp b/src/UsgsAstroFrameSensorModel.cpp
index ca233c8be1d386da66118c5ae98fcf00ce25f248..71176369c3d202bb1246bd90a03b540dee333ea9 100644
--- a/src/UsgsAstroFrameSensorModel.cpp
+++ b/src/UsgsAstroFrameSensorModel.cpp
@@ -1,5 +1,4 @@
 #include "UsgsAstroFrameSensorModel.h"
-#include "Distortion.h"
 
 #include <iomanip>
 #include <iostream>
@@ -10,6 +9,9 @@
 #include <Error.h>
 #include <Version.h>
 
+#include "Distortion.h"
+#include "Utilities.h"
+
 using json = nlohmann::json;
 using namespace std;
 
@@ -791,156 +793,120 @@ void UsgsAstroFrameSensorModel::replaceModelState(const std::string& stringState
 
 
 std::string UsgsAstroFrameSensorModel::constructStateFromIsd(const std::string& jsonIsd, csm::WarningList* warnings) {
-    auto metric_conversion = [](double val, std::string from, std::string to="m") {
-        json typemap = {
-          {"m", 0},
-          {"km", 3}
-        };
-
-        // everything to lowercase
-        std::transform(from.begin(), from.end(), from.begin(), ::tolower);
-        std::transform(to.begin(), to.end(), to.begin(), ::tolower);
-        return val*pow(10, typemap[from].get<int>() - typemap[to].get<int>());
-    };
 
     json isd = json::parse(jsonIsd);
     json state = {};
 
+    csm::WarningList* parsingWarnings = new csm::WarningList;
 
-    try {
-      state["m_modelName"] = isd.at("name_model");
-      state["m_imageIdentifier"] = isd.at("image_identifier");
-      state["m_sensorName"] = isd.at("name_sensor");
-      state["m_platformName"] = isd.at("name_platform");
-      std::cerr << "Model Name Parsed!" << std::endl;
-
-      state["m_startingDetectorSample"] = isd.at("starting_detector_sample");
-      state["m_startingDetectorLine"] = isd.at("starting_detector_line");
-
-      std::cerr << "Detector Starting Pixel Parsed!" << std::endl;
+    state["m_modelName"] = getSensorModelName(isd, parsingWarnings);
+    state["m_imageIdentifier"] = getImageId(isd, parsingWarnings);
+    state["m_sensorName"] = getSensorName(isd, parsingWarnings);
+    state["m_platformName"] = getPlatformName(isd, parsingWarnings);
+    std::cerr << "Model Name Parsed!" << std::endl;
 
-      // get focal length
-      {
-        json jayson = isd.at("focal_length_model");
-        json focal_length = jayson.at("focal_length");
-        json epsilon = jayson.at("focal_epsilon");
+    state["m_startingDetectorSample"] = getDetectorStartingSample(isd, parsingWarnings);
+    state["m_startingDetectorLine"] = getDetectorStartingLine(isd, parsingWarnings);
 
-        state["m_focalLength"] = focal_length;
-        state["m_focalLengthEpsilon"] = epsilon;
+    std::cerr << "Detector Starting Pixel Parsed!" << std::endl;
 
-        std::cerr << "Focal Length Parsed!" << std::endl;
-      }
-
-      // get sensor_position
-      {
-        json jayson = isd.at("sensor_position");
-        json positions = jayson.at("positions")[0];
-        json velocities = jayson.at("velocities")[0];
-        json unit = jayson.at("unit");
-
-        unit = unit.get<std::string>();
-        state["m_currentParameterValue"] = json();
-        state["m_currentParameterValue"][0] = metric_conversion(positions[0].get<double>(), unit);
-        state["m_currentParameterValue"][1] = metric_conversion(positions[1].get<double>(), unit);
-        state["m_currentParameterValue"][2] = metric_conversion(positions[2].get<double>(), unit);
-        state["m_spacecraftVelocity"] = velocities;
-
-        std::cerr << "Sensor Location Parsed!" << std::endl;
-      }
+    // get focal length
+    state["m_focalLength"] = getFocalLength(isd, parsingWarnings);
+    state["m_focalLengthEpsilon"] = getFocalLengthEpsilon(isd, parsingWarnings);
 
-      // get sun_position
-      // sun position is not strictly necessary, but is required for getIlluminationDirection.
-      {
-        json jayson = isd.at("sun_position");
-        json positions = jayson.at("positions")[0];
-        json unit = jayson.at("unit");
+    std::cerr << "Focal Length Parsed!" << std::endl;
 
-        unit = unit.get<std::string>();
-        state["m_sunPosition"] = json();
-        state["m_sunPosition"][0] = metric_conversion(positions[0].get<double>(), unit);
-        state["m_sunPosition"][1] = metric_conversion(positions[1].get<double>(), unit);
-        state["m_sunPosition"][2] = metric_conversion(positions[2].get<double>(), unit);
-
-        std::cerr << "Sun Position Parsed!" << std::endl;
-      }
+    state["m_currentParameterValue"] = json();
 
-      // get sensor_orientation quaternion
-      {
-        json jayson = isd.at("sensor_orientation");
-        json quaternion = jayson.at("quaternions")[0];
-
-        state["m_currentParameterValue"][3] = quaternion[0];
-        state["m_currentParameterValue"][4] = quaternion[1];
-        state["m_currentParameterValue"][5] = quaternion[2];
-        state["m_currentParameterValue"][6] = quaternion[3];
+    // get sensor_position
+    std::vector<double> position = getSensorPositions(isd, parsingWarnings);
+    if (!position.empty() && position.size() != 3) {
+      parsingWarnings->push_back(
+        csm::Warning(
+          csm::Warning::DATA_NOT_AVAILABLE,
+          "Sensor position does not have 3 values.",
+          "UsgsAstroFrameSensorModel::constructStateFromIsd()"));
+      state["m_currentParameterValue"][0] = 0;
+      state["m_currentParameterValue"][1] = 0;
+      state["m_currentParameterValue"][2] = 0;
+    }
+    else {
+      state["m_currentParameterValue"] = position;
+    }
 
-        std::cerr << "Sensor Orientation Parsed!" << std::endl;
-      }
+    // get sensor_velocity
+    std::vector<double> velocity = getSensorVelocities(isd, parsingWarnings);
+    if (!velocity.empty() && velocity.size() != 3) {
+      parsingWarnings->push_back(
+        csm::Warning(
+          csm::Warning::DATA_NOT_AVAILABLE,
+          "Sensor velocity does not have 3 values.",
+          "UsgsAstroFrameSensorModel::constructStateFromIsd()"));
+    }
+    else {
+      state["m_spacecraftVelocity"] = velocity;
+    }
 
-      // get optical_distortion
-      {
-        json jayson = isd.at("optical_distortion");
-        std::vector<double> xDistortion = jayson.at("transverse").at("x");
-        std::vector<double> yDistortion = jayson.at("transverse").at("y");
-        xDistortion.resize(10, 0.0);
-        yDistortion.resize(10, 0.0);
+    std::cerr << "Sensor Location Parsed!" << std::endl;
 
-        state["m_odtX"] = xDistortion;
-        state["m_odtY"] = yDistortion;
+    // get sun_position
+    // sun position is not strictly necessary, but is required for getIlluminationDirection.
+    state["m_sunPosition"] = getSunPositions(isd);
 
-        std::cerr << "Distortion Parsed!" << std::endl;
-      }
+    std::cerr << "Sun Position Parsed!" << std::endl;
 
-      // get detector_center
-      {
-        json jayson = isd.at("detector_center");
-        json sample = jayson.at("sample");
-        json line = jayson.at("line");
+    // get sensor_orientation quaternion
+    std::vector<double> quaternion = getSensorOrientations(isd, parsingWarnings);
+    if (!quaternion.empty() && quaternion.size() != 4) {
+      parsingWarnings->push_back(
+        csm::Warning(
+          csm::Warning::DATA_NOT_AVAILABLE,
+          "Sensor orientation quaternion does not have 4 values.",
+          "UsgsAstroFrameSensorModel::constructStateFromIsd()"));
+    }
+    else {
+      state["m_currentParameterValue"][3] = quaternion[0];
+      state["m_currentParameterValue"][4] = quaternion[1];
+      state["m_currentParameterValue"][5] = quaternion[2];
+      state["m_currentParameterValue"][6] = quaternion[3];
+    }
 
-        state["m_ccdCenter"][0] = line;
-        state["m_ccdCenter"][1] = sample;
+    std::cerr << "Sensor Orientation Parsed!" << std::endl;
 
-        std::cerr << "Detector Center Parsed!" << std::endl;
-      }
+    // get optical_distortion
+    state["m_odtX"] = getTransverseDistortionX(isd, parsingWarnings);
+    state["m_odtY"] = getTransverseDistortionY(isd, parsingWarnings);
 
-      // get radii
-      {
-        json jayson = isd.at("radii");
-        json semiminor = jayson.at("semiminor");
-        json semimajor = jayson.at("semimajor");
-        json unit = jayson.at("unit");
+    std::cerr << "Distortion Parsed!" << std::endl;
 
-        unit = unit.get<std::string>();
-        state["m_minorAxis"] = metric_conversion(semiminor.get<double>(), unit);
-        state["m_majorAxis"] = metric_conversion(semimajor.get<double>(), unit);
+    // get detector_center
+    state["m_ccdCenter"][0] = getDetectorCenterLine(isd, parsingWarnings);
+    state["m_ccdCenter"][1] = getDetectorCenterSample(isd, parsingWarnings);
 
-        std::cerr << "Target Radii Parsed!" << std::endl;
-      }
+    std::cerr << "Detector Center Parsed!" << std::endl;
 
-      // get reference_height
-      {
-        json reference_height = isd.at("reference_height");
-        json maxheight = reference_height.at("maxheight");
-        json minheight = reference_height.at("minheight");
-        json unit = reference_height.at("unit");
+    // get radii
+    state["m_minorAxis"] = getSemiMinorRadius(isd, parsingWarnings);
+    state["m_majorAxis"] = getSemiMajorRadius(isd, parsingWarnings);
 
-        unit = unit.get<std::string>();
-        state["m_minElevation"] = metric_conversion(minheight.get<double>(), unit);
-        state["m_maxElevation"] = metric_conversion(maxheight.get<double>(), unit);
+    std::cerr << "Target Radii Parsed!" << std::endl;
 
-        std::cerr << "Reference Height Parsed!" << std::endl;
-      }
+    // get reference_height
+    state["m_minElevation"] = getMinHeight(isd, parsingWarnings);
+    state["m_maxElevation"] = getMaxHeight(isd, parsingWarnings);
 
-      state["m_ephemerisTime"] = isd.at("center_ephemeris_time");
-      state["m_nLines"] = isd.at("image_lines");
-      state["m_nSamples"] = isd.at("image_samples");
+    std::cerr << "Reference Height Parsed!" << std::endl;
 
-      state["m_iTransL"] = isd.at("focal2pixel_lines");
+    state["m_ephemerisTime"] = getCenterTime(isd, parsingWarnings);
+    state["m_nLines"] = getTotalLines(isd, parsingWarnings);
+    state["m_nSamples"] = getTotalSamples(isd, parsingWarnings);
 
-      state["m_iTransS"] = isd.at("focal2pixel_samples");
+    state["m_iTransL"] = getFocal2PixelLines(isd, parsingWarnings);
+    state["m_iTransS"] = getFocal2PixelSamples(isd, parsingWarnings);
 
-      // We don't pass the pixel to focal plane transformation so invert the
-      // focal plane to pixel transformation
+    // We don't pass the pixel to focal plane transformation so invert the
+    // focal plane to pixel transformation
+    try {
       double determinant = state["m_iTransL"][1].get<double>() * state["m_iTransS"][2].get<double>() -
                            state["m_iTransL"][2].get<double>() * state["m_iTransS"][1].get<double>();
 
@@ -953,27 +919,37 @@ std::string UsgsAstroFrameSensorModel::constructStateFromIsd(const std::string&
       state["m_transY"][2] =  state["m_iTransS"][2].get<double>() / determinant;
       state["m_transY"][0] = -(state["m_transY"][1].get<double>() * state["m_iTransL"][0].get<double>() +
                                state["m_transY"][2].get<double>() * state["m_iTransS"][0].get<double>());
+    }
+    catch (...) {
+      parsingWarnings->push_back(
+        csm::Warning(
+          csm::Warning::DATA_NOT_AVAILABLE,
+          "Could not compute detector pixel to focal plane coordinate transformation.",
+          "UsgsAstroFrameSensorModel::constructStateFromIsd()"));
+    }
 
-      std::cerr << "Focal To Pixel Transformation Parsed!" << std::endl;
+    std::cerr << "Focal To Pixel Transformation Parsed!" << std::endl;
 
-      state["m_referencePointXyz"] = std::vector<double>(3, 0.0);
-      state["m_currentParameterCovariance"] = std::vector<double>(NUM_PARAMETERS*NUM_PARAMETERS,0.0);
-      state["m_collectionIdentifier"] = "";
+    state["m_referencePointXyz"] = std::vector<double>(3, 0.0);
+    state["m_currentParameterCovariance"] = std::vector<double>(NUM_PARAMETERS*NUM_PARAMETERS,0.0);
+    state["m_collectionIdentifier"] = "";
 
-      std::cerr << "Constants Set!" << std::endl;
+    std::cerr << "Constants Set!" << std::endl;
 
-    }
-    catch(std::out_of_range& e) {
-      throw csm::Error(csm::Error::SENSOR_MODEL_NOT_CONSTRUCTIBLE,
-                       "ISD missing necessary keywords to create sensor model: " + std::string(e.what()),
-                       "UsgsAstroFrameSensorModel::constructStateFromIsd");
-    }
-    catch(...) {
+    if (!parsingWarnings->empty()) {
+      if (warnings) {
+        warnings->insert(warnings->end(), parsingWarnings->begin(), parsingWarnings->end());
+      }
+      delete parsingWarnings;
+      parsingWarnings = nullptr;
       throw csm::Error(csm::Error::SENSOR_MODEL_NOT_CONSTRUCTIBLE,
                        "ISD is invalid for creating the sensor model.",
                        "UsgsAstroFrameSensorModel::constructStateFromIsd");
     }
 
+    delete parsingWarnings;
+    parsingWarnings = nullptr;
+
     return state.dump();
 
 }
diff --git a/src/Utilities.cpp b/src/Utilities.cpp
index e9c82f6cdf766fc760136fea19f3ed9474fa342a..840a3d61922125a09a0b8263fd51ba8222c44c3c 100644
--- a/src/Utilities.cpp
+++ b/src/Utilities.cpp
@@ -1,5 +1,7 @@
 #include "Utilities.h"
 
+using json = nlohmann::json;
+
 // Calculates a rotation matrix from Euler angles
 void calculateRotationMatrixFromEuler(double euler[],
                                       double rotationMatrix[]) {
@@ -45,7 +47,7 @@ std::tuple<double, double> computeDistortedFocalPlaneCoordinates(
   const double& line,
   const double& sample,
   const double& sampleOrigin,
-  const double& lineOrigin, 
+  const double& lineOrigin,
   const double& sampleSumming,
   const double& startingSample,
   const double& lineOffset,
@@ -66,7 +68,7 @@ std::tuple<double, double> computeDistortedFocalPlaneCoordinates(
 
   double distortedLine = p11 * t1 + p12 * t2;
   double distortedSample = p21 * t1 + p22 * t2;
-  return std::make_tuple(distortedLine, distortedSample);  
+  return std::make_tuple(distortedLine, distortedSample);
 };
 
 // Define imaging ray in image space (In other words, create a look vector in camera space)
@@ -88,3 +90,603 @@ void createCameraLookVector(
    cameraLook[1] /= magnitude;
    cameraLook[2] /= magnitude;
 }
+
+double metric_conversion(double val, std::string from, std::string to) {
+    json typemap = {
+      {"m", 0},
+      {"km", 3}
+    };
+
+    // everything to lowercase
+    std::transform(from.begin(), from.end(), from.begin(), ::tolower);
+    std::transform(to.begin(), to.end(), to.begin(), ::tolower);
+    return val*pow(10, typemap[from].get<int>() - typemap[to].get<int>());
+}
+
+std::string getSensorModelName(json isd, csm::WarningList *list) {
+  std::string name = "";
+  try {
+    name = isd.at("name_model");
+  }
+  catch (...) {
+    if (list) {
+      list->push_back(
+        csm::Warning(
+          csm::Warning::DATA_NOT_AVAILABLE,
+          "Could not parse the sensor model name.",
+          "Utilities::getSensorModelName()"));
+    }
+  }
+  return name;
+}
+
+std::string getImageId(json isd, csm::WarningList *list) {
+  std::string id = "";
+  try {
+    id = isd.at("image_identifier");
+  }
+  catch (...) {
+    if (list) {
+      list->push_back(
+        csm::Warning(
+          csm::Warning::DATA_NOT_AVAILABLE,
+          "Could not parse the image identifier.",
+          "Utilities::getImageId()"));
+    }
+  }
+  return id;
+}
+
+std::string getSensorName(json isd, csm::WarningList *list) {
+  std::string name = "";
+  try {
+    name = isd.at("name_sensor");
+  }
+  catch (...) {
+    if (list) {
+      list->push_back(
+        csm::Warning(
+          csm::Warning::DATA_NOT_AVAILABLE,
+          "Could not parse the sensor name.",
+          "Utilities::getSensorName()"));
+    }
+  }
+  return name;
+}
+
+std::string getPlatformName(json isd, csm::WarningList *list) {
+  std::string name = "";
+  try {
+    name = isd.at("name_platform");
+  }
+  catch (...) {
+    if (list) {
+      list->push_back(
+        csm::Warning(
+          csm::Warning::DATA_NOT_AVAILABLE,
+          "Could not parse the platform name.",
+          "Utilities::getPlatformName()"));
+    }
+  }
+  return name;
+}
+
+int getTotalLines(json isd, csm::WarningList *list) {
+  int lines = 0;
+  try {
+    lines = isd.at("image_lines");
+  }
+  catch (...) {
+    if (list) {
+      list->push_back(
+        csm::Warning(
+          csm::Warning::DATA_NOT_AVAILABLE,
+          "Could not parse the number of lines in the image.",
+          "Utilities::getTotalLines()"));
+    }
+  }
+  return lines;
+}
+
+int getTotalSamples(json isd, csm::WarningList *list) {
+  int samples = 0;
+  try {
+    samples = isd.at("image_samples");
+  }
+  catch (...) {
+    if (list) {
+      list->push_back(
+        csm::Warning(
+          csm::Warning::DATA_NOT_AVAILABLE,
+          "Could not parse the number of samples in the image.",
+          "Utilities::getTotalSamples()"));
+    }
+  }
+  return samples;
+}
+
+double getStartingTime(json isd, csm::WarningList *list) {
+    double time = 0.0;
+    try {
+      time = isd.at("starting_ephemeris_time");
+    }
+    catch (...) {
+      if (list) {
+        list->push_back(
+          csm::Warning(
+            csm::Warning::DATA_NOT_AVAILABLE,
+            "Could not parse the image start time.",
+            "Utilities::getStartingTime()"));
+      }
+    }
+    return time;
+}
+
+double getCenterTime(json isd, csm::WarningList *list) {
+  double time = 0.0;
+  try {
+    time = isd.at("center_ephemeris_time");
+  }
+  catch (...) {
+    if (list) {
+      list->push_back(
+        csm::Warning(
+          csm::Warning::DATA_NOT_AVAILABLE,
+          "Could not parse the center image time.",
+          "Utilities::getCenterTime()"));
+    }
+  }
+  return time;
+}
+
+std::vector<double> getIntegrationStartLines(json isd, csm::WarningList *list) {
+  std::vector<double> lines;
+  try {
+    for (auto& scanRate : isd.at("line_scan_rate")) {
+      lines.push_back(scanRate[0]);
+    }
+  }
+  catch (...) {
+    if (list) {
+      list->push_back(
+        csm::Warning(
+          csm::Warning::DATA_NOT_AVAILABLE,
+          "Could not parse the integration start lines in the integration time table.",
+          "Utilities::getIntegrationStartLines()"));
+    }
+  }
+  return lines;
+}
+
+std::vector<double> getIntegrationStartTimes(json isd, csm::WarningList *list) {
+  std::vector<double> times;
+  try {
+    for (auto& scanRate : isd.at("line_scan_rate")) {
+      times.push_back(scanRate[1]);
+    }
+  }
+  catch (...) {
+    if (list) {
+      list->push_back(
+        csm::Warning(
+          csm::Warning::DATA_NOT_AVAILABLE,
+          "Could not parse the integration start times in the integration time table.",
+          "Utilities::getIntegrationStartTimes()"));
+    }
+  }
+  return times;
+}
+
+std::vector<double> getIntegrationTimes(json isd, csm::WarningList *list) {
+  std::vector<double> times;
+  try {
+    for (auto& scanRate : isd.at("line_scan_rate")) {
+      times.push_back(scanRate[2]);
+    }
+  }
+  catch (...) {
+    if (list) {
+      list->push_back(
+        csm::Warning(
+          csm::Warning::DATA_NOT_AVAILABLE,
+          "Could not parse the integration times in the integration time table.",
+          "Utilities::getIntegrationTimes()"));
+    }
+  }
+  return times;
+}
+
+int getSampleSumming(json isd, csm::WarningList *list) {
+  int summing = 0;
+  try {
+    summing = isd.at("detector_sample_summing");
+  }
+  catch (...) {
+    if (list) {
+      list->push_back(
+        csm::Warning(
+          csm::Warning::DATA_NOT_AVAILABLE,
+          "Could not parse the sample direction detector pixel summing.",
+          "Utilities::getSampleSumming()"));
+    }
+  }
+  return summing;
+}
+
+int getLineSumming(json isd, csm::WarningList *list) {
+  int summing = 0;
+  try {
+    summing = isd.at("detector_line_summing");
+  }
+  catch (...) {
+    if (list) {
+      list->push_back(
+        csm::Warning(
+          csm::Warning::DATA_NOT_AVAILABLE,
+          "Could not parse the line direction detector pixel summing.",
+          "Utilities::getLineSumming()"));
+    }
+  }
+  return summing;
+}
+
+double getFocalLength(json isd, csm::WarningList *list) {
+  double length = 0.0;
+  try {
+    length = isd.at("focal_length_model").at("focal_length");
+  }
+  catch (...) {
+    if (list) {
+      list->push_back(
+        csm::Warning(
+          csm::Warning::DATA_NOT_AVAILABLE,
+          "Could not parse the focal length.",
+          "Utilities::getFocalLength()"));
+    }
+  }
+  return length;
+}
+
+double getFocalLengthEpsilon(json isd, csm::WarningList *list) {
+  double epsilon = 0.0;
+  try {
+    epsilon = isd.at("focal_length_model").at("focal_epsilon");
+  }
+  catch (...) {
+    if (list) {
+      list->push_back(
+        csm::Warning(
+          csm::Warning::DATA_NOT_AVAILABLE,
+          "Could not parse the focal length uncertainty.",
+          "Utilities::getFocalLengthEpsilon()"));
+    }
+  }
+  return epsilon;
+}
+
+std::vector<double> getFocal2PixelLines(json isd, csm::WarningList *list) {
+  std::vector<double> transformation;
+  try {
+    transformation = isd.at("focal2pixel_lines").get<std::vector<double>>();
+  }
+  catch (...) {
+    if (list) {
+      list->push_back(
+        csm::Warning(
+          csm::Warning::DATA_NOT_AVAILABLE,
+          "Could not parse the focal plane coordinate to detector lines transformation.",
+          "Utilities::getFocal2PixelLines()"));
+    }
+  }
+  return transformation;
+}
+
+std::vector<double> getFocal2PixelSamples(json isd, csm::WarningList *list) {
+  std::vector<double> transformation;
+  try {
+    transformation = isd.at("focal2pixel_samples").get<std::vector<double>>();
+  }
+  catch (...) {
+    if (list) {
+      list->push_back(
+        csm::Warning(
+          csm::Warning::DATA_NOT_AVAILABLE,
+          "Could not parse the focal plane coordinate to detector samples transformation.",
+          "Utilities::getFocal2PixelSamples()"));
+    }
+  }
+  return transformation;
+}
+
+double getDetectorCenterLine(json isd, csm::WarningList *list) {
+  double line;
+  try {
+    line = isd.at("detector_center").at("line");
+  }
+  catch (...) {
+    if (list) {
+      list->push_back(
+        csm::Warning(
+          csm::Warning::DATA_NOT_AVAILABLE,
+          "Could not parse the detector center line.",
+          "Utilities::getDetectorCenterLine()"));
+    }
+  }
+  return line;
+}
+
+double getDetectorCenterSample(json isd, csm::WarningList *list) {
+  double sample;
+  try {
+    sample = isd.at("detector_center").at("sample");
+  }
+  catch (...) {
+    if (list) {
+      list->push_back(
+        csm::Warning(
+          csm::Warning::DATA_NOT_AVAILABLE,
+          "Could not parse the detector center sample.",
+          "Utilities::getDetectorCenterSample()"));
+    }
+  }
+  return sample;
+}
+
+
+double getDetectorStartingLine(json isd, csm::WarningList *list) {
+  double line;
+  try {
+    line = isd.at("starting_detector_line");
+  }
+  catch (...) {
+    if (list) {
+      list->push_back(
+        csm::Warning(
+          csm::Warning::DATA_NOT_AVAILABLE,
+          "Could not parse the detector starting line.",
+          "Utilities::getDetectorStartingLine()"));
+    }
+  }
+  return line;
+}
+
+double getDetectorStartingSample(json isd, csm::WarningList *list) {
+  double sample;
+  try {
+    sample = isd.at("starting_detector_sample");
+  }
+  catch (...) {
+    if (list) {
+      list->push_back(
+        csm::Warning(
+          csm::Warning::DATA_NOT_AVAILABLE,
+          "Could not parse the detector starting sample.",
+          "Utilities::getDetectorStartingSample()"));
+    }
+  }
+  return sample;
+}
+
+double getMinHeight(json isd, csm::WarningList *list) {
+  double height = 0.0;
+  try {
+    json referenceHeight = isd.at("reference_height");
+    json minHeight = referenceHeight.at("minheight");
+    json unit = referenceHeight.at("unit");
+    height = metric_conversion(minHeight.get<double>(), unit.get<std::string>());
+  }
+  catch (...) {
+    if (list) {
+      list->push_back(
+        csm::Warning(
+          csm::Warning::DATA_NOT_AVAILABLE,
+          "Could not parse the minimum height above the reference ellipsoid.",
+          "Utilities::getMinHeight()"));
+    }
+  }
+  return height;
+}
+
+double getMaxHeight(json isd, csm::WarningList *list) {
+  double height = 0.0;
+  try {
+    json referenceHeight = isd.at("reference_height");
+    json maxHeight = referenceHeight.at("maxheight");
+    json unit = referenceHeight.at("unit");
+    height = metric_conversion(maxHeight.get<double>(), unit.get<std::string>());
+  }
+  catch (...) {
+    if (list) {
+      list->push_back(
+        csm::Warning(
+          csm::Warning::DATA_NOT_AVAILABLE,
+          "Could not parse the maximum height above the reference ellipsoid.",
+          "Utilities::getMaxHeight()"));
+    }
+  }
+  return height;
+}
+
+double getSemiMajorRadius(json isd, csm::WarningList *list) {
+  double radius = 0.0;
+  try {
+    json radii = isd.at("radii");
+    json semiMajor = radii.at("semimajor");
+    json unit = radii.at("unit");
+    radius = metric_conversion(semiMajor.get<double>(), unit.get<std::string>());
+  }
+  catch (...) {
+    if (list) {
+      list->push_back(
+        csm::Warning(
+          csm::Warning::DATA_NOT_AVAILABLE,
+          "Could not parse the reference ellipsoid semimajor radius.",
+          "Utilities::getSemiMajorRadius()"));
+    }
+  }
+  return radius;
+}
+
+double getSemiMinorRadius(json isd, csm::WarningList *list) {
+  double radius = 0.0;
+  try {
+    json radii = isd.at("radii");
+    json semiMinor = radii.at("semiminor");
+    json unit = radii.at("unit");
+    radius = metric_conversion(semiMinor.get<double>(), unit.get<std::string>());
+  }
+  catch (...) {
+    if (list) {
+      list->push_back(
+        csm::Warning(
+          csm::Warning::DATA_NOT_AVAILABLE,
+          "Could not parse the reference ellipsoid semiminor radius.",
+          "Utilities::getSemiMinorRadius()"));
+    }
+  }
+  return radius;
+}
+
+std::vector<double> getTransverseDistortionX(json isd, csm::WarningList *list) {
+  std::vector<double> coefficients;
+  try {
+    coefficients = isd.at("optical_distortion").at("transverse").at("x").get<std::vector<double>>();
+    coefficients.resize(10, 0.0);
+  }
+  catch (...) {
+    if (list) {
+      list->push_back(
+        csm::Warning(
+          csm::Warning::DATA_NOT_AVAILABLE,
+          "Could not parse the transverse distortion model X coefficients.",
+          "Utilities::getTransverseDistortionX()"));
+    }
+  }
+  return coefficients;
+}
+
+std::vector<double> getTransverseDistortionY(json isd, csm::WarningList *list) {
+  std::vector<double> coefficients;
+  try {
+    coefficients = isd.at("optical_distortion").at("transverse").at("y").get<std::vector<double>>();
+    coefficients.resize(10, 0.0);
+  }
+  catch (...) {
+    if (list) {
+      list->push_back(
+        csm::Warning(
+          csm::Warning::DATA_NOT_AVAILABLE,
+          "Could not parse the transverse distortion model Y coefficients.",
+          "Utilities::getTransverseDistortionY()"));
+    }
+  }
+  return coefficients;
+}
+
+std::vector<double> getRadialDistortion(json isd, csm::WarningList *list) {
+  std::vector<double> coefficients;
+  try {
+    coefficients = isd.at("optical_distortion").at("radial").at("coefficients").get<std::vector<double>>();
+  }
+  catch (...) {
+    if (list) {
+      list->push_back(
+        csm::Warning(
+          csm::Warning::DATA_NOT_AVAILABLE,
+          "Could not parse the radial distortion model coefficients.",
+          "Utilities::getRadialDistortion()"));
+    }
+  }
+  return coefficients;
+}
+
+std::vector<double> getSunPositions(json isd, csm::WarningList *list) {
+  std::vector<double> positions;
+  try {
+    json jayson = isd.at("sun_position");
+    json unit = jayson.at("unit");
+    for (auto& location : jayson.at("positions")) {
+      positions.push_back(metric_conversion(location[0].get<double>(), unit.get<std::string>()));
+      positions.push_back(metric_conversion(location[1].get<double>(), unit.get<std::string>()));
+      positions.push_back(metric_conversion(location[2].get<double>(), unit.get<std::string>()));
+    }
+  }
+  catch (...) {
+    if (list) {
+      list->push_back(
+        csm::Warning(
+          csm::Warning::DATA_NOT_AVAILABLE,
+          "Could not parse the sun positions.",
+          "Utilities::getSunPositions()"));
+    }
+  }
+  return positions;
+}
+
+std::vector<double> getSensorPositions(json isd, csm::WarningList *list) {
+  std::vector<double> positions;
+  try {
+    json jayson = isd.at("sensor_position");
+    json unit = jayson.at("unit");
+    for (auto& location : jayson.at("positions")) {
+      positions.push_back(metric_conversion(location[0].get<double>(), unit.get<std::string>()));
+      positions.push_back(metric_conversion(location[1].get<double>(), unit.get<std::string>()));
+      positions.push_back(metric_conversion(location[2].get<double>(), unit.get<std::string>()));
+    }
+  }
+  catch (...) {
+    if (list) {
+      list->push_back(
+        csm::Warning(
+          csm::Warning::DATA_NOT_AVAILABLE,
+          "Could not parse the sensor positions.",
+          "Utilities::getSensorPositions()"));
+    }
+  }
+  return positions;
+}
+
+std::vector<double> getSensorVelocities(json isd, csm::WarningList *list) {
+  std::vector<double> velocities;
+  try {
+    json jayson = isd.at("sensor_position");
+    json unit = jayson.at("unit");
+    for (auto& velocity : jayson.at("velocities")) {
+      velocities.push_back(metric_conversion(velocity[0].get<double>(), unit.get<std::string>()));
+      velocities.push_back(metric_conversion(velocity[1].get<double>(), unit.get<std::string>()));
+      velocities.push_back(metric_conversion(velocity[2].get<double>(), unit.get<std::string>()));
+    }
+  }
+  catch (...) {
+    if (list) {
+      list->push_back(
+        csm::Warning(
+          csm::Warning::DATA_NOT_AVAILABLE,
+          "Could not parse the sensor velocities.",
+          "Utilities::getSensorVelocities()"));
+    }
+  }
+  return velocities;
+}
+
+std::vector<double> getSensorOrientations(json isd, csm::WarningList *list) {
+  std::vector<double> quaternions;
+  try {
+    for (auto& quaternion : isd.at("sensor_orientation").at("quaternions")) {
+      quaternions.push_back(quaternion[0]);
+      quaternions.push_back(quaternion[1]);
+      quaternions.push_back(quaternion[2]);
+      quaternions.push_back(quaternion[3]);
+     }
+  }
+  catch (...) {
+    if (list) {
+      list->push_back(
+        csm::Warning(
+          csm::Warning::DATA_NOT_AVAILABLE,
+          "Could not parse the sensor orientations.",
+          "Utilities::getSensorOrientations()"));
+    }
+  }
+  return quaternions;
+}
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index e3567d19534610f1ae123066eba4fd99a9a3720e..3306376a11e7477ba008192ebfda67ebc3b71742 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -5,7 +5,8 @@ add_executable(runCSMCameraModelTests
                PluginTests.cpp
                FrameCameraTests.cpp
                LineScanCameraTests.cpp
-               DistortionTests.cpp)
+               DistortionTests.cpp
+               ISDParsingTests.cpp)
 if(WIN32)
   option(CMAKE_USE_WIN32_THREADS_INIT "using WIN32 threads" ON)
   option(gtest_disable_pthreads "Disable uses of pthreads in gtest." ON)
diff --git a/tests/ISDParsingTests.cpp b/tests/ISDParsingTests.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..c2976e3e902d082f4f75cee84bade8f9ea2d7c81
--- /dev/null
+++ b/tests/ISDParsingTests.cpp
@@ -0,0 +1,323 @@
+#include "Utilities.h"
+
+#include <gtest/gtest.h>
+
+#include "Fixtures.h"
+
+TEST(MetricConversion, DistanceConversion) {
+  EXPECT_EQ(1,     metric_conversion(1000, "m", "km"));
+  EXPECT_EQ(1000,  metric_conversion(1000, "m", "m"));
+  EXPECT_EQ(1000,  metric_conversion(1, "km", "m"));
+  EXPECT_EQ(1,     metric_conversion(1, "km", "km"));
+  EXPECT_EQ(0,     metric_conversion(0, "m", "km"));
+  EXPECT_EQ(0,     metric_conversion(0, "m", "m"));
+  EXPECT_EQ(0,     metric_conversion(0, "km", "m"));
+  EXPECT_EQ(0,     metric_conversion(0, "km", "km"));
+  EXPECT_EQ(-1,    metric_conversion(-1000, "m", "km"));
+  EXPECT_EQ(-1000, metric_conversion(-1000, "m", "m"));
+  EXPECT_EQ(-1000, metric_conversion(-1, "km", "m"));
+  EXPECT_EQ(-1,    metric_conversion(-1, "km", "km"));
+}
+
+TEST(ISDParsing, ModelName) {
+  json isd = {
+    {"name_model", "Test"}
+  };
+  EXPECT_EQ("Test", getSensorModelName(isd));
+}
+
+TEST(ISDParsing, ImageIdentifier) {
+  json isd = {
+    {"image_identifier", "Test"}
+  };
+  EXPECT_EQ("Test", getImageId(isd));
+}
+
+TEST(ISDParsing, SensorName) {
+  json isd = {
+    {"name_sensor", "Test"}
+  };
+  EXPECT_EQ("Test", getSensorName(isd));
+}
+
+TEST(ISDParsing, PlatformName) {
+  json isd = {
+    {"name_platform", "Test"}
+  };
+  EXPECT_EQ("Test", getPlatformName(isd));
+}
+
+TEST(ISDParsing, TotalLines) {
+  json isd = {
+    {"image_lines", 16}
+  };
+  EXPECT_EQ(16, getTotalLines(isd));
+}
+
+TEST(ISDParsing, TotalSamples) {
+  json isd = {
+    {"image_samples", 16}
+  };
+  EXPECT_EQ(16, getTotalSamples(isd));
+}
+
+TEST(ISDParsing, StartTime) {
+  json isd = {
+    {"starting_ephemeris_time", -10}
+  };
+  EXPECT_EQ(-10, getStartingTime(isd));
+}
+
+TEST(ISDParsing, CenterTime) {
+  json isd = {
+    {"center_ephemeris_time", -10}
+  };
+  EXPECT_EQ(-10, getCenterTime(isd));
+}
+
+TEST(ISDParsing, IntegrationStartLines) {
+  json isd = {
+    {"line_scan_rate", {
+      {0, 1, 2},
+      {3, 4, 5},
+      {6, 7, 8}}
+    }
+  };
+  std::vector<double> startLines = {0, 3, 6};
+  EXPECT_EQ(startLines, getIntegrationStartLines(isd));
+}
+
+TEST(ISDParsing, IntegrationStartTimes) {
+  json isd = {
+    {"line_scan_rate", {
+      {0, 1, 2},
+      {3, 4, 5},
+      {6, 7, 8}}
+    }
+  };
+  std::vector<double> startTimes = {1, 4, 7};
+  EXPECT_EQ(startTimes, getIntegrationStartTimes(isd));
+}
+
+TEST(ISDParsing, IntegrationTimes) {
+  json isd = {
+    {"line_scan_rate", {
+      {0, 1, 2},
+      {3, 4, 5},
+      {6, 7, 8}}
+    }
+  };
+  std::vector<double> times = {2, 5, 8};
+  EXPECT_EQ(times, getIntegrationTimes(isd));
+}
+
+TEST(ISDParsing, SampleSumming) {
+  json isd = {
+    {"detector_sample_summing", 4}
+  };
+  EXPECT_EQ(4, getSampleSumming(isd));
+}
+
+TEST(ISDParsing, LineSumming) {
+  json isd = {
+    {"detector_line_summing", 4}
+  };
+  EXPECT_EQ(4, getLineSumming(isd));
+}
+
+TEST(ISDParsing, FocalLength) {
+  json isd = {
+    {"focal_length_model", {
+      {"focal_length", 2}}
+    }
+  };
+  EXPECT_EQ(2, getFocalLength(isd));
+}
+
+TEST(ISDParsing, FocalLengthEpsilon) {
+  json isd = {
+    {"focal_length_model", {
+      {"focal_epsilon", 0.1}}
+    }
+  };
+  EXPECT_EQ(0.1, getFocalLengthEpsilon(isd));
+}
+
+TEST(ISDParsing, Focal2PixelLines) {
+  json isd = {
+    {"focal2pixel_lines", {0, 1, 2}}
+  };
+  std::vector<double> coefficients = {0, 1, 2};
+  EXPECT_EQ(coefficients, getFocal2PixelLines(isd));
+}
+
+TEST(ISDParsing, Focal2PixelSamples) {
+  json isd = {
+    {"focal2pixel_samples", {0, 1, 2}}
+  };
+  std::vector<double> coefficients = {0, 1, 2};
+  EXPECT_EQ(coefficients, getFocal2PixelSamples(isd));
+}
+
+TEST(ISDParsing, DetectorCenterLine) {
+  json isd = {
+    {"detector_center", {
+      {"line", 2}}
+    }
+  };
+  EXPECT_EQ(2, getDetectorCenterLine(isd));
+}
+
+TEST(ISDParsing, DetectorCenterSample) {
+  json isd = {
+    {"detector_center", {
+      {"sample", 3}}
+    }
+  };
+  EXPECT_EQ(3, getDetectorCenterSample(isd));
+}
+
+TEST(ISDParsing, DetectorStartingLine) {
+  json isd = {
+    {"starting_detector_line", 1}
+  };
+  EXPECT_EQ(1, getDetectorStartingLine(isd));
+}
+
+TEST(ISDParsing, DetectorStartingSample) {
+  json isd = {
+    {"starting_detector_sample", 2}
+  };
+  EXPECT_EQ(2, getDetectorStartingSample(isd));
+}
+
+TEST(ISDParsing, MinHeight) {
+  json isd = {
+    {"reference_height", {
+      {"minheight", -1},
+      {"unit", "km"}}
+    }
+  };
+  EXPECT_EQ(-1000, getMinHeight(isd));
+}
+
+TEST(ISDParsing, MaxHeight) {
+  json isd = {
+    {"reference_height", {
+      {"maxheight", 10},
+      {"unit", "km"}}
+    }
+  };
+  EXPECT_EQ(10000, getMaxHeight(isd));
+}
+
+TEST(ISDParsing, SemiMajor) {
+  json isd = {
+    {"radii", {
+      {"semimajor", 2},
+      {"unit", "km"}}
+    }
+  };
+  EXPECT_EQ(2000, getSemiMajorRadius(isd));
+}
+
+TEST(ISDParsing, SemiMinor) {
+  json isd = {
+    {"radii", {
+      {"semiminor", 1},
+      {"unit", "km"}}
+    }
+  };
+  EXPECT_EQ(1000, getSemiMinorRadius(isd));
+}
+
+TEST(ISDParsing, TransverseX) {
+  json isd = {
+    {"optical_distortion", {
+      {"transverse", {
+        {"x", {-1, 2, 4}}}}
+      }
+    }
+  };
+  std::vector<double> coefficients = {-1, 2, 4, 0, 0, 0, 0, 0, 0, 0};
+  EXPECT_EQ(coefficients, getTransverseDistortionX(isd));
+}
+
+TEST(ISDParsing, TransverseY) {
+  json isd = {
+    {"optical_distortion", {
+      {"transverse", {
+        {"y", {-11, 21, 24, 16, 20}}}}
+      }
+    }
+  };
+  std::vector<double> coefficients = {-11, 21, 24, 16, 20, 0, 0, 0, 0, 0};
+  EXPECT_EQ(coefficients, getTransverseDistortionY(isd));
+}
+
+TEST(ISDParsing, Radial) {
+  json isd = {
+    {"optical_distortion", {
+      {"radial", {
+        {"coefficients", {0, 1, 2}}}}
+      }
+    }
+  };
+  std::vector<double> coefficients = {0, 1, 2};
+  EXPECT_EQ(coefficients, getRadialDistortion(isd));
+}
+
+TEST(ISDParsing, SunPosition) {
+  json isd = {
+    {"sun_position", {
+      {"positions", {
+        {0, 1, 2},
+        {3, 4, 5},
+        {6, 7, 8}}},
+      {"unit", "km"}}
+    }
+  };
+  std::vector<double> positions = {0, 1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000};
+  EXPECT_EQ(positions, getSunPositions(isd));
+}
+
+TEST(ISDParsing, SensorPosition) {
+  json isd = {
+    {"sensor_position", {
+      {"positions", {
+        {0, 1, 2},
+        {3, 4, 5},
+        {6, 7, 8}}},
+      {"unit", "km"}}
+    }
+  };
+  std::vector<double> positions = {0, 1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000};
+  EXPECT_EQ(positions, getSensorPositions(isd));
+}
+
+TEST(ISDParsing, SensorVelocities) {
+  json isd = {
+    {"sensor_position", {
+      {"velocities", {
+        {0, 1, 2},
+        {3, 4, 5},
+        {6, 7, 8}}},
+      {"unit", "km"}}
+    }
+  };
+  std::vector<double> velocity = {0, 1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000};
+  EXPECT_EQ(velocity, getSensorVelocities(isd));
+}
+
+TEST(ISDParsing, SensorOrientations) {
+  json isd = {
+    {"sensor_orientation", {
+      {"quaternions", {
+        {0, 1, 2, 3},
+        {4, 5, 6, 7},
+        {8, 9, 10, 11}}}}
+    }
+  };
+  std::vector<double> rotations = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11};
+  EXPECT_EQ(rotations, getSensorOrientations(isd));
+}
diff --git a/tests/PluginTests.cpp b/tests/PluginTests.cpp
index 2252e8851dc5d0685f51d55a3458e16f8393c7d4..f805a8c0eac100d48adf4861e64ccbffa7811ec1 100644
--- a/tests/PluginTests.cpp
+++ b/tests/PluginTests.cpp
@@ -112,15 +112,17 @@ TEST_F(FrameIsdTest, ConstructInValidCamera) {
    UsgsAstroPlugin testPlugin;
    isd.setFilename("data/constVelocityLineScan.img");
    csm::Model *cameraModel = NULL;
+   csm::WarningList *warnings = new csm::WarningList;
    try {
       testPlugin.constructModelFromISD(
             isd,
             "USGS_ASTRO_FRAME_SENSOR_MODEL",
-            NULL);
+            warnings);
       FAIL() << "Expected an error";
    }
    catch(csm::Error &e) {
       EXPECT_EQ(e.getError(), csm::Error::SENSOR_MODEL_NOT_CONSTRUCTIBLE);
+      EXPECT_FALSE(warnings->empty());
    }
    catch(...) {
       FAIL() << "Expected csm SENSOR_MODEL_NOT_CONSTRUCTIBLE error";
@@ -128,6 +130,9 @@ TEST_F(FrameIsdTest, ConstructInValidCamera) {
    if (cameraModel) {
       delete cameraModel;
    }
+   if (warnings) {
+     delete warnings;
+   }
 }
 
 TEST_F(ConstVelLineScanIsdTest, Constructible) {
diff --git a/tests/data/simpleFramerISD.json b/tests/data/simpleFramerISD.json
index ddc5492815a0533b5bbccbc1ab9f260f8732bc62..b22c3e8ab043f663fb569eb15e4800689138c780 100644
--- a/tests/data/simpleFramerISD.json
+++ b/tests/data/simpleFramerISD.json
@@ -2,6 +2,7 @@
 	"name_model" : "USGS_ASTRO_FRAME_SENSOR_MODEL",
 	"name_sensor": "SENSOR",
 	"name_platform": "CarryMe",
+	"image_identifier": "TEST_IMAGE",
 	"center_ephemeris_time": 50,
 	"dt_ephemeris": 100,
   "focal2pixel_lines": [0.0, 0.0, 10.0],