boost::optional<QDomDocument> ForwardTranslator::translateModel(const openstudio::model::Model& model)
  {
    QDomDocument doc;
    doc.createProcessingInstruction("xml", "version=\"1.0\" encoding=\"utf-8\"");

    QDomElement sddElement = doc.createElement("SDDXML");
    sddElement.setAttribute("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance");
    sddElement.setAttribute("xmlns:xsd", "http://www.w3.org/2001/XMLSchema");
    doc.appendChild(sddElement);

    // set ruleset, where should this data come from?
    QDomElement rulesetFilenameElement = doc.createElement("RulesetFilename");
    sddElement.appendChild(rulesetFilenameElement);
    rulesetFilenameElement.setAttribute("file", "CEC 2013 NonRes.bin"); // DLM: only allow one value for now

    // set project, where should this data come from?
    QDomElement projectElement = doc.createElement("Proj");
    sddElement.appendChild(projectElement);

    // DLM: what name to use here?
    QDomElement projectNameElement = doc.createElement("Name");
    projectElement.appendChild(projectNameElement);
    projectNameElement.appendChild(doc.createTextNode("unknown"));

    // site data
    boost::optional<model::ClimateZones> climateZones = model.getOptionalUniqueModelObject<model::ClimateZones>();
    if (climateZones){
      // todo: check document year
      std::vector<model::ClimateZone> zones = climateZones->getClimateZones("CEC");
      if (zones.size() > 0 && !zones[0].value().empty()){

        bool isNumber;
        QString value = toQString(zones[0].value());
        value.toInt(&isNumber);
        if (isNumber){
          value = QString("ClimateZone") + value;
        }

        QDomElement projectClimateZoneElement = doc.createElement("CliZn");
        projectElement.appendChild(projectClimateZoneElement);
        projectClimateZoneElement.appendChild(doc.createTextNode(value));

        m_translatedObjects[climateZones->handle()] = projectClimateZoneElement;
      }
    }

    // set lat, lon, elev
    // DLM: do not translate forward,  Issue 242: Forward Translator - Remove Proj:Lat/Lon/Elevation translation
    /*
    boost::optional<model::Site> site = model.getOptionalUniqueModelObject<model::Site>();
    if (site){
      double latitude = site->latitude();
      QDomElement latElement = doc.createElement("Lat");
      projectElement.appendChild(latElement);
      latElement.appendChild( doc.createTextNode(QString::number(latitude)));

      double longitude = site->longitude();
      QDomElement longElement = doc.createElement("Long");
      projectElement.appendChild(longElement);
      longElement.appendChild( doc.createTextNode(QString::number(longitude)));

      double elevationSI = site->elevation();
      double elevationIP = elevationSI/0.3048;
      QDomElement elevationElement = doc.createElement("Elevation");
      projectElement.appendChild(elevationElement);
      elevationElement.appendChild( doc.createTextNode(QString::number(elevationIP)));

      m_translatedObjects[site.handle()] = latElement;
    }
    */

    // todo: write out epw file path
    // todo: write out ddy file and set path
    //<DDWeatherFile>C:/svn-CBECC-Com-130521/CBECC-Com13/Data/EPW/SACRAMENTO-EXECUTIVE_724830_CZ2010.ddy</DDWeatherFile>
    //<AnnualWeatherFile>C:/svn-CBECC-Com-130521/CBECC-Com13/Data/EPW/SACRAMENTO-EXECUTIVE_724830_CZ2010.epw</AnnualWeatherFile>
    //<HVACAutoSizing>1</HVACAutoSizing>
    //<SimDsgnDays>1</SimDsgnDays>
    //<RunPeriodBeginMonth>0</RunPeriodBeginMonth>
    //<RunPeriodBeginDay>0</RunPeriodBeginDay>
    //<RunPeriodEndMonth>0</RunPeriodEndMonth>
    //<RunPeriodEndDay>0</RunPeriodEndDay>
    //<RunPeriodYear>0</RunPeriodYear>

    // do materials before constructions 
    std::vector<model::Material> materials = model.getModelObjects<model::Material>();
    std::sort(materials.begin(), materials.end(), WorkspaceObjectNameLess());

    if (m_progressBar){
      m_progressBar->setWindowTitle(toString("Translating Materials"));
      m_progressBar->setMinimum(0);
      m_progressBar->setMaximum((int)materials.size());
      m_progressBar->setValue(0);
    }

    for (const model::Material& material : materials){

      boost::optional<QDomElement> materialElement = translateMaterial(material, doc);
      if (materialElement){
        projectElement.appendChild(*materialElement);
      }

      if (m_progressBar){
        m_progressBar->setValue(m_progressBar->value() + 1);
      }
    }
  
    // do constructions before geometry

    std::vector<model::ConstructionBase> constructions = model.getModelObjects<model::ConstructionBase>();
    std::sort(constructions.begin(), constructions.end(), WorkspaceObjectNameLess());

    if (m_progressBar){
      m_progressBar->setWindowTitle(toString("Translating Constructions"));
      m_progressBar->setMinimum(0);
      m_progressBar->setMaximum(3 * ((int)constructions.size())); // three loops below
      m_progressBar->setValue(0);
    }

    std::set<Handle> surfaceConstructions;
    for (const model::Surface& surface : model.getConcreteModelObjects<model::Surface>()){
      boost::optional<model::ConstructionBase> construction = surface.construction();
      if (construction){
        surfaceConstructions.insert(construction->handle());
      }
    }

    std::set<Handle> doorConstructions;
    std::set<Handle> fenestrationConstructions;
    for (const model::SubSurface& subSurface : model.getConcreteModelObjects<model::SubSurface>()){
      boost::optional<model::ConstructionBase> construction = subSurface.construction();
      if (construction){
        std::string subSurfaceType = subSurface.subSurfaceType();
        if (istringEqual("Door", subSurfaceType) || istringEqual("OverheadDoor", subSurfaceType)){
          doorConstructions.insert(construction->handle());
        }else{
          fenestrationConstructions.insert(construction->handle());
        }
      }
    }

    // translate surface constructions
    for (const model::ConstructionBase& constructionBase : constructions){
      if (surfaceConstructions.find(constructionBase.handle()) == surfaceConstructions.end()){
        continue;
      }

      boost::optional<QDomElement> constructionElement = translateConstructionBase(constructionBase, doc);
      if (constructionElement){
        projectElement.appendChild(*constructionElement);
      }
            
      if (m_progressBar){
        m_progressBar->setValue(m_progressBar->value() + 1);
      }
    }

    // translate door constructions
    for (const model::ConstructionBase& constructionBase : constructions){
      if (doorConstructions.find(constructionBase.handle()) == doorConstructions.end()){
        continue;
      }

      boost::optional<QDomElement> constructionElement = translateDoorConstruction(constructionBase, doc);
      if (constructionElement){
        projectElement.appendChild(*constructionElement);
      }
            
      if (m_progressBar){
        m_progressBar->setValue(m_progressBar->value() + 1);
      }
    }

    // translate fenestration constructions
    for (const model::ConstructionBase& constructionBase : constructions){
      if (fenestrationConstructions.find(constructionBase.handle()) == fenestrationConstructions.end()){
        continue;
      }

      boost::optional<QDomElement> constructionElement = translateFenestrationConstruction(constructionBase, doc);
      if (constructionElement){
        projectElement.appendChild(*constructionElement);
      }

      if (m_progressBar){
        m_progressBar->setValue(m_progressBar->value() + 1);
      }
    }

    // translate site shading
    std::vector<model::ShadingSurfaceGroup> shadingSurfaceGroups = model.getConcreteModelObjects<model::ShadingSurfaceGroup>();
    std::sort(shadingSurfaceGroups.begin(), shadingSurfaceGroups.end(), WorkspaceObjectNameLess());

    if (m_progressBar){
      m_progressBar->setWindowTitle(toString("Translating Site Shading"));
      m_progressBar->setMinimum(0);
      m_progressBar->setMaximum((int)shadingSurfaceGroups.size()); 
      m_progressBar->setValue(0);
    }

    for (const model::ShadingSurfaceGroup& shadingSurfaceGroup : shadingSurfaceGroups){
      if (istringEqual(shadingSurfaceGroup.shadingSurfaceType(), "Site")){

        Transformation transformation = shadingSurfaceGroup.siteTransformation();

        for (const model::ShadingSurface& shadingSurface : shadingSurfaceGroup.shadingSurfaces()){
          boost::optional<QDomElement> shadingSurfaceElement = translateShadingSurface(shadingSurface, transformation, doc);
          if (shadingSurfaceElement){
            projectElement.appendChild(*shadingSurfaceElement);
          }
        }
      }

      if (m_progressBar){
        m_progressBar->setValue(m_progressBar->value() + 1);
      }
    }

    // translate the building
    boost::optional<model::Building> building = model.getOptionalUniqueModelObject<model::Building>();
    if (building){
      boost::optional<QDomElement> buildingElement = translateBuilding(*building, doc);
      if (buildingElement){
        projectElement.appendChild(*buildingElement);
      }
    }

    m_ignoreTypes.push_back(model::BoilerSteam::iddObjectType());
    m_ignoreTypes.push_back(model::ClimateZones::iddObjectType()); // might not be translated but it is checked
    m_ignoreTypes.push_back(model::CoilCoolingDXMultiSpeedStageData::iddObjectType());
    m_ignoreTypes.push_back(model::CoilHeatingGasMultiStageStageData::iddObjectType());
    m_ignoreTypes.push_back(model::ComponentCostAdjustments::iddObjectType());
    m_ignoreTypes.push_back(model::ComponentData::iddObjectType());
    m_ignoreTypes.push_back(model::Connection::iddObjectType());
    m_ignoreTypes.push_back(model::ControllerWaterCoil::iddObjectType());
    m_ignoreTypes.push_back(model::ConvergenceLimits::iddObjectType());
    m_ignoreTypes.push_back(model::CoolingTowerPerformanceCoolTools::iddObjectType());
    m_ignoreTypes.push_back(model::CoolingTowerPerformanceYorkCalc::iddObjectType());
    m_ignoreTypes.push_back(model::CurrencyType::iddObjectType());
    m_ignoreTypes.push_back(model::CurveBicubic::iddObjectType());
    m_ignoreTypes.push_back(model::CurveBiquadratic::iddObjectType());
    m_ignoreTypes.push_back(model::CurveCubic::iddObjectType());
    m_ignoreTypes.push_back(model::CurveDoubleExponentialDecay::iddObjectType());
    m_ignoreTypes.push_back(model::CurveExponent::iddObjectType());
    m_ignoreTypes.push_back(model::CurveExponentialDecay::iddObjectType());
    m_ignoreTypes.push_back(model::CurveExponentialSkewNormal::iddObjectType());
    m_ignoreTypes.push_back(model::CurveFanPressureRise::iddObjectType());
    m_ignoreTypes.push_back(model::CurveFunctionalPressureDrop::iddObjectType());
    m_ignoreTypes.push_back(model::CurveLinear::iddObjectType());
    m_ignoreTypes.push_back(model::CurveQuadratic::iddObjectType());
    m_ignoreTypes.push_back(model::CurveQuadraticLinear::iddObjectType());
    m_ignoreTypes.push_back(model::CurveQuartic::iddObjectType());
    m_ignoreTypes.push_back(model::CurveRectangularHyperbola1::iddObjectType());
    m_ignoreTypes.push_back(model::CurveRectangularHyperbola2::iddObjectType());
    m_ignoreTypes.push_back(model::CurveSigmoid::iddObjectType());
    m_ignoreTypes.push_back(model::CurveTriquadratic::iddObjectType());
    m_ignoreTypes.push_back(model::DefaultConstructionSet::iddObjectType());
    m_ignoreTypes.push_back(model::DesignDay::iddObjectType());
    m_ignoreTypes.push_back(model::DefaultScheduleSet::iddObjectType());
    m_ignoreTypes.push_back(model::DesignSpecificationZoneAirDistribution::iddObjectType());
    m_ignoreTypes.push_back(model::DefaultSurfaceConstructions::iddObjectType());
    m_ignoreTypes.push_back(model::DefaultSubSurfaceConstructions::iddObjectType());
    m_ignoreTypes.push_back(model::Facility::iddObjectType());
    m_ignoreTypes.push_back(model::HeatBalanceAlgorithm::iddObjectType());
    m_ignoreTypes.push_back(model::IlluminanceMap::iddObjectType());
    m_ignoreTypes.push_back(model::InsideSurfaceConvectionAlgorithm::iddObjectType());
    m_ignoreTypes.push_back(model::InternalMass::iddObjectType());
    m_ignoreTypes.push_back(model::LifeCycleCost::iddObjectType());
    m_ignoreTypes.push_back(model::LifeCycleCostParameters::iddObjectType());
    m_ignoreTypes.push_back(model::LightingDesignDay::iddObjectType());
    m_ignoreTypes.push_back(model::LightingSimulationControl::iddObjectType());
    m_ignoreTypes.push_back(model::Meter::iddObjectType());
    m_ignoreTypes.push_back(model::ModelObjectList::iddObjectType());
    m_ignoreTypes.push_back(model::Node::iddObjectType());
    m_ignoreTypes.push_back(model::OutputControlReportingTolerances::iddObjectType());
    m_ignoreTypes.push_back(model::OutputVariable::iddObjectType());
    m_ignoreTypes.push_back(model::OutsideSurfaceConvectionAlgorithm::iddObjectType());
    m_ignoreTypes.push_back(model::PortList::iddObjectType());
    m_ignoreTypes.push_back(model::ProgramControl::iddObjectType());
    m_ignoreTypes.push_back(model::RadianceParameters::iddObjectType());
    m_ignoreTypes.push_back(model::RenderingColor::iddObjectType());
    m_ignoreTypes.push_back(model::RunPeriod::iddObjectType());
    m_ignoreTypes.push_back(model::ScheduleCompact::iddObjectType());
    m_ignoreTypes.push_back(model::ScheduleConstant::iddObjectType());
    m_ignoreTypes.push_back(model::ScheduleDay::iddObjectType());
    m_ignoreTypes.push_back(model::ScheduleFixedInterval::iddObjectType());
    m_ignoreTypes.push_back(model::ScheduleRule::iddObjectType());
    m_ignoreTypes.push_back(model::ScheduleRuleset::iddObjectType());
    m_ignoreTypes.push_back(model::ScheduleTypeLimits::iddObjectType());
    m_ignoreTypes.push_back(model::ScheduleVariableInterval::iddObjectType());
    m_ignoreTypes.push_back(model::ScheduleWeek::iddObjectType());
    m_ignoreTypes.push_back(model::ScheduleYear::iddObjectType());
    m_ignoreTypes.push_back(model::SetpointManagerMixedAir::iddObjectType());
    m_ignoreTypes.push_back(model::ShadowCalculation::iddObjectType());
    m_ignoreTypes.push_back(model::SimulationControl::iddObjectType());
    m_ignoreTypes.push_back(model::Site::iddObjectType()); // might not be translated but it is checked
    m_ignoreTypes.push_back(model::SiteGroundReflectance::iddObjectType());
    m_ignoreTypes.push_back(model::SiteGroundTemperatureBuildingSurface::iddObjectType());
    m_ignoreTypes.push_back(model::SiteWaterMainsTemperature::iddObjectType());
    m_ignoreTypes.push_back(model::SizingParameters::iddObjectType());
    m_ignoreTypes.push_back(model::SkyTemperature::iddObjectType());
    m_ignoreTypes.push_back(model::StandardsInformationConstruction::iddObjectType());
    m_ignoreTypes.push_back(model::StandardsInformationMaterial::iddObjectType());
    m_ignoreTypes.push_back(model::TableMultiVariableLookup::iddObjectType());
    m_ignoreTypes.push_back(model::Timestep::iddObjectType());
    m_ignoreTypes.push_back(model::UtilityBill::iddObjectType());
    m_ignoreTypes.push_back(model::UtilityCost_Charge_Block::iddObjectType());
    m_ignoreTypes.push_back(model::UtilityCost_Charge_Simple::iddObjectType());
    m_ignoreTypes.push_back(model::UtilityCost_Computation::iddObjectType());
    m_ignoreTypes.push_back(model::UtilityCost_Qualify::iddObjectType());
    m_ignoreTypes.push_back(model::UtilityCost_Ratchet::iddObjectType());
    m_ignoreTypes.push_back(model::UtilityCost_Tariff::iddObjectType());
    m_ignoreTypes.push_back(model::UtilityCost_Variable::iddObjectType());
    m_ignoreTypes.push_back(model::Version::iddObjectType());
    m_ignoreTypes.push_back(model::WeatherFile::iddObjectType());
    m_ignoreTypes.push_back(model::WeatherFileConditionType::iddObjectType());
    m_ignoreTypes.push_back(model::WeatherFileDays::iddObjectType());
    m_ignoreTypes.push_back(model::YearDescription::iddObjectType());
    m_ignoreTypes.push_back(model::ZoneAirContaminantBalance::iddObjectType());
    m_ignoreTypes.push_back(model::ZoneAirHeatBalanceAlgorithm::iddObjectType());
    m_ignoreTypes.push_back(model::ZoneCapacitanceMultiplierResearchSpecial::iddObjectType());
    m_ignoreTypes.push_back(model::ZoneHVACEquipmentList::iddObjectType());

    return doc;
  }
  boost::optional<QDomDocument> ForwardTranslator::translateModel(const openstudio::model::Model& model)
  {
    QDomDocument doc;
    doc.createProcessingInstruction("xml", "version=\"1.0\" encoding=\"utf-8\"");

    QDomElement sddElement = doc.createElement("SDDXML");
    sddElement.setAttribute("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance");
    sddElement.setAttribute("xmlns:xsd", "http://www.w3.org/2001/XMLSchema");
    doc.appendChild(sddElement);

    // set ruleset, where should this data come from?
    QDomElement rulesetFilenameElement = doc.createElement("RulesetFilename");
    sddElement.appendChild(rulesetFilenameElement);
    rulesetFilenameElement.setAttribute("file", "unknown");

    // set project, where should this data come from?
    QDomElement projectElement = doc.createElement("Proj");
    sddElement.appendChild(projectElement);

    QDomElement projectNameElement = doc.createElement("Name");
    projectElement.appendChild(projectNameElement);
    projectNameElement.appendChild( doc.createTextNode( "unknown"));

    // site data
    QDomElement projectClimateZoneElement = doc.createElement("CliZn");
    projectElement.appendChild(projectClimateZoneElement);
    projectClimateZoneElement.appendChild( doc.createTextNode( "unknown"));

    // set lat, lon, elev
    // DLM: do not translate forward,  Issue 242: Forward Translator - Remove Proj:Lat/Lon/Elevation translation
    /*
    boost::optional<model::Site> site = model.getOptionalUniqueModelObject<model::Site>();
    if (site){
      double latitude = site->latitude();
      QDomElement latElement = doc.createElement("Lat");
      projectElement.appendChild(latElement);
      latElement.appendChild( doc.createTextNode(QString::number(latitude)));

      double longitude = site->longitude();
      QDomElement longElement = doc.createElement("Long");
      projectElement.appendChild(longElement);
      longElement.appendChild( doc.createTextNode(QString::number(longitude)));

      double elevationSI = site->elevation();
      double elevationIP = elevationSI/0.3048;
      QDomElement elevationElement = doc.createElement("Elevation");
      projectElement.appendChild(elevationElement);
      elevationElement.appendChild( doc.createTextNode(QString::number(elevationIP)));
    }
    */

    // todo: write out epw file path
    // todo: write out ddy file and set path
    //<DDWeatherFile>C:/svn-CBECC-Com-130521/CBECC-Com13/Data/EPW/SACRAMENTO-EXECUTIVE_724830_CZ2010.ddy</DDWeatherFile>
    //<AnnualWeatherFile>C:/svn-CBECC-Com-130521/CBECC-Com13/Data/EPW/SACRAMENTO-EXECUTIVE_724830_CZ2010.epw</AnnualWeatherFile>
    //<HVACAutoSizing>1</HVACAutoSizing>
    //<SimDsgnDays>1</SimDsgnDays>
    //<RunPeriodBeginMonth>0</RunPeriodBeginMonth>
    //<RunPeriodBeginDay>0</RunPeriodBeginDay>
    //<RunPeriodEndMonth>0</RunPeriodEndMonth>
    //<RunPeriodEndDay>0</RunPeriodEndDay>
    //<RunPeriodYear>0</RunPeriodYear>

    // do materials before constructions 
    std::vector<model::Material> materials = model.getModelObjects<model::Material>();
    std::sort(materials.begin(), materials.end(), WorkspaceObjectNameLess());

    if (m_progressBar){
      m_progressBar->setWindowTitle(toString("Translating Materials"));
      m_progressBar->setMinimum(0);
      m_progressBar->setMaximum(materials.size());
      m_progressBar->setValue(0);
    }

    for (const model::Material& material : materials){

      boost::optional<QDomElement> materialElement = translateMaterial(material, doc);
      if (materialElement){
        projectElement.appendChild(*materialElement);
      }

      if (m_progressBar){
        m_progressBar->setValue(m_progressBar->value() + 1);
      }
    }
  
    // do constructions before geometry

    std::vector<model::ConstructionBase> constructions = model.getModelObjects<model::ConstructionBase>();
    std::sort(constructions.begin(), constructions.end(), WorkspaceObjectNameLess());

    if (m_progressBar){
      m_progressBar->setWindowTitle(toString("Translating Constructions"));
      m_progressBar->setMinimum(0);
      m_progressBar->setMaximum(3*constructions.size()); // three loops below
      m_progressBar->setValue(0);
    }

    std::set<Handle> surfaceConstructions;
    for (const model::Surface& surface : model.getConcreteModelObjects<model::Surface>()){
      boost::optional<model::ConstructionBase> construction = surface.construction();
      if (construction){
        surfaceConstructions.insert(construction->handle());
      }
    }

    std::set<Handle> doorConstructions;
    std::set<Handle> fenestrationConstructions;
    for (const model::SubSurface& subSurface : model.getConcreteModelObjects<model::SubSurface>()){
      boost::optional<model::ConstructionBase> construction = subSurface.construction();
      if (construction){
        std::string subSurfaceType = subSurface.subSurfaceType();
        if (istringEqual("Door", subSurfaceType) || istringEqual("OverheadDoor", subSurfaceType)){
          doorConstructions.insert(construction->handle());
        }else{
          fenestrationConstructions.insert(construction->handle());
        }
      }
    }

    // translate surface constructions
    for (const model::ConstructionBase& constructionBase : constructions){
      if (surfaceConstructions.find(constructionBase.handle()) == surfaceConstructions.end()){
        continue;
      }

      boost::optional<QDomElement> constructionElement = translateConstructionBase(constructionBase, doc);
      if (constructionElement){
        projectElement.appendChild(*constructionElement);
      }
            
      if (m_progressBar){
        m_progressBar->setValue(m_progressBar->value() + 1);
      }
    }

    // translate door constructions
    for (const model::ConstructionBase& constructionBase : constructions){
      if (doorConstructions.find(constructionBase.handle()) == doorConstructions.end()){
        continue;
      }

      boost::optional<QDomElement> constructionElement = translateDoorConstruction(constructionBase, doc);
      if (constructionElement){
        projectElement.appendChild(*constructionElement);
      }
            
      if (m_progressBar){
        m_progressBar->setValue(m_progressBar->value() + 1);
      }
    }

    // translate fenestration constructions
    for (const model::ConstructionBase& constructionBase : constructions){
      if (fenestrationConstructions.find(constructionBase.handle()) == fenestrationConstructions.end()){
        continue;
      }

      boost::optional<QDomElement> constructionElement = translateFenestrationConstruction(constructionBase, doc);
      if (constructionElement){
        projectElement.appendChild(*constructionElement);
      }

      if (m_progressBar){
        m_progressBar->setValue(m_progressBar->value() + 1);
      }
    }

    // translate site shading
    std::vector<model::ShadingSurfaceGroup> shadingSurfaceGroups = model.getConcreteModelObjects<model::ShadingSurfaceGroup>();
    std::sort(shadingSurfaceGroups.begin(), shadingSurfaceGroups.end(), WorkspaceObjectNameLess());

    if (m_progressBar){
      m_progressBar->setWindowTitle(toString("Translating Site Shading"));
      m_progressBar->setMinimum(0);
      m_progressBar->setMaximum(shadingSurfaceGroups.size()); 
      m_progressBar->setValue(0);
    }

    for (const model::ShadingSurfaceGroup& shadingSurfaceGroup : shadingSurfaceGroups){
      if (istringEqual(shadingSurfaceGroup.shadingSurfaceType(), "Site")){

        Transformation transformation = shadingSurfaceGroup.siteTransformation();

        for (const model::ShadingSurface& shadingSurface : shadingSurfaceGroup.shadingSurfaces()){
          boost::optional<QDomElement> shadingSurfaceElement = translateShadingSurface(shadingSurface, transformation, doc);
          if (shadingSurfaceElement){
            projectElement.appendChild(*shadingSurfaceElement);
          }
        }
      }

      if (m_progressBar){
        m_progressBar->setValue(m_progressBar->value() + 1);
      }
    }

    // translate the building
    boost::optional<model::Building> building = model.getOptionalUniqueModelObject<model::Building>();
    if (building){
      boost::optional<QDomElement> buildingElement = translateBuilding(*building, doc);
      if (buildingElement){
        projectElement.appendChild(*buildingElement);
      }
    }

    return doc;
  }
boost::optional<ModelObject> ReverseTranslator::translateAndMapWorkspaceObject(const WorkspaceObject & workspaceObject)
{
  auto i = m_workspaceToModelMap.find(workspaceObject.handle());

  boost::optional<ModelObject> modelObject;

  if( i !=  m_workspaceToModelMap.end())
  {
    return boost::optional<ModelObject>(i->second);
  }

  LOG(Trace,"Translating " << workspaceObject.briefDescription() << ".");

  // DLM: the scope of this translator is being changed, we now only import objects from idf
  // in the geometry, loads, resources, and general simulation control portions of the model.
  // Users can add idf objects to their model using idf measures.  Only objects viewable in the
  // current GUIs should be imported, I am making an exception for curves.

  bool addToUntranslated = true;

  switch(workspaceObject.iddObject().type().value())
  {
  case openstudio::IddObjectType::AirLoopHVAC :
    {
      //modelObject = translateAirLoopHVAC(workspaceObject);
      break;
    }
  case openstudio::IddObjectType::AirLoopHVAC_ControllerList :
    {
      break; // no-op
    }
  case openstudio::IddObjectType::AirLoopHVAC_OutdoorAirSystem :
    {
      //modelObject = translateAirLoopHVACOutdoorAirSystem(workspaceObject );
      break;
    }
  case openstudio::IddObjectType::AirLoopHVAC_OutdoorAirSystem_EquipmentList :
    {
      break; // no-op
    }
  case openstudio::IddObjectType::AirLoopHVAC_ReturnPath :
    {
      break; // no-op
    }
  case openstudio::IddObjectType::CoilSystem_Cooling_DX :
    {
      //modelObject = translateCoilSystemCoolingDX(workspaceObject);
      break;
    }
  case openstudio::IddObjectType::AirLoopHVAC_ZoneSplitter :
    {
      break; // no-op
    }
  case openstudio::IddObjectType::AirTerminal_SingleDuct_ConstantVolume_Reheat :
    {
      modelObject = translateAirTerminalSingleDuctConstantVolumeReheat(workspaceObject );
      break;
    }
  case openstudio::IddObjectType::AirTerminal_SingleDuct_Uncontrolled :
    {
      //modelObject = translateAirTerminalSingleDuctUncontrolled(workspaceObject );
      break;
    }
  case openstudio::IddObjectType::AirTerminal_SingleDuct_VAV_NoReheat :
    {
      modelObject = translateAirTerminalSingleDuctVAVNoReheat(workspaceObject );
      break;
    }
  case openstudio::IddObjectType::AirTerminal_SingleDuct_VAV_Reheat :
    {
      //modelObject = translateAirTerminalSingleDuctVAVReheat(workspaceObject );
      break;
    }
  case openstudio::IddObjectType::AvailabilityManagerAssignmentList :
    {
      break; // no-op
    }
  case openstudio::IddObjectType::Branch :
    {
      break; // no-op
    }
  case openstudio::IddObjectType::BranchList :
    {
      break; // no-op
    }
  case openstudio::IddObjectType::BuildingSurface_Detailed :
    {
      modelObject = translateBuildingSurfaceDetailed(workspaceObject );
      break;
    }
  case openstudio::IddObjectType::Building :
    {
      modelObject = translateBuilding(workspaceObject );
      break;
    }
  case openstudio::IddObjectType::Coil_Heating_Fuel :
    {
      //modelObject = translateCoilHeatingGas(workspaceObject );
      break;
    }
  case openstudio::IddObjectType::Coil_Cooling_DX_SingleSpeed :
    {
      //modelObject = translateCoilCoolingDXSingleSpeed(workspaceObject );
      break;
    }
  case openstudio::IddObjectType::CommentOnly :
    {
      break; // no-op
    }
  case openstudio::IddObjectType::ComponentCost_LineItem :
    {
      break; // no-op
    }
  case openstudio::IddObjectType::Connector_Mixer :
    {
      break; // no-op
    }
  case openstudio::IddObjectType::Connector_Splitter :
    {
      break; // no-op
    }
  case openstudio::IddObjectType::ConnectorList :
    {
      break; // no-op
    }
  case openstudio::IddObjectType::Construction :
    {
      modelObject = translateConstruction(workspaceObject);
      break;
    }
  case openstudio::IddObjectType::Controller_OutdoorAir :
    {
      //modelObject = translateControllerOutdoorAir(workspaceObject);
      break;
    }
  case openstudio::IddObjectType::ConvergenceLimits :
    {
      modelObject = translateConvergenceLimits(workspaceObject);
      break;
    }
  case openstudio::IddObjectType::Curve_Bicubic :
    {
      modelObject = translateCurveBicubic(workspaceObject);
      break;
    }
  case openstudio::IddObjectType::Curve_Biquadratic :
    {
      modelObject = translateCurveBiquadratic(workspaceObject);
      break;
    }
  case openstudio::IddObjectType::Curve_Cubic :
    {
      modelObject = translateCurveCubic(workspaceObject);
      break;
    }
  case openstudio::IddObjectType::Curve_DoubleExponentialDecay :
    {
      modelObject = translateCurveDoubleExponentialDecay(workspaceObject);
      break;
    }
  case openstudio::IddObjectType::Curve_ExponentialSkewNormal :
    {
      modelObject = translateCurveExponentialSkewNormal(workspaceObject);
      break;
    }
  case openstudio::IddObjectType::Curve_FanPressureRise :
    {
      modelObject = translateCurveFanPressureRise(workspaceObject);
      break;
    }
  case openstudio::IddObjectType::Curve_Functional_PressureDrop :
    {
      modelObject = translateCurveFunctionalPressureDrop(workspaceObject);
      break;
    }
  case openstudio::IddObjectType::Curve_Linear :
    {
      modelObject = translateCurveLinear(workspaceObject);
      break;
    }
  case openstudio::IddObjectType::Curve_Quadratic :
    {
      modelObject = translateCurveQuadratic(workspaceObject);
      break;
    }
  case openstudio::IddObjectType::Curve_QuadraticLinear :
    {
      modelObject = translateCurveQuadraticLinear(workspaceObject);
      break;
    }
  case openstudio::IddObjectType::Curve_Quartic :
    {
      modelObject = translateCurveQuartic(workspaceObject);
      break;
    }
  case openstudio::IddObjectType::Curve_RectangularHyperbola1 :
    {
      modelObject = translateCurveRectangularHyperbola1(workspaceObject);
      break;
    }
  case openstudio::IddObjectType::Curve_RectangularHyperbola2 :
    {
      modelObject = translateCurveRectangularHyperbola2(workspaceObject);
      break;
    }
  case openstudio::IddObjectType::Curve_Sigmoid :
    {
      modelObject = translateCurveSigmoid(workspaceObject);
      break;
    }
  case openstudio::IddObjectType::Curve_Triquadratic :
    {
      modelObject = translateCurveTriquadratic(workspaceObject);
      break;
    }
  case openstudio::IddObjectType::Daylighting_Controls :
    {
      modelObject = translateDaylightingControls(workspaceObject );
      break;
    }
  case openstudio::IddObjectType::DesignSpecification_OutdoorAir :
    {
      // Call this directly because we don't want to translate all of them
      // only those that are connected to the SizingZone object
      //modelObject = translateDesignSpecificationOutdoorAir(workspaceObject);
      break;
    }
  case openstudio::IddObjectType::ElectricEquipment :
    {
      modelObject = translateElectricEquipment(workspaceObject );
      break;
    }
  case openstudio::IddObjectType::Exterior_Lights :
    {
      //modelObject = translateExteriorLights(workspaceObject);
      break;
    }
  case openstudio::IddObjectType::ElectricLoadCenter_Storage_Simple :
    {
      modelObject = translateElectricLoadCenterStorageSimple(workspaceObject);
      break;
    }
  case openstudio::IddObjectType::ElectricLoadCenter_Storage_Converter :
    {
      modelObject = translateElectricLoadCenterStorageConverter(workspaceObject);
      break;
    }  
  case openstudio::IddObjectType::EvaporativeCooler_Direct_ResearchSpecial :
    {
      //modelObject = translateEvaporativeCoolerDirectResearchSpecial(workspaceObject);
      break;
    }
  case openstudio::IddObjectType::EvaporativeFluidCooler_SingleSpeed :
    {
      modelObject = translateEvaporativeFluidCoolerSingleSpeed(workspaceObject);
      break;
    }
  case openstudio::IddObjectType::Fan_ConstantVolume :
    {
      //modelObject = translateFanConstantVolume(workspaceObject );
      break;
    }
  case openstudio::IddObjectType::FenestrationSurface_Detailed :
    {
      modelObject = translateFenestrationSurfaceDetailed(workspaceObject);
      break;
    }
  case openstudio::IddObjectType::Generator_MicroTurbine :
    {
      modelObject = translateGeneratorMicroTurbine(workspaceObject);
      break;
    }
  case openstudio::IddObjectType::GlobalGeometryRules :
    {
      // added by geometry translator, do not add to untranslated objects
      addToUntranslated = false;
      break; // no-op
    }
  case openstudio::IddObjectType::GasEquipment :
    {
      modelObject = translateGasEquipment(workspaceObject );
      break;
    }
  case openstudio::IddObjectType::GroundHeatExchanger_Vertical :
    {
      //modelObject = translateGroundHeatExchangerVertical(workspaceObject );
      break;
    }
  case openstudio::IddObjectType::HeatBalanceAlgorithm :
    {
      modelObject = translateHeatBalanceAlgorithm(workspaceObject);
      break;
    }
  case openstudio::IddObjectType::HotWaterEquipment :
    {
      modelObject = translateHotWaterEquipment(workspaceObject );
      break;
    }
  case openstudio::IddObjectType::HVACTemplate_Thermostat :
    {
      break; // no-op
    }
  case openstudio::IddObjectType::InternalMass :
    {
      modelObject = translateInternalMass(workspaceObject );
      break;
    }
  case openstudio::IddObjectType::Lights :
    {
      modelObject = translateLights(workspaceObject );
      break;
    }
  case openstudio::IddObjectType::Material :
    {
      modelObject = translateMaterial(workspaceObject);
      break;
    }
  case openstudio::IddObjectType::Material_AirGap :
    {
      modelObject = translateMaterialAirGap(workspaceObject);
      break;
    }
  case openstudio::IddObjectType::Material_NoMass :
    {
      modelObject = translateMaterialNoMass(workspaceObject);
      break;
    }
  case openstudio::IddObjectType::Meter_Custom :
    {
      modelObject = translateMeterCustom(workspaceObject);
      break;
    }
  case openstudio::IddObjectType::Meter_CustomDecrement :
    {
      modelObject = translateMeterCustomDecrement(workspaceObject);
      break;
    }
  case openstudio::IddObjectType::OtherEquipment :
    {
      modelObject = translateOtherEquipment(workspaceObject);
      break;
    }
  case openstudio::IddObjectType::OutdoorAir_Mixer :
    {
      break; // no-op
    }
  case openstudio::IddObjectType::OutdoorAir_Node :
    {
      break; // no-op
    }
  case openstudio::IddObjectType::OutdoorAir_NodeList :
    {
      break; // no-op
    }
  case openstudio::IddObjectType::Output_IlluminanceMap :
    {
      modelObject = translateOutputIlluminanceMap(workspaceObject);
      break;
    }
  case openstudio::IddObjectType::Output_Meter :
    {
      modelObject = translateOutputMeter(workspaceObject);
      break;
    }
  case openstudio::IddObjectType::Output_Meter_Cumulative :
    {
      modelObject = translateOutputMeterCumulative(workspaceObject);
      break;
    }
  case openstudio::IddObjectType::Output_Meter_Cumulative_MeterFileOnly :
    {
      modelObject = translateOutputMeterCumulativeMeterFileOnly(workspaceObject);
      break;
    }
  case openstudio::IddObjectType::Output_Meter_MeterFileOnly :
    {
      modelObject = translateOutputMeterMeterFileOnly(workspaceObject);
      break;
    }
  case openstudio::IddObjectType::Output_SQLite :
    {
      break; // no-op
    }
  case openstudio::IddObjectType::Output_Table_Monthly :
    {
      break; // no-op
    }
  case openstudio::IddObjectType::Output_Table_SummaryReports :
    {
      break; // no-op
    }
  case openstudio::IddObjectType::Output_Variable :
    {
      modelObject = translateOutputVariable(workspaceObject);
      break;
    }
  case openstudio::IddObjectType::OutputControl_Table_Style :
    {
      break; // no-op
    }
  case openstudio::IddObjectType::People :
    {
      modelObject = translatePeople(workspaceObject);
      break;
    }
  case openstudio::IddObjectType::Refrigeration_Case :
    {
      // modelObject = translateRefrigerationCase(workspaceObject);
      break;
    }
  case openstudio::IddObjectType::Refrigeration_Compressor :
    {
      // modelObject = translateRefrigerationCompressor(workspaceObject);
      break;
    }
  case openstudio::IddObjectType::RunPeriod :
    {
      modelObject = translateRunPeriod(workspaceObject);
      break;
    }
  case openstudio::IddObjectType::RunPeriodControl_DaylightSavingTime :
    {
      modelObject = translateRunPeriodControlDaylightSavingTime(workspaceObject);
      break;
    }
  case openstudio::IddObjectType::RunPeriodControl_SpecialDays :
    {
      //modelObject = translateRunPeriodControlSpecialDays(workspaceObject);
      break;
    }
  case openstudio::IddObjectType::Schedule_Compact :
    {
      modelObject = translateScheduleCompact(workspaceObject);
      break;
    }
  case openstudio::IddObjectType::Schedule_Constant :
    {
      modelObject = translateScheduleConstant(workspaceObject);
      break;
    }
  case openstudio::IddObjectType::Schedule_Day_Hourly :
    {
      modelObject = translateScheduleDayHourly(workspaceObject);
      break;
    }
  case openstudio::IddObjectType::Schedule_Day_Interval :
    {
      modelObject = translateScheduleDayInterval(workspaceObject);
      break;
    }
  case openstudio::IddObjectType::ScheduleTypeLimits :
    {
      modelObject = translateScheduleTypeLimits(workspaceObject);
      break;
    }
  case openstudio::IddObjectType::Schedule_Week_Daily :
    {
      modelObject = translateScheduleWeekDaily(workspaceObject);
      break;
    }
  case openstudio::IddObjectType::Schedule_Year :
    {
      modelObject = translateScheduleYear(workspaceObject);
      break;
    }
  case openstudio::IddObjectType::SetpointManager_MixedAir :
    {
      //modelObject = translateSetpointManagerMixedAir(workspaceObject);
      break;
    }
  case openstudio::IddObjectType::SetpointManager_Scheduled :
    {
      //modelObject = translateSetpointManagerScheduled(workspaceObject);
      break;
    }
  case openstudio::IddObjectType::SetpointManager_SingleZone_Reheat :
    {
      //modelObject = translateSetpointManagerSingleZoneReheat(workspaceObject);
      break;
    }
  case openstudio::IddObjectType::Shading_Building_Detailed :
    {
      modelObject = translateShadingBuildingDetailed(workspaceObject);
      break;
    }
  case openstudio::IddObjectType::Shading_Site_Detailed :
    {
      modelObject = translateShadingSiteDetailed(workspaceObject);
      break;
    }
  case openstudio::IddObjectType::Shading_Zone_Detailed :
    {
      modelObject = translateShadingZoneDetailed(workspaceObject);
      break;
    }
  case openstudio::IddObjectType::ShadowCalculation :
    {
      modelObject = translateShadowCalculation(workspaceObject);
      break;
    }
  case openstudio::IddObjectType::SimulationControl :
    {
      modelObject = translateSimulationControl(workspaceObject );
      break;
    }
  case openstudio::IddObjectType::Site_Location :
    {
      modelObject = translateSiteLocation(workspaceObject);
      break;
    }
  case openstudio::IddObjectType::Site_GroundReflectance :
    {
      //modelObject = translateSiteGroundReflectance(workspaceObject);
      break;
    }
  case openstudio::IddObjectType::Site_GroundTemperature_BuildingSurface :
    {
      //modelObject = translateSiteGroundTemperatureBuildingSurface(workspaceObject);
      break;
    }
  case openstudio::IddObjectType::Site_WaterMainsTemperature :
    {
      //modelObject = translateSiteWaterMainsTemperature(workspaceObject);
      break;
    }
  case openstudio::IddObjectType::Sizing_Parameters :
    {
      modelObject = translateSizingParameters(workspaceObject );
      break;
    }
  case openstudio::IddObjectType::SizingPeriod_DesignDay :
    {
      modelObject = translateSizingPeriodDesignDay(workspaceObject );
      break;
    }
  case openstudio::IddObjectType::Sizing_System :
    {
      //modelObject = translateSizingSystem(workspaceObject );
      break;
    }
  case openstudio::IddObjectType::Sizing_Zone :
    {
      modelObject = translateSizingZone(workspaceObject );
      break;
    }
  case openstudio::IddObjectType::SteamEquipment :
    {
      modelObject = translateSteamEquipment(workspaceObject);
      break;
    }
  case openstudio::IddObjectType::SurfaceConvectionAlgorithm_Inside :
    {
      //modelObject = translateSurfaceConvectionAlgorithmInside(workspaceObject);
      break;
    }
  case openstudio::IddObjectType::SurfaceConvectionAlgorithm_Outside :
    {
      //modelObject = translateSurfaceConvectionAlgorithmOutside(workspaceObject);
      break;
    }
  case openstudio::IddObjectType::ThermostatSetpoint_DualSetpoint :
    {
      modelObject = translateThermostatSetpointDualSetpoint(workspaceObject);
      break;
    }
  case openstudio::IddObjectType::Timestep :
    {
      modelObject = translateTimestep(workspaceObject);
      break;
    }
  case openstudio::IddObjectType::UtilityCost_Charge_Simple :
    {
      break; // no-op
    }
  case openstudio::IddObjectType::UtilityCost_Qualify :
    {
      break; // no-op
    }
  case openstudio::IddObjectType::Version :
   {
     modelObject = translateVersion(workspaceObject );
     break;
   }
  case openstudio::IddObjectType::WindowMaterial_Gas:
    {
      modelObject = translateWindowMaterialGas(workspaceObject);
      break;
    }
  case openstudio::IddObjectType::WindowMaterial_Glazing:
    {
      modelObject = translateWindowMaterialGlazing(workspaceObject);
      break;
    }
  case openstudio::IddObjectType::WindowMaterial_SimpleGlazingSystem:
    {
      modelObject = translateWindowMaterialSimpleGlazingSystem(workspaceObject);
      break;
    }
  case openstudio::IddObjectType::WindowProperty_FrameAndDivider:
  {
    modelObject = translateWindowPropertyFrameAndDivider(workspaceObject);
    break;
  }
  case openstudio::IddObjectType::Zone:
    {
      modelObject = translateZone(workspaceObject);
      break;
    }
  case openstudio::IddObjectType::ZoneAirHeatBalanceAlgorithm:
    {
      // DLM: why is this commented out?
      //modelObject = translateZoneAirHeatBalanceAlgorithm(workspaceObject);
      break;
    }
  case openstudio::IddObjectType::ZoneAirMassFlowConservation:
  {
    modelObject = translateZoneAirMassFlowConservation(workspaceObject);
    break;
  }
  case openstudio::IddObjectType::ZoneControl_Thermostat :
    {
      break; // no-op
    }
  case openstudio::IddObjectType::ZoneCrossMixing:
  {
    modelObject = translateZoneCrossMixing(workspaceObject);
    break;
  }
  case openstudio::IddObjectType::ZoneHVAC_EquipmentList :
    {
      //modelObject = translateZoneHVACEquipmentList(workspaceObject);
      break; 
    }
  case openstudio::IddObjectType::ZoneHVAC_IdealLoadsAirSystem :
    {
      //modelObject = translateZoneHVACIdealLoadsAirSystem(workspaceObject);
      break;
    }
  case openstudio::IddObjectType::ZoneInfiltration_DesignFlowRate :
    {
      modelObject = translateZoneInfiltrationDesignFlowRate(workspaceObject);
      break;
    }
  case openstudio::IddObjectType::ZoneInfiltration_EffectiveLeakageArea :
  {
      modelObject = translateZoneInfiltrationEffectiveLeakageArea(workspaceObject);
      break;
  }
  case openstudio::IddObjectType::ZoneList:
    {
      modelObject = translateZone(workspaceObject);
      break;
    }
  case openstudio::IddObjectType::ZoneMixing:
  {
    modelObject = translateZoneMixing(workspaceObject);
    break;
  }
  case openstudio::IddObjectType::ZoneVentilation_DesignFlowRate :
    {
      modelObject = translateZoneVentilationDesignFlowRate(workspaceObject);
      break;
    }
  default:
    {
      break; // no-op
    }
  }

  if( modelObject )
  {
    LOG(Trace,"Adding " << modelObject.get().briefDescription() << " to map.");
    m_workspaceToModelMap.insert(make_pair(workspaceObject.handle(), modelObject.get()));
  }else{
    if (addToUntranslated){
      if (std::find_if(m_untranslatedIdfObjects.begin(), m_untranslatedIdfObjects.end(), IdfObjectEqual(workspaceObject.idfObject())) == m_untranslatedIdfObjects.end()){
        LOG(Trace,"Ignoring " << workspaceObject.briefDescription() << ".");
        m_untranslatedIdfObjects.push_back(workspaceObject.idfObject());
      }
    }
  }

  if (m_progressBar){
    m_progressBar->setValue(m_untranslatedIdfObjects.size() + m_workspaceToModelMap.size());
  }

  return modelObject;
}