TEST_F(IdfFixture,ValidityReport_WithCustomIdd) 
{
  Workspace workspace;
  EXPECT_EQ(IddFileType::OpenStudio, workspace.iddFileType().value());
  EXPECT_TRUE(workspace.isValid(StrictnessLevel::Draft));
  workspace.addObject(IdfObject(IddObjectType::OS_Building));
  EXPECT_TRUE(workspace.isValid(StrictnessLevel::Draft));

  std::stringstream ss;
  workspace.iddFile().print(ss);
  boost::optional<IddFile> iddFile = IddFile::load(ss);
  ASSERT_TRUE(iddFile);

  Workspace workspace2(*iddFile, StrictnessLevel::None);
  EXPECT_EQ(IddFileType::UserCustom, workspace2.iddFileType().value());
  workspace2.addObjects(workspace.toIdfFile().objects());
  EXPECT_EQ(workspace.objects().size(), workspace2.objects().size());
  EXPECT_TRUE(workspace2.isValid(StrictnessLevel::Draft));
  ValidityReport report = workspace2.validityReport(StrictnessLevel::Draft);
  LOG(Debug,"Validity report for workspace2: " << std::endl << report);
}
Model ReverseTranslator::translateWorkspace(const Workspace & workspace, ProgressBar* progressBar )
{
  // check input
  if (workspace.iddFileType() != IddFileType::EnergyPlus){
    LOG(Error, "Cannot translate Workspace with IddFileType = '" << workspace.iddFileType().valueName() << "'");
    return Model();
  }

  m_model = Model();
  m_model.setFastNaming(true);

  m_workspace = workspace.clone();

  m_workspaceToModelMap.clear();

  m_untranslatedIdfObjects.clear();

  m_logSink.resetStringStream();

  // if multiple runperiod objects in idf, remove them all
  vector<WorkspaceObject> runPeriods = m_workspace.getObjectsByType(IddObjectType::RunPeriod);
  if (runPeriods.size() > 1){
    for(auto & runPeriod : runPeriods)
    {
      runPeriod.remove();
    }
  }

  // first thing to do is convert geometry system
  m_logSink.setChannelRegex(boost::regex("openstudio\\.energyplus\\.GeometryTranslator"));

  m_progressBar = progressBar;
  if (m_progressBar){
    m_progressBar->setMinimum(0);
    m_progressBar->setMaximum(workspace.numObjects());
  }

  LOG(Trace,"Calling geometry translator.");
  GeometryTranslator geometryTranslator(m_workspace);
  geometryTranslator.convert(CoordinateSystem::Relative, CoordinateSystem::Relative);

  m_logSink.setChannelRegex(boost::regex("openstudio\\.energyplus\\.ReverseTranslator"));

  // look for site object in workspace and translate if found
  LOG(Trace,"Translating Site:Location object.");
  vector<WorkspaceObject> site = m_workspace.getObjectsByType(IddObjectType::Site_Location);
  for(auto & elem : site)
  {
    translateAndMapWorkspaceObject(elem);
  }

  // look for simulation control object in workspace and translate if found
  LOG(Trace,"Translating SimulationControl object.");
  vector<WorkspaceObject> simulationControl = m_workspace.getObjectsByType(IddObjectType::SimulationControl);
  for(auto & elem : simulationControl)
  {
    translateAndMapWorkspaceObject(elem);
  }

  // loop over all of the air loops
  LOG(Trace,"Translating AirLoops.");
  vector<WorkspaceObject> airLoops = m_workspace.getObjectsByType(IddObjectType::AirLoopHVAC);
  for(auto it = airLoops.begin(),iend=airLoops.end();it!=iend;++it)
  {
    LOG(Trace,"Translating AirLoop '" << it->name().get() << "'.");
    translateAndMapWorkspaceObject( *it );
  }

  // Now loop over all objects to make sure nothing as missed.
  // In the future this might be removed.
  LOG(Trace,"Translating remaining objects.");
  vector<WorkspaceObject> all = m_workspace.objects();
  for(auto & elem : all)
  {
    translateAndMapWorkspaceObject( elem );
  }

  LOG(Trace,"Translation nominally complete.");
  m_model.setFastNaming(false);
  return m_model;
}