OptionalModelObject ReverseTranslator::translateAirTerminalSingleDuctUncontrolled( const WorkspaceObject & workspaceObject )
{
  if( workspaceObject.iddObject().type() != IddObjectType::AirTerminal_SingleDuct_Uncontrolled )
  {
     LOG(Error, "WorkspaceObject is not IddObjectType: AirTerminal_SingleDuct_Uncontrolled");
     return boost::none;
  }

  boost::optional<WorkspaceObject> wo = workspaceObject.getTarget(AirTerminal_SingleDuct_UncontrolledFields::AvailabilityScheduleName);
  boost::optional<Schedule> schedule;
  boost::optional<AirTerminalSingleDuctUncontrolled> airTerminal;
  boost::optional<double> value;

  if( wo )
  {
    boost::optional<ModelObject> mo = translateAndMapWorkspaceObject(wo.get());
    if( mo )
    {
      if( ! (schedule = mo->optionalCast<Schedule>()) )
      {
        LOG(Error, workspaceObject.briefDescription() << " does not have an associated availability schedule");

        return boost::none;
      }
    }
  }

  if( schedule )
  {
    airTerminal = AirTerminalSingleDuctUncontrolled(m_model,schedule.get());
  }

  if( airTerminal )
  {
    boost::optional<std::string> s = workspaceObject.getString(AirTerminal_SingleDuct_UncontrolledFields::Name);
    if( s )
    {
      airTerminal->setName(s.get());
    }

    s = workspaceObject.getString(AirTerminal_SingleDuct_UncontrolledFields::MaximumAirFlowRate);
    if( s && istringEqual(s.get(),"AutoSize") )
    {
      airTerminal->autosizeMaximumAirFlowRate();
    }
    else if( (value = workspaceObject.getDouble(AirTerminal_SingleDuct_UncontrolledFields::MaximumAirFlowRate)) )
    {
      airTerminal->setMaximumAirFlowRate(value.get());
    }

    return airTerminal.get();
  }
  else
  {
    LOG(Error, "Unknown error translating " << workspaceObject.briefDescription());

    return boost::none;
  }
}
OptionalModelObject ReverseTranslator::translateZoneInfiltrationEffectiveLeakageArea( const WorkspaceObject & workspaceObject )
{
  if( workspaceObject.iddObject().type() != IddObjectType::ZoneInfiltration_EffectiveLeakageArea ){
    LOG(Error, "WorkspaceObject " << workspaceObject.briefDescription()
        << " is not IddObjectType: SpaceInfiltration_EffectiveLeakageArea");
    return boost::none;
  }

  // create the instance
  SpaceInfiltrationEffectiveLeakageArea spaceInfiltrationEffectiveLeakageArea(m_model);

  OptionalString s = workspaceObject.name();
  if(s){
    spaceInfiltrationEffectiveLeakageArea.setName(*s);
  }

  OptionalWorkspaceObject target = workspaceObject.getTarget(ZoneInfiltration_EffectiveLeakageAreaFields::ZoneName);
  if (target){
    OptionalModelObject modelObject = translateAndMapWorkspaceObject(*target);
    if (modelObject){
      if (modelObject->optionalCast<Space>()){
        spaceInfiltrationEffectiveLeakageArea.setSpace(modelObject->cast<Space>());
      }else if (modelObject->optionalCast<SpaceType>()){
        spaceInfiltrationEffectiveLeakageArea.setSpaceType(modelObject->cast<SpaceType>());
      }
    }
  }

  target = workspaceObject.getTarget(ZoneInfiltration_EffectiveLeakageAreaFields::ScheduleName);
  if (target){
    OptionalModelObject modelObject = translateAndMapWorkspaceObject(*target);
    if (modelObject){
      if (OptionalSchedule intermediate = modelObject->optionalCast<Schedule>()){
        Schedule schedule(*intermediate);
        spaceInfiltrationEffectiveLeakageArea.setSchedule(schedule);
      }
    }
  }

  boost::optional<double> value = workspaceObject.getDouble(ZoneInfiltration_EffectiveLeakageAreaFields::EffectiveAirLeakageArea);
  if( value )
  {
    spaceInfiltrationEffectiveLeakageArea.setEffectiveAirLeakageArea(value.get());
  }

  value = workspaceObject.getDouble(ZoneInfiltration_EffectiveLeakageAreaFields::StackCoefficient);
  if( value )
  {
    spaceInfiltrationEffectiveLeakageArea.setStackCoefficient(value.get());
  }

  value = workspaceObject.getDouble(ZoneInfiltration_EffectiveLeakageAreaFields::WindCoefficient);
  if( value )
  {
    spaceInfiltrationEffectiveLeakageArea.setWindCoefficient(value.get());
  }
  
  return spaceInfiltrationEffectiveLeakageArea;
}
OptionalModelObject ReverseTranslator::translateThermostatSetpointDualSetpoint( const WorkspaceObject & workspaceObject )
{
OptionalModelObject result,temp;
  OptionalSchedule schedule;

  ThermostatSetpointDualSetpoint tsds(m_model);

  OptionalWorkspaceObject owo = workspaceObject.getTarget(ThermostatSetpoint_DualSetpointFields::HeatingSetpointTemperatureScheduleName);
  if(!owo)
  {
    LOG(Error, "Error importing object: "
             << workspaceObject.briefDescription()
             << " Can't find Schedule: ");
    return result;
  }
  temp = translateAndMapWorkspaceObject( *owo);
  if(temp)
  {
    schedule=temp->optionalCast<Schedule>();
    if(schedule){
      tsds.setHeatingSchedule( *schedule );
    }
  }

  owo = workspaceObject.getTarget(ThermostatSetpoint_DualSetpointFields::CoolingSetpointTemperatureScheduleName);
  if(!owo)
  {
    LOG(Error, "Error importing object: "
             << workspaceObject.briefDescription()
             << " Can't find Schedule: ");
    return result;
  }
  temp = translateAndMapWorkspaceObject( *owo);
  if(temp)
  {
    schedule=temp->optionalCast<Schedule>();
    if(schedule){
      tsds.setCoolingSchedule( *schedule );
    }
  }

  result = tsds;
  return result;
}
boost::optional<model::ModelObject> ReverseTranslator::translateExteriorLights(
    const WorkspaceObject& workspaceObject)
{
  if (workspaceObject.iddObject().type() != IddObjectType::Exterior_Lights) {
    LOG(Error,"WorkspaceObject " << workspaceObject.briefDescription()
        << " is not of IddObjectType::Exterior_Lights.");
    return boost::none;
  }

  model::ExteriorLightsDefinition definition(m_model);

  OptionalString s;
  OptionalDouble d;

  if ((s = workspaceObject.name())) {
    definition.setName(*s + " Definition");
  }

  if ((d = workspaceObject.getDouble(Exterior_LightsFields::DesignLevel))){
    definition.setDesignLevel(*d);
  }

  model::OptionalExteriorLights exteriorLights;
  model::OptionalSchedule schedule;

  if (OptionalWorkspaceObject target = workspaceObject.getTarget(Exterior_LightsFields::ScheduleName))
  {
    if (model::OptionalModelObject modelObject = translateAndMapWorkspaceObject(*target)) {
      schedule = modelObject->optionalCast<model::Schedule>();
    }
  }

  if (schedule) {
    try {
      exteriorLights = model::ExteriorLights(definition,*schedule);
    }
    catch (std::exception& e) {
      LOG(Warn,"Could not reverse translate " << workspaceObject.briefDescription()
          << " in full, because " << e.what() << ".");
    }
  }
  if (!exteriorLights) {
    exteriorLights = model::ExteriorLights(definition);
  }

  OS_ASSERT(exteriorLights);

  if ((s = workspaceObject.name())) {
    exteriorLights->setName(*s);
  }

  if ((s = workspaceObject.getString(Exterior_LightsFields::ControlOption,false,true))) {
    exteriorLights->setControlOption(*s);
  }

  if ((s = workspaceObject.getString(Exterior_LightsFields::EndUseSubcategory,false,true))) {
    exteriorLights->setEndUseSubcategory(*s);
  }

  return *exteriorLights;
}
OptionalModelObject ReverseTranslator::translateAirTerminalSingleDuctVAVNoReheat( const WorkspaceObject & workspaceObject )
{
  if( workspaceObject.iddObject().type() != IddObjectType::AirTerminal_SingleDuct_VAV_NoReheat )
  {
     LOG(Error, "WorkspaceObject is not IddObjectType: AirTerminal_SingleDuct_VAV_NoReheat");
     return boost::none;
  }

  boost::optional<WorkspaceObject> wo = workspaceObject.getTarget(AirTerminal_SingleDuct_VAV_NoReheatFields::AvailabilityScheduleName);
  boost::optional<Schedule> schedule;
  boost::optional<AirTerminalSingleDuctVAVNoReheat> airTerminal;

  if( wo )
  {
    boost::optional<ModelObject> mo = translateAndMapWorkspaceObject(wo.get());
    if( mo )
    {
      if( ! (schedule = mo->optionalCast<Schedule>()) )
      {
        LOG(Error, workspaceObject.briefDescription() << " does not have an associated availability schedule");

        return boost::none;
      }
    }
  }

  if( schedule )
  {
    airTerminal = AirTerminalSingleDuctVAVNoReheat( m_model,schedule.get() );
  }

  if( airTerminal )
  {
    boost::optional<double> value;
    boost::optional<std::string> s = workspaceObject.getString(AirTerminal_SingleDuct_VAV_NoReheatFields::Name);

    if( s )
    {
      airTerminal->setName(s.get());
    }

    // MaximumAirFlowRate
    value = workspaceObject.getDouble(AirTerminal_SingleDuct_VAV_NoReheatFields::MaximumAirFlowRate);
    s = workspaceObject.getString(AirTerminal_SingleDuct_VAV_NoReheatFields::MaximumAirFlowRate);
    if( value )
    {
      airTerminal->setMaximumAirFlowRate(value.get());
    }
    else if( s && istringEqual(s.get(),"Autosize") )
    {
      airTerminal->autosizeMaximumAirFlowRate();
    }
    else if( s && istringEqual(s.get(),"Autocalculate") )
    {
      airTerminal->autosizeMaximumAirFlowRate();
    }

    // ZoneMinimumAirFlowInputMethod
    s = workspaceObject.getString(AirTerminal_SingleDuct_VAV_NoReheatFields::ZoneMinimumAirFlowInputMethod);
    if( s )
    {
      airTerminal->setZoneMinimumAirFlowInputMethod(s.get());
    }

    // ConstantMinimumAirFlowFraction
    value = workspaceObject.getDouble(AirTerminal_SingleDuct_VAV_NoReheatFields::ConstantMinimumAirFlowFraction);
    if( value )
    {
      airTerminal->setConstantMinimumAirFlowFraction(value.get());
    }

    // FixedMinimumAirFlowRate
    value = workspaceObject.getDouble(AirTerminal_SingleDuct_VAV_NoReheatFields::FixedMinimumAirFlowRate);
    if( value )
    {
      airTerminal->setFixedMinimumAirFlowRate(value.get());
    }

    boost::optional<WorkspaceObject> _schedule;

    // MinimumAirFlowFractionScheduleName
    _schedule = workspaceObject.getTarget(AirTerminal_SingleDuct_VAV_NoReheatFields::MinimumAirFlowFractionScheduleName);
    if( _schedule )
    {
      boost::optional<ModelObject> mo = translateAndMapWorkspaceObject(_schedule.get());
      if( mo )
      {
        if( boost::optional<Schedule> schedule = mo->optionalCast<Schedule>() )
        {
          airTerminal->setMinimumAirFlowFractionSchedule(schedule.get());
        }
      }
    }

    return airTerminal.get();
  }
  else
  {
    LOG(Error, "Unknown error translating " << workspaceObject.briefDescription());

    return boost::none;
  }
}
OptionalModelObject ReverseTranslator::translateRefrigerationCase( const WorkspaceObject & workspaceObject )
{
  if( workspaceObject.iddObject().type() != IddObjectType::Refrigeration_Case )
  {
     LOG(Error, "WorkspaceObject is not IddObjectType: Refrigeration_Case");
     return boost::none;
  }

  boost::optional<WorkspaceObject> wo = workspaceObject.getTarget(Refrigeration_CaseFields::CaseDefrostScheduleName);
  boost::optional<Schedule> caseDefrostSchedule;
  boost::optional<RefrigerationCase> refrigerationCase;

  if( wo )
  {
    if( boost::optional<ModelObject> mo = translateAndMapWorkspaceObject(wo.get()) )
    {
      if( ! (caseDefrostSchedule = mo->optionalCast<Schedule>()) )
      {
        LOG(Error, workspaceObject.briefDescription() << " does not have an associated case defrost schedule");

        return boost::none;
      }
    }
  }

  if( caseDefrostSchedule )
  {
    refrigerationCase = RefrigerationCase( m_model,caseDefrostSchedule.get() );
  }

  if( refrigerationCase )
  {
    boost::optional<double> value;
    boost::optional<std::string> s = workspaceObject.getString(Refrigeration_CaseFields::Name);

// Name
    if( s )
    {
      refrigerationCase->setName(s.get());
    }
// AvailabilityScheduleName
    if( (wo = workspaceObject.getTarget(Refrigeration_CaseFields::AvailabilityScheduleName)) )
    {
      if( boost::optional<ModelObject> mo = translateAndMapWorkspaceObject(wo.get()) )
      {
        if( boost::optional<Schedule> schedule = mo->optionalCast<Schedule>() )
        {
          refrigerationCase->setAvailabilitySchedule(schedule.get());
        }
      }
    }
// ZoneName
    if( (wo = workspaceObject.getTarget(Refrigeration_CaseFields::ZoneName)) )
    {
      if( boost::optional<ModelObject> mo = translateAndMapWorkspaceObject(wo.get()) )
      {
        if( boost::optional<ThermalZone> thermalZone = mo->optionalCast<ThermalZone>() )
        {
          refrigerationCase->setThermalZone(thermalZone.get());
        }
      }
    }
// RatedAmbientTemperature
    value = workspaceObject.getDouble(Refrigeration_CaseFields::RatedAmbientTemperature);
    if( value )
    {
      refrigerationCase->setRatedAmbientTemperature(value.get());
    }
// RatedAmbientRelativeHumidity
    value = workspaceObject.getDouble(Refrigeration_CaseFields::RatedAmbientRelativeHumidity);
    if( value )
    {
      refrigerationCase->setRatedAmbientRelativeHumidity(value.get());
    }
// RatedTotalCoolingCapacityperUnitLength
    value = workspaceObject.getDouble(Refrigeration_CaseFields::RatedTotalCoolingCapacityperUnitLength);
    if( value )
    {
      refrigerationCase->setRatedTotalCoolingCapacityperUnitLength(value.get());
    }
// RatedLatentHeatRatio
    value = workspaceObject.getDouble(Refrigeration_CaseFields::RatedLatentHeatRatio);
    if( value )
    {
      refrigerationCase->setRatedLatentHeatRatio(value.get());
    }
// RatedRuntimeFraction
    value = workspaceObject.getDouble(Refrigeration_CaseFields::RatedRuntimeFraction);
    if( value )
    {
      refrigerationCase->setRatedRuntimeFraction(value.get());
    }
// CaseLength
    value = workspaceObject.getDouble(Refrigeration_CaseFields::CaseLength);
    if( value )
    {
      refrigerationCase->setCaseLength(value.get());
    }
// CaseOperatingTemperature
    value = workspaceObject.getDouble(Refrigeration_CaseFields::CaseOperatingTemperature);
    if( value )
    {
      refrigerationCase->setCaseOperatingTemperature(value.get());
    }
// LatentCaseCreditCurveType
    s = workspaceObject.getString(Refrigeration_CaseFields::LatentCaseCreditCurveType);
    if( s )
    {
      refrigerationCase->setLatentCaseCreditCurveType(s.get());
    }
// LatentCaseCreditCurveName
    if( (wo = workspaceObject.getTarget(Refrigeration_CaseFields::LatentCaseCreditCurveName)) )
    {
      if( boost::optional<ModelObject> mo = translateAndMapWorkspaceObject(wo.get()) )
      {
        if( boost::optional<CurveCubic> curve = mo->optionalCast<CurveCubic>() )
        {
          refrigerationCase->setLatentCaseCreditCurve(curve.get());
        }
      }
    }
// StandardCaseFanPowerperUnitLength
    value = workspaceObject.getDouble(Refrigeration_CaseFields::StandardCaseFanPowerperUnitLength);
    if( value )
    {
      refrigerationCase->setStandardCaseFanPowerperUnitLength(value.get());
    }
// OperatingCaseFanPowerperUnitLength
    value = workspaceObject.getDouble(Refrigeration_CaseFields::OperatingCaseFanPowerperUnitLength);
    if( value )
    {
      refrigerationCase->setOperatingCaseFanPowerperUnitLength(value.get());
    }
// StandardCaseLightingPowerperUnitLength
    value = workspaceObject.getDouble(Refrigeration_CaseFields::StandardCaseLightingPowerperUnitLength);
    if( value )
    {
      refrigerationCase->setStandardCaseLightingPowerperUnitLength(value.get());
    }
// InstalledCaseLightingPowerperUnitLength
    value = workspaceObject.getDouble(Refrigeration_CaseFields::InstalledCaseLightingPowerperUnitLength);
    if( value )
    {
      refrigerationCase->setInstalledCaseLightingPowerperUnitLength(value.get());
    }
// CaseLightingScheduleName
    if( (wo = workspaceObject.getTarget(Refrigeration_CaseFields::CaseLightingScheduleName)) )
    {
      if( boost::optional<ModelObject> mo = translateAndMapWorkspaceObject(wo.get()) )
      {
        if( boost::optional<Schedule> schedule = mo->optionalCast<Schedule>() )
        {
          refrigerationCase->setCaseLightingSchedule(schedule.get());
        }
      }
    }
// FractionofLightingEnergytoCase
    value = workspaceObject.getDouble(Refrigeration_CaseFields::FractionofLightingEnergytoCase);
    if( value )
    {
      refrigerationCase->setFractionofLightingEnergytoCase(value.get());
    }
// CaseAntiSweatHeaterPowerperUnitLength
    value = workspaceObject.getDouble(Refrigeration_CaseFields::CaseAntiSweatHeaterPowerperUnitLength);
    if( value )
    {
      refrigerationCase->setCaseAntiSweatHeaterPowerperUnitLength(value.get());
    }
// MinimumAntiSweatHeaterPowerperUnitLength
    value = workspaceObject.getDouble(Refrigeration_CaseFields::MinimumAntiSweatHeaterPowerperUnitLength);
    if( value )
    {
      refrigerationCase->setMinimumAntiSweatHeaterPowerperUnitLength(value.get());
    }
// AntiSweatHeaterControlType
    s = workspaceObject.getString(Refrigeration_CaseFields::AntiSweatHeaterControlType);
    if( s )
    {
      refrigerationCase->setAntiSweatHeaterControlType(s.get());
    }
// HumidityatZeroAntiSweatHeaterEnergy
    value = workspaceObject.getDouble(Refrigeration_CaseFields::HumidityatZeroAntiSweatHeaterEnergy);
    if( value )
    {
      refrigerationCase->setHumidityatZeroAntiSweatHeaterEnergy(value.get());
    }
// CaseHeight
    value = workspaceObject.getDouble(Refrigeration_CaseFields::CaseHeight);
    if( value )
    {
      refrigerationCase->setCaseHeight(value.get());
    }
// FractionofAntiSweatHeaterEnergytoCase
    value = workspaceObject.getDouble(Refrigeration_CaseFields::FractionofAntiSweatHeaterEnergytoCase);
    if( value )
    {
      refrigerationCase->setFractionofAntiSweatHeaterEnergytoCase(value.get());
    }
// CaseDefrostPowerperUnitLength
    value = workspaceObject.getDouble(Refrigeration_CaseFields::CaseDefrostPowerperUnitLength);
    if( value )
    {
      refrigerationCase->setCaseDefrostPowerperUnitLength(value.get());
    }
// CaseDefrostType
    s = workspaceObject.getString(Refrigeration_CaseFields::CaseDefrostType);
    if( s )
    {
      refrigerationCase->setCaseDefrostType(s.get());
    }
// CaseDefrostScheduleName
    if( (wo = workspaceObject.getTarget(Refrigeration_CaseFields::CaseDefrostScheduleName)) )
    {
      if( boost::optional<ModelObject> mo = translateAndMapWorkspaceObject(wo.get()) )
      {
        if( boost::optional<Schedule> schedule = mo->optionalCast<Schedule>() )
        {
          refrigerationCase->setCaseDefrostSchedule(schedule.get());
        }
      }
    }
// CaseDefrostDripDownScheduleName
    if( (wo = workspaceObject.getTarget(Refrigeration_CaseFields::CaseDefrostDripDownScheduleName)) )
    {
      if( boost::optional<ModelObject> mo = translateAndMapWorkspaceObject(wo.get()) )
      {
        if( boost::optional<Schedule> schedule = mo->optionalCast<Schedule>() )
        {
          refrigerationCase->setCaseDefrostDripDownSchedule(schedule.get());
        }
      }
    }
// DefrostEnergyCorrectionCurveType
    s = workspaceObject.getString(Refrigeration_CaseFields::DefrostEnergyCorrectionCurveType);
    if( s )
    {
      refrigerationCase->setDefrostEnergyCorrectionCurveType(s.get());
    }
// DefrostEnergyCorrectionCurveName
    if( (wo = workspaceObject.getTarget(Refrigeration_CaseFields::DefrostEnergyCorrectionCurveName)) )
    {
      if( boost::optional<ModelObject> mo = translateAndMapWorkspaceObject(wo.get()) )
      {
        if( boost::optional<CurveCubic> curve = mo->optionalCast<CurveCubic>() )
        {
          refrigerationCase->setDefrostEnergyCorrectionCurve(curve.get());
        }
      }
    }
// UnderCaseHVACReturnAirFraction
    value = workspaceObject.getDouble(Refrigeration_CaseFields::UnderCaseHVACReturnAirFraction);
    if( value )
    {
      refrigerationCase->setUnderCaseHVACReturnAirFraction(value.get());
    }
// RefrigeratedCaseRestockingScheduleName
    if( (wo = workspaceObject.getTarget(Refrigeration_CaseFields::RefrigeratedCaseRestockingScheduleName)) )
    {
      if( boost::optional<ModelObject> mo = translateAndMapWorkspaceObject(wo.get()) )
      {
        if( boost::optional<Schedule> schedule = mo->optionalCast<Schedule>() )
        {
          refrigerationCase->setRefrigeratedCaseRestockingSchedule(schedule.get());
        }
      }
    }
// CaseCreditFractionScheduleName
    if( (wo = workspaceObject.getTarget(Refrigeration_CaseFields::CaseCreditFractionScheduleName)) )
    {
      if( boost::optional<ModelObject> mo = translateAndMapWorkspaceObject(wo.get()) )
      {
        if( boost::optional<Schedule> schedule = mo->optionalCast<Schedule>() )
        {
          refrigerationCase->setCaseCreditFractionSchedule(schedule.get());
        }
      }
    }
// DesignEvaporatorTemperatureorBrineInletTemperature
    value = workspaceObject.getDouble(Refrigeration_CaseFields::DesignEvaporatorTemperatureorBrineInletTemperature);
    if( value )
    {
      refrigerationCase->setDesignEvaporatorTemperatureorBrineInletTemperature(value.get());
    }
// AverageRefrigerantChargeInventory
    value = workspaceObject.getDouble(Refrigeration_CaseFields::AverageRefrigerantChargeInventory);
    if( value )
    {
      refrigerationCase->setAverageRefrigerantChargeInventory(value.get());
    }

    return refrigerationCase.get();
  }
  else
  {
    LOG(Error, "Unknown error translating " << workspaceObject.briefDescription());

    return boost::none;
  }
}
OptionalModelObject ReverseTranslator::translateGeneratorMicroTurbine( const WorkspaceObject & workspaceObject )
{

  OptionalModelObject result,temp;
  OptionalDouble d;
  boost::optional<WorkspaceObject> owo;
  OptionalString optS;
  
  
  // TODO: The availability schedule is in the ElectricLoadCenter:Generators (list) in E+, here it's carried by the generator itself
  // Should also get the Rated Thermal To Electrical Power Ratio in the list

  //Generator:MicroTurbine,
  //    Capstone C65,            !- Name

  openstudio::model::GeneratorMicroTurbine mchp( m_model );
  
  // Name
  optS = workspaceObject.name();
  if(optS)
  {
    mchp.setName(*optS);
  }

  
    
  //    65000,                   !- Reference Electrical Power Output {W}
  d = workspaceObject.getDouble(Generator_MicroTurbineFields::ReferenceElectricalPowerOutput);
  if(d)
  {
    mchp.setReferenceElectricalPowerOutput(*d);
  }
  //    29900,                   !- Minimum Full Load Electrical Power Output {W}
  d = workspaceObject.getDouble(Generator_MicroTurbineFields::MinimumFullLoadElectricalPowerOutput);
  if(d)
  {
    mchp.setMinimumFullLoadElectricalPowerOutput(*d);
  }
  //    65000,                   !- Maximum Full Load Electrical Power Output {W} setMaximumFullLoadElectricalPowerOutput
  d = workspaceObject.getDouble(Generator_MicroTurbineFields::MaximumFullLoadElectricalPowerOutput);
  if(d)
  {
    mchp.setMaximumFullLoadElectricalPowerOutput(*d);
  }

  //    0.29,                    !- Reference Electrical Efficiency Using Lower Heating Value
  d = workspaceObject.getDouble(Generator_MicroTurbineFields::ReferenceElectricalEfficiencyUsingLowerHeatingValue);
  if(d)
  {
    mchp.setReferenceElectricalEfficiencyUsingLowerHeatingValue(*d);
  }

  //    15.0,                    !- Reference Combustion Air Inlet Temperature {C}
  d = workspaceObject.getDouble(Generator_MicroTurbineFields::ReferenceCombustionAirInletTemperature);
  if(d)
  {
    mchp.setReferenceCombustionAirInletTemperature(*d);
  }

  //    0.00638,                 !- Reference Combustion Air Inlet Humidity Ratio {kgWater/kgDryAir}
  d = workspaceObject.getDouble(Generator_MicroTurbineFields::ReferenceCombustionAirInletHumidityRatio);
  if(d)
  {
    mchp.setReferenceCombustionAirInletHumidityRatio(*d);
  }

  //    0.0,                     !- Reference Elevation {m}
  d = workspaceObject.getDouble(Generator_MicroTurbineFields::MinimumFullLoadElectricalPowerOutput);
  if(d)
  {
    mchp.setMinimumFullLoadElectricalPowerOutput(*d);
  }

  //    Capstone C65 Power_vs_Temp_Elev,  !- Electrical Power Function of Temperature and Elevation Curve Name
  // BiquadraticCurves
  if( (owo = workspaceObject.getTarget(Generator_MicroTurbineFields::ElectricalPowerFunctionofTemperatureandElevationCurveName)) )
    {
      if( boost::optional<ModelObject> mo = translateAndMapWorkspaceObject(owo.get()) )
      {
        if( boost::optional<CurveBiquadratic> curve = mo->optionalCast<CurveBiquadratic>() )
        {
          mchp.setElectricalPowerFunctionofTemperatureandElevationCurve(curve.get());
        }
        else
        {
          LOG(Warn, workspaceObject.briefDescription() << " has a wrong type curve for field Electrical Power Function of Temperature and Elevation Curve Name");
        }
      }
    }

  //    Capstone C65 Efficiency_vs_Temp,  !- Electrical Efficiency Function of Temperature Curve Name
  // QuadraticCubicCurves
  if( (owo = workspaceObject.getTarget(Generator_MicroTurbineFields::ElectricalEfficiencyFunctionofTemperatureCurveName)) )
    {
      if( boost::optional<ModelObject> mo = translateAndMapWorkspaceObject(owo.get()) )
      {
        if( boost::optional<CurveQuadratic> curve = mo->optionalCast<CurveQuadratic>() )
        {
          mchp.setElectricalEfficiencyFunctionofTemperatureCurve(curve.get());
        }
        else if( boost::optional<CurveCubic> curve = mo->optionalCast<CurveCubic>() )
        {
          mchp.setElectricalEfficiencyFunctionofTemperatureCurve(curve.get());
        }
        else
        {
          LOG(Warn, workspaceObject.briefDescription() << " has a wrong type curve for field Electrical Efficiency Function of Temperature Curve Name");
        }
      }
    }
  

  //    Capstone C65 Efficiency_vs_PLR,  !- Electrical Efficiency Function of Part Load Ratio Curve Name
  // QuadraticCubicCurves
  // setElectricalEfficiencyFunctionofPartLoadRatioCurve
  if( (owo = workspaceObject.getTarget(Generator_MicroTurbineFields::ElectricalEfficiencyFunctionofPartLoadRatioCurveName)) )
    {
      if( boost::optional<ModelObject> mo = translateAndMapWorkspaceObject(owo.get()) )
      {
        if( boost::optional<CurveQuadratic> curve = mo->optionalCast<CurveQuadratic>() )
        {
          mchp.setElectricalEfficiencyFunctionofPartLoadRatioCurve(curve.get());
        }
        else if( boost::optional<CurveCubic> curve = mo->optionalCast<CurveCubic>() )
        {
          mchp.setElectricalEfficiencyFunctionofPartLoadRatioCurve(curve.get());
        }
        else
        {
          LOG(Warn, workspaceObject.briefDescription() << " has a wrong type curve for field Electrical Efficiency Function of Part Load Ratio Curve Name");
        }
      }
    }

  //    NaturalGas,              !- Fuel Type
  optS = workspaceObject.getString(Generator_MicroTurbineFields::FuelType);
  if(optS)
  {
    mchp.setFuelType(*optS);
  }
    
  //    50000,                   !- Fuel Higher Heating Value {kJ/kg}
  d = workspaceObject.getDouble(Generator_MicroTurbineFields::FuelHigherHeatingValue);
  if(d)
  {
    mchp.setFuelHigherHeatingValue(*d);
  }

  //    45450,                   !- Fuel Lower Heating Value {kJ/kg}
  d = workspaceObject.getDouble(Generator_MicroTurbineFields::FuelLowerHeatingValue);
  if(d)
  {
    mchp.setFuelLowerHeatingValue(*d);
  }

  //    300,                     !- Standby Power {W}
  d = workspaceObject.getDouble(Generator_MicroTurbineFields::StandbyPower);
  if(d)
  {
    mchp.setStandbyPower(*d);
  }

  //    4500,                    !- Ancillary Power {W}
  d = workspaceObject.getDouble(Generator_MicroTurbineFields::AncillaryPower);
  if(d)
  {
    mchp.setAncillaryPower(*d);
  }

  //    ,                        !- Ancillary Power Function of Fuel Input Curve Name
  // QuadraticCurves
  // mchp.setAncillaryPowerFunctionofFuelInputCurve
  if( (owo = workspaceObject.getTarget(Generator_MicroTurbineFields::AncillaryPowerFunctionofFuelInputCurveName)) )
    {
      if( boost::optional<ModelObject> mo = translateAndMapWorkspaceObject(owo.get()) )
      {
        if( boost::optional<CurveQuadratic> curve = mo->optionalCast<CurveQuadratic>() )
        {
          mchp.setAncillaryPowerFunctionofFuelInputCurve(curve.get());
        }
        else
        {
          LOG(Warn, workspaceObject.briefDescription() << " has a wrong type curve for field Ancillary Power Function of Fuel Input Curve Name");
        }
      }
    }

  
  // Fields in between (in E+.idd) are moved at the end in the Heat Recovery section

  //    Capstone C65 Combustion Air Inlet Node,  !- Combustion Air Inlet Node Name
  //    Capstone C65 Combustion Air Outlet Node,  !- Combustion Air Outlet Node Name


  //    0.489885,                !- Reference Exhaust Air Mass Flow Rate {kg/s}
  d = workspaceObject.getDouble(Generator_MicroTurbineFields::ReferenceExhaustAirMassFlowRate);
  if(d)
  {
    mchp.setReferenceExhaustAirMassFlowRate(*d);
  }

  //    Capstone C65 ExhAirFlowRate_vs_InletTemp,  !- Exhaust Air Flow Rate Function of Temperature Curve Name
  // QuadraticCubicCurves
  // mchp.setExhaustAirFlowRateFunctionofTemperatureCurve
  if( (owo = workspaceObject.getTarget(Generator_MicroTurbineFields::ExhaustAirFlowRateFunctionofTemperatureCurveName)) )
    {
      if( boost::optional<ModelObject> mo = translateAndMapWorkspaceObject(owo.get()) )
      {
        if( boost::optional<CurveQuadratic> curve = mo->optionalCast<CurveQuadratic>() )
        {
          mchp.setExhaustAirFlowRateFunctionofTemperatureCurve(curve.get());
        }
        else if( boost::optional<CurveCubic> curve = mo->optionalCast<CurveCubic>() )
        {
          mchp.setExhaustAirFlowRateFunctionofTemperatureCurve(curve.get());
        }
        else
        {
          LOG(Warn, workspaceObject.briefDescription() << " has a wrong type curve for field Exhaust Air Flow Rate Function of Temperature Curve Name");
        }
      }
    }

  //    Capstone C65 ExhAirFlowRate_vs_PLR,  !- Exhaust Air Flow Rate Function of Part Load Ratio Curve Name
  // QuadraticCubicCurves
  // mchp.setExhaustAirFlowRateFunctionofPartLoadRatioCurve(curve)
  if( (owo = workspaceObject.getTarget(Generator_MicroTurbineFields::ExhaustAirFlowRateFunctionofPartLoadRatioCurveName)) )
    {
      if( boost::optional<ModelObject> mo = translateAndMapWorkspaceObject(owo.get()) )
      {
        if( boost::optional<CurveQuadratic> curve = mo->optionalCast<CurveQuadratic>() )
        {
          mchp.setExhaustAirFlowRateFunctionofPartLoadRatioCurve(curve.get());
        }
        else if( boost::optional<CurveCubic> curve = mo->optionalCast<CurveCubic>() )
        {
          mchp.setExhaustAirFlowRateFunctionofPartLoadRatioCurve(curve.get());
        }
        else
        {
          LOG(Warn, workspaceObject.briefDescription() << " has a wrong type curve for field Exhaust Air Flow Rate Function of Part Load Ratio Curve Name");
        }
      }
    }

  //    308.9,                   !- Nominal Exhaust Air Outlet Temperature
  d = workspaceObject.getDouble(Generator_MicroTurbineFields::NominalExhaustAirOutletTemperature);
  if(d)
  {
    mchp.setNominalExhaustAirOutletTemperature(*d);
  }

  //    Capstone C65 ExhaustTemp_vs_InletTemp,  !- Exhaust Air Temperature Function of Temperature Curve Name
  // QuadraticCubicCurves
  // mchp.setExhaustAirTemperatureFunctionofTemperatureCurve(curve)
  if( (owo = workspaceObject.getTarget(Generator_MicroTurbineFields::ExhaustAirTemperatureFunctionofTemperatureCurveName)) )
    {
      if( boost::optional<ModelObject> mo = translateAndMapWorkspaceObject(owo.get()) )
      {
        if( boost::optional<CurveQuadratic> curve = mo->optionalCast<CurveQuadratic>() )
        {
          mchp.setExhaustAirTemperatureFunctionofTemperatureCurve(curve.get());
        }
        else if( boost::optional<CurveCubic> curve = mo->optionalCast<CurveCubic>() )
        {
          mchp.setExhaustAirTemperatureFunctionofTemperatureCurve(curve.get());
        }
        else
        {
          LOG(Warn, workspaceObject.briefDescription() << " has a wrong type curve for field Exhaust Air Temperature Function of Temperature Curve Name");
        }
      }
    }

  //    Capstone C65 ExhaustTemp_vs_PLR;  !- Exhaust Air Temperature Function of Part Load Ratio Curve Name
  // QuadraticCubicCurves
  // mchp.setExhaustAirTemperatureFunctionofPartLoadRatioCurve(curve)
  if( (owo = workspaceObject.getTarget(Generator_MicroTurbineFields::ExhaustAirTemperatureFunctionofPartLoadRatioCurveName)) )
    {
      if( boost::optional<ModelObject> mo = translateAndMapWorkspaceObject(owo.get()) )
      {
        if( boost::optional<CurveQuadratic> curve = mo->optionalCast<CurveQuadratic>() )
        {
          mchp.setExhaustAirTemperatureFunctionofPartLoadRatioCurve(curve.get());
        }
        else if( boost::optional<CurveCubic> curve = mo->optionalCast<CurveCubic>() )
        {
          mchp.setExhaustAirTemperatureFunctionofPartLoadRatioCurve(curve.get());
        }
        else
        {
          LOG(Warn, workspaceObject.briefDescription() << " has a wrong type curve for field Exhaust Air Temperature Function of Part Load Ratio Curve Name");
        }
      }
    }
    
    
  /// HEAT RECOVERY PORTION
  
  // Would need to add that to the plantLoop reverse translator
  //    Capstone C65 Heat Recovery Water Inlet Node,  !- Heat Recovery Water Inlet Node Name
  //    Capstone C65 Heat Recovery Water Outlet Node,  !- Heat Recovery Water Outlet Node Name
  

  
  
  // TODO: For now, I trigger the creation is the 'Reference Thermal Efficiency Using Lower Heat Value' is filled.
  // TODO: I should trigger it based on the `Rated Thermal To Electrical Power Ratio in the list`  in the ElectricLoadCenter:Generators (list)
  // TODO: But in order to do that, the ElectricLoadCenter:Distribution & ElectricLoadCenter:Generators need to have a reverse translator
  
  //    0.4975,                  !- Reference Thermal Efficiency Using Lower Heat Value
  d = workspaceObject.getDouble(Generator_MicroTurbineFields::ReferenceThermalEfficiencyUsingLowerHeatValue);
  
  if(d)
  {
   
    // Create a GeneratorMicroTurbineHeatRecovery module, and assign it to the MicroTurbine
    // I've Set the Name in the constructor
    openstudio::model::GeneratorMicroTurbineHeatRecovery mchpHR (m_model, mchp);
    
    // Assign the Reference Thermal Efficiency Using Lower Heat Value
    mchpHR.setReferenceThermalEfficiencyUsingLowerHeatValue(*d);
    

    //    60.0,                    !- Reference Inlet Water Temperature {C}
    d = workspaceObject.getDouble(Generator_MicroTurbineFields::ReferenceInletWaterTemperature);
    if(d)
    {
      mchpHR.setReferenceInletWaterTemperature(*d);
    }
    
    //    PlantControl,            !- Heat Recovery Water Flow Operating Mode
    optS = workspaceObject.getString(Generator_MicroTurbineFields::HeatRecoveryWaterFlowOperatingMode);
    if(optS)
    {
      mchpHR.setHeatRecoveryWaterFlowOperatingMode(*optS);
    }
    
    //    0.00252362,              !- Reference Heat Recovery Water Flow Rate {m3/s}
    d = workspaceObject.getDouble(Generator_MicroTurbineFields::ReferenceHeatRecoveryWaterFlowRate);
    if(d)
    {
      mchpHR.setReferenceHeatRecoveryWaterFlowRate(*d);
    }
 
    //    ,                        !- Heat Recovery Water Flow Rate Function of Temperature and Power Curve Name
    // BiquadraticCurves
    // mchpHR.setHeatRecoveryWaterFlowRateFunctionofTemperatureandPowerCurve();
    if( (owo = workspaceObject.getTarget(Generator_MicroTurbineFields::HeatRecoveryWaterFlowRateFunctionofTemperatureandPowerCurveName)) )
      {
        if( boost::optional<ModelObject> mo = translateAndMapWorkspaceObject(owo.get()) )
        {
          if( boost::optional<CurveBiquadratic> curve = mo->optionalCast<CurveBiquadratic>() )
          {
            mchpHR.setHeatRecoveryWaterFlowRateFunctionofTemperatureandPowerCurve(curve.get());
          }
          else
          {
            LOG(Warn, workspaceObject.briefDescription() << " has a wrong type curve for field Heat Recovery Water Flow Rate Function of Temperature and Power Curve Name");
          }
        }
      }

    //    Capstone C65 ThermalEff_vs_Temp_Elev,  !- Thermal Efficiency Function of Temperature and Elevation Curve Name
    // BicubicBiquadraticCurves
    // mchpHR.setThermalEfficiencyFunctionofTemperatureandElevationCurve();
    if( (owo = workspaceObject.getTarget(Generator_MicroTurbineFields::ThermalEfficiencyFunctionofTemperatureandElevationCurveName)) )
      {
        if( boost::optional<ModelObject> mo = translateAndMapWorkspaceObject(owo.get()) )
        {
          if( boost::optional<CurveBicubic> curve = mo->optionalCast<CurveBicubic>() )
          {
            mchpHR.setThermalEfficiencyFunctionofTemperatureandElevationCurve(curve.get());
          }
          else if( boost::optional<CurveBiquadratic> curve = mo->optionalCast<CurveBiquadratic>() )
          {
            mchpHR.setThermalEfficiencyFunctionofTemperatureandElevationCurve(curve.get());
          }
          else
          {
            LOG(Warn, workspaceObject.briefDescription() << " has a wrong type curve for field Thermal Efficiency Function of Temperature and Elevation Curve Name");
          }
        }
      }

    //    Capstone C65 HeatRecoveryRate_vs_PLR,  !- Heat Recovery Rate Function of Part Load Ratio Curve Name
    // QuadraticCubicCurves
    // mchpHR.setHeatRecoveryRateFunctionofPartLoadRatioCurve();
    if( (owo = workspaceObject.getTarget(Generator_MicroTurbineFields::HeatRecoveryRateFunctionofPartLoadRatioCurveName)) )
      {
        if( boost::optional<ModelObject> mo = translateAndMapWorkspaceObject(owo.get()) )
        {
          if( boost::optional<CurveQuadratic> curve = mo->optionalCast<CurveQuadratic>() )
          {
            mchpHR.setHeatRecoveryRateFunctionofPartLoadRatioCurve(curve.get());
          }
          else if( boost::optional<CurveCubic> curve = mo->optionalCast<CurveCubic>() )
          {
            mchpHR.setHeatRecoveryRateFunctionofPartLoadRatioCurve(curve.get());
          }
          else
          {
            LOG(Warn, workspaceObject.briefDescription() << " has a wrong type curve for field Heat Recovery Rate Function of Part Load Ratio Curve Name");
          }
        }
      }

    //    Capstone C65 HeatRecoveryRate_vs_InletTemp,  !- Heat Recovery Rate Function of Inlet Water Temperature Curve Name
    // QuadraticCurves
    // mchpHR.setHeatRecoveryRateFunctionofInletWaterTemperatureCurve();
    if ((owo = workspaceObject.getTarget(Generator_MicroTurbineFields::HeatRecoveryRateFunctionofInletWaterTemperatureCurveName)))
      {
        if( boost::optional<ModelObject> mo = translateAndMapWorkspaceObject(owo.get()) )
        {
          if( boost::optional<CurveQuadratic> curve = mo->optionalCast<CurveQuadratic>() )
          {
            mchpHR.setHeatRecoveryRateFunctionofInletWaterTemperatureCurve(curve.get());
          }
          else
          {
            LOG(Warn, workspaceObject.briefDescription() << " has a wrong type curve for field Heat Recovery Rate Function of Part Load Ratio Curve Name");
          }
        }
      }

    //    Capstone C65 HeatRecoveryRate_vs_WaterFlow,  !- Heat Recovery Rate Function of Water Flow Rate Curve Name
    // QuadraticCurves
    // mchpHR.setHeatRecoveryRateFunctionofInletWaterFlowRateCurve();
    if( (owo = workspaceObject.getTarget(Generator_MicroTurbineFields::HeatRecoveryRateFunctionofWaterFlowRateCurveName)) )
      {
        if( boost::optional<ModelObject> mo = translateAndMapWorkspaceObject(owo.get()) )
        {
          if( boost::optional<CurveQuadratic> curve = mo->optionalCast<CurveQuadratic>() )
          {
            mchpHR.setHeatRecoveryRateFunctionofWaterFlowRateCurve(curve.get());
          }
          else
          {
            LOG(Warn, workspaceObject.briefDescription() << " has a wrong type curve for field Heat Recovery Rate Function of Water Flow Rate Curve Name");
          }
        }
      }

    //    0.001577263,             !- Minimum Heat Recovery Water Flow Rate {m3/s}
    d = workspaceObject.getDouble(Generator_MicroTurbineFields::MinimumHeatRecoveryWaterFlowRate);
    if(d)
    {
      mchpHR.setMinimumHeatRecoveryWaterFlowRate(*d);
    }

    //    0.003785432,             !- Maximum Heat Recovery Water Flow Rate {m3/s}
    d = workspaceObject.getDouble(Generator_MicroTurbineFields::MaximumHeatRecoveryWaterFlowRate);
    if(d)
    {
      mchpHR.setMaximumHeatRecoveryWaterFlowRate(*d);
    }

    //    82.2,                    !- Maximum Heat Recovery Water Temperature {C}
    d = workspaceObject.getDouble(Generator_MicroTurbineFields::MaximumHeatRecoveryWaterTemperature);
    if(d)
    {
      mchpHR.setMaximumHeatRecoveryWaterTemperature(*d);
    }
    
    
  }
    
    
  result=mchp;
  return result;
}
OptionalModelObject ReverseTranslator::translateSetpointManagerSingleZoneReheat( const WorkspaceObject & workspaceObject )
{
  if( workspaceObject.iddObject().type() != IddObjectType::SetpointManager_SingleZone_Reheat )
  {
     LOG(Error, "WorkspaceObject is not IddObjectType: SetpointManager_SingleZone_Reheat");
     return boost::none;
  }

  bool nodeFound = false;

  if( boost::optional<std::string> setpointNodeName = workspaceObject.getString(SetpointManager_SingleZone_ReheatFields::SetpointNodeorNodeListName) )
  {
    boost::optional<Node> setpointNode = m_model.getModelObjectByName<Node>(setpointNodeName.get());

    if( setpointNode ) { nodeFound = true; }
  }

  if( ! nodeFound )
  {
    LOG(Error, workspaceObject.briefDescription() << " is not attached to a node in the model");

    return boost::none;
  }

  SetpointManagerSingleZoneReheat mo(m_model);

  boost::optional<std::string> s = workspaceObject.getString(SetpointManager_SingleZone_ReheatFields::Name);
  if( s )
  {
    mo.setName(s.get());
  }

  boost::optional<double> value = workspaceObject.getDouble(SetpointManager_SingleZone_ReheatFields::MinimumSupplyAirTemperature);
  if( value )
  {
    mo.setMinimumSupplyAirTemperature(value.get());
  }

  value = workspaceObject.getDouble(SetpointManager_SingleZone_ReheatFields::MaximumSupplyAirTemperature);
  if( value )
  {
    mo.setMaximumSupplyAirTemperature(value.get());
  }

  s = workspaceObject.getString(SetpointManager_SingleZone_ReheatFields::ControlZoneName);
  if( s )
  {
    boost::optional<ModelObject> modelObject;
    boost::optional<Space> space;

    if( boost::optional<WorkspaceObject> _zone = 
          workspaceObject.workspace().getObjectByTypeAndName(IddObjectType::Zone,s.get()) )
    {
      modelObject = translateAndMapWorkspaceObject(_zone.get());
    }

    if( modelObject )
    {
      if( (space = modelObject->optionalCast<Space>()) )
      {
        if( boost::optional<ThermalZone> thermalZone = space->thermalZone() )
        {
          mo.setControlZone(thermalZone.get());
        }
      }
    }
  }

  s = workspaceObject.getString(SetpointManager_SingleZone_ReheatFields::SetpointNodeorNodeListName);
  if( s )
  {
    if( boost::optional<Node> node = m_model.getModelObjectByName<Node>(s.get()) )
    {
      mo.addToNode(node.get());
    }
  }

  if( mo.setpointNode() )
  {
    return mo;
  }
  else
  {
    return boost::none;
  }
}
OptionalModelObject ReverseTranslator::translateFanConstantVolume( const WorkspaceObject & workspaceObject )
{
OptionalModelObject result,temp;
  OptionalSchedule schedule;

  OptionalWorkspaceObject owo = workspaceObject.getTarget(Fan_ConstantVolumeFields::AvailabilityScheduleName);
  if(!owo)
  {
    LOG(Error, "Error importing object: "
             << workspaceObject.briefDescription()
             << " Can't find Schedule: ");
    return result;
  }
  temp = translateAndMapWorkspaceObject( *owo);
  if(temp)
  {
    schedule = temp->optionalCast<Schedule>();
  }

  if( !schedule )
  {
    LOG(Error, "Error importing object: "
             << workspaceObject.name().get()
             <<"Failed to convert iddObjects into model Objects. Maybe they do not exist in model yet");

    return result;
  }

  openstudio::model::FanConstantVolume fan( m_model, *schedule );
  OptionalString optS = workspaceObject.name();
  if(optS)
  {
    fan.setName(*optS);
  }
  //inlet and outlet nodes are set my the HVACAirLoop
  OptionalDouble d;
  d = workspaceObject.getDouble(openstudio::Fan_ConstantVolumeFields::FanTotalEfficiency);
  if(d)
  {
    fan.setFanEfficiency(*d);
  }
  d = workspaceObject.getDouble(openstudio::Fan_ConstantVolumeFields::PressureRise);
  if(d)
  {
    fan.setPressureRise(*d);
  }
  d = workspaceObject.getDouble(openstudio::Fan_ConstantVolumeFields::MaximumFlowRate);
  if(d)
  {
    fan.setMaximumFlowRate(*d);
  }
  d = workspaceObject.getDouble(openstudio::Fan_ConstantVolumeFields::MotorEfficiency);
  if(d)
  {
    fan.setMotorEfficiency(*d);
  }
  d = workspaceObject.getDouble(openstudio::Fan_ConstantVolumeFields::MotorInAirstreamFraction);
  if(d)
  {
    fan.setMotorInAirstreamFraction(*d);
  }

  optS=workspaceObject.getString(openstudio::Fan_ConstantVolumeFields::EndUseSubcategory);
  if(optS)
  {
    fan.setEndUseSubcategory(*optS);
  }

  result=fan;
  return result;
}
OptionalModelObject ReverseTranslator::translateScheduleDayInterval(const WorkspaceObject & workspaceObject){
  if (workspaceObject.iddObject().type() != IddObjectType::Schedule_Day_Interval){
    LOG(Error, "WorkspaceObject is not IddObjectType: Schedule:Day:Interval");
    return boost::none;
  }

  // create the schedule
  ScheduleDay scheduleDay(m_model);

  OptionalString s = workspaceObject.name();
  if (s){
    scheduleDay.setName(*s);
  }

  OptionalWorkspaceObject target = workspaceObject.getTarget(Schedule_Day_IntervalFields::ScheduleTypeLimitsName);
  if (target){
    OptionalModelObject scheduleTypeLimits = translateAndMapWorkspaceObject(*target);
    if (scheduleTypeLimits){
      scheduleDay.setPointer(OS_Schedule_DayFields::ScheduleTypeLimitsName, scheduleTypeLimits->handle());
    }
  }

  s = workspaceObject.getString(2,true);
  if (s){
    if (openstudio::istringEqual(*s,"yes")){
      scheduleDay.setInterpolatetoTimestep(true);
    }
    else if (openstudio::istringEqual(*s,"yes")){
      scheduleDay.setInterpolatetoTimestep(false);
    }
  }

  //get extensible groups
  std::vector<IdfExtensibleGroup> extensibleGroups = workspaceObject.extensibleGroups();
  //loop over extensible groups
  boost::regex timeRegex("(\\d?\\d:\\d\\d)");
  boost::smatch m;
  unsigned n = extensibleGroups.size();
  for (unsigned i = 0; i < n; ++i){
    //read in extensible groups
    boost::optional<std::string> timeString = extensibleGroups[i].getString(Schedule_Day_IntervalExtensibleFields::Time);
    boost::optional<double> valueUntilTime = extensibleGroups[i].getDouble(Schedule_Day_IntervalExtensibleFields::ValueUntilTime);
    if (timeString && valueUntilTime) {
      // Time string may be prefixed with "Until: ". Extract time in HH:MM format.
      if (boost::regex_search(*timeString,m,timeRegex)) {
        timeString = std::string(m[1].first,m[1].second);
      }
      try {
        openstudio::Time time(*timeString);
        scheduleDay.addValue(time,*valueUntilTime);
      }
      catch (std::exception& e) {
        LOG(Warn,"Could not add value (" << *timeString << ", " << *valueUntilTime
            << ") to ScheduleDay being created from " << workspaceObject.briefDescription()
            << ", because " << e.what() << ".");
      }
    }
    else {
      LOG(Warn,"Encountered extensible group with incomplete or improperly formatted data in "
          << workspaceObject.briefDescription() << ". Therefore, a corresponding value is not "
          << "being added to the ScheduleDay object under construction.");
    }
  }

  return scheduleDay;
}
OptionalModelObject ReverseTranslator::translateSizingSystem( const WorkspaceObject & workspaceObject )
{
  boost::optional<WorkspaceObject> _airLoopHVAC = workspaceObject.getTarget(Sizing_SystemFields::AirLoopName);

  boost::optional<AirLoopHVAC> airLoopHVAC;

  if( _airLoopHVAC )
  {
    boost::optional<ModelObject> mo = translateAndMapWorkspaceObject(_airLoopHVAC.get());

    if( mo )
    {
      airLoopHVAC = mo->optionalCast<AirLoopHVAC>();
    }
  }

  if( ! airLoopHVAC )
  {
    LOG(Error, "Error importing object: "
             << workspaceObject.briefDescription()
             << " Can't find associated AirLoopHVAC.");

    return boost::none;
  }

  openstudio::model::SizingSystem sizingSystem = airLoopHVAC->sizingSystem(); 

  boost::optional<std::string> s;
  boost::optional<double> value;

  // TypeofLoadtoSizeOn

  s = workspaceObject.getString(Sizing_SystemFields::TypeofLoadtoSizeOn);
  if( s )
  {
    sizingSystem.setTypeofLoadtoSizeOn(s.get());
  }

  // DesignOutdoorAirFlowRate

  s = workspaceObject.getString(Sizing_SystemFields::DesignOutdoorAirFlowRate);
  value = workspaceObject.getDouble(Sizing_SystemFields::DesignOutdoorAirFlowRate);
  if( value )
  {
    sizingSystem.setDesignOutdoorAirFlowRate(value.get());
  }
  else if( s && istringEqual(s.get(),"Autosize") )
  {
    sizingSystem.autosizeDesignOutdoorAirFlowRate();
  }

  // MinimumSystemAirFlowRatio

  value = workspaceObject.getDouble(Sizing_SystemFields::CentralHeatingMaximumSystemAirFlowRatio);
  if( value )
  {
    sizingSystem.setMinimumSystemAirFlowRatio(value.get());
  }

  // PreheatDesignTemperature

  value = workspaceObject.getDouble(Sizing_SystemFields::PreheatDesignTemperature);
  if( value )
  {
    sizingSystem.setPreheatDesignTemperature(value.get());
  }

  // PreheatDesignHumidityRatio

  value = workspaceObject.getDouble(Sizing_SystemFields::PreheatDesignHumidityRatio);
  if( value )
  {
    sizingSystem.setPreheatDesignHumidityRatio(value.get());
  }

  // PrecoolDesignTemperature

  value = workspaceObject.getDouble(Sizing_SystemFields::PrecoolDesignTemperature);
  if( value )
  {
    sizingSystem.setPrecoolDesignTemperature(value.get());
  }

  // PrecoolDesignHumidityRatio

  value = workspaceObject.getDouble(Sizing_SystemFields::PrecoolDesignHumidityRatio);
  if( value )
  {
    sizingSystem.setPrecoolDesignHumidityRatio(value.get());
  }

  // CentralCoolingDesignSupplyAirTemperature

  value = workspaceObject.getDouble(Sizing_SystemFields::CentralCoolingDesignSupplyAirTemperature);
  if( value )
  {
    sizingSystem.setCentralCoolingDesignSupplyAirTemperature(value.get());
  }

  // CentralHeatingDesignSupplyAirTemperature

  value = workspaceObject.getDouble(Sizing_SystemFields::CentralHeatingDesignSupplyAirTemperature);
  if( value )
  {
    sizingSystem.setCentralHeatingDesignSupplyAirTemperature(value.get());
  }

  // SizingOption

  s = workspaceObject.getString(Sizing_SystemFields::TypeofZoneSumtoUse);
  if( s )
  {
    sizingSystem.setSizingOption(s.get());
  }

  // AllOutdoorAirinCooling

  s = workspaceObject.getString(Sizing_SystemFields::AllOutdoorAirinCooling);
  if( s && istringEqual(s.get(),"Yes") )
  {
    sizingSystem.setAllOutdoorAirinCooling(true);
  }
  else if( s && istringEqual(s.get(),"No") )
  {
    sizingSystem.setAllOutdoorAirinCooling(false);
  }

  // AllOutdoorAirinHeating

  s = workspaceObject.getString(Sizing_SystemFields::AllOutdoorAirinHeating);
  if( s && istringEqual(s.get(),"Yes")  )
  {
    sizingSystem.setAllOutdoorAirinHeating(true);
  }
  else if( s && istringEqual(s.get(),"No") )
  {
    sizingSystem.setAllOutdoorAirinHeating(false);
  }

  // CentralCoolingDesignSupplyAirHumidityRatio

  value = workspaceObject.getDouble(Sizing_SystemFields::CentralCoolingDesignSupplyAirHumidityRatio);
  if( value )
  {
    sizingSystem.setCentralCoolingDesignSupplyAirHumidityRatio(value.get());
  }

  // CentralHeatingDesignSupplyAirHumidityRatio

  value = workspaceObject.getDouble(Sizing_SystemFields::CentralHeatingDesignSupplyAirHumidityRatio);
  if( value )
  {
    sizingSystem.setCentralHeatingDesignSupplyAirHumidityRatio(value.get());
  }

  // CoolingDesignAirFlowMethod

  s = workspaceObject.getString(Sizing_SystemFields::CoolingSupplyAirFlowRateMethod);
  if( s )
  {
    sizingSystem.setCoolingDesignAirFlowMethod(s.get());
  }

  // CoolingDesignAirFlowRate

  value = workspaceObject.getDouble(Sizing_SystemFields::CoolingSupplyAirFlowRate);
  if( value )
  {
    sizingSystem.setCoolingDesignAirFlowRate(value.get());
  }

  // HeatingDesignAirFlowMethod

  s = workspaceObject.getString(Sizing_SystemFields::HeatingSupplyAirFlowRateMethod);
  if( s )
  {
    sizingSystem.setHeatingDesignAirFlowMethod(s.get());
  }

  // HeatingDesignAirFlowRate

  value = workspaceObject.getDouble(Sizing_SystemFields::HeatingSupplyAirFlowRate);
  if( value )
  {
    sizingSystem.setHeatingDesignAirFlowRate(value.get());
  }

  // SystemOutdoorAirMethod

  s = workspaceObject.getString(Sizing_SystemFields::SystemOutdoorAirMethod);
  if( s )
  {
    sizingSystem.setSystemOutdoorAirMethod(s.get());
  }

  return sizingSystem;
}
boost::optional<model::ModelObject> ReverseTranslator::translateExteriorFuelEquipment(
    const WorkspaceObject& workspaceObject)
{
  if (workspaceObject.iddObject().type() != IddObjectType::Exterior_FuelEquipment) {
    LOG(Error,"WorkspaceObject " << workspaceObject.briefDescription()
        << " is not of IddObjectType::Exterior_FuelEquipment.");
    return boost::none;
  }

  // Create an EquipmentDefinition to hold the Design Level
  model::ExteriorFuelEquipmentDefinition definition(m_model);

  OptionalString s;
  OptionalDouble d;

  if ((s = workspaceObject.name())) {
    definition.setName(*s + " Definition");
  }

  if ((d = workspaceObject.getDouble(Exterior_FuelEquipmentFields::DesignLevel))){
    definition.setDesignLevel(*d);
  }

  model::OptionalExteriorFuelEquipment exteriorFuelEquipment;
  model::OptionalSchedule schedule;

  if (OptionalWorkspaceObject target = workspaceObject.getTarget(Exterior_FuelEquipmentFields::ScheduleName))
  {
    if (model::OptionalModelObject modelObject = translateAndMapWorkspaceObject(*target)) {
      schedule = modelObject->optionalCast<model::Schedule>();
    }
  }

  if (schedule) {
    try {
      exteriorFuelEquipment = model::ExteriorFuelEquipment(definition,*schedule);
    }
    catch (std::exception& e) {
      LOG(Warn,"Could not reverse translate " << workspaceObject.briefDescription()
          << " in full, because " << e.what() << ".");
    }
  }
  if (!exteriorFuelEquipment) {
    exteriorFuelEquipment = model::ExteriorFuelEquipment(definition);
  }

  OS_ASSERT(exteriorFuelEquipment);

  if ((s = workspaceObject.name())) {
    exteriorFuelEquipment->setName(*s);
  }

  if ((s = workspaceObject.getString(Exterior_FuelEquipmentFields::FuelUseType,false,true))) {
    exteriorFuelEquipment->setFuelType(*s);
  } else {
    LOG(Warn, "The Fuel Use Type (required) isn't set for " << workspaceObject.briefDescription() <<
              " while it is a required field with no default... Will default to Electricity")
    exteriorFuelEquipment->setFuelType("Electricity");
  }

  if ((s = workspaceObject.getString(Exterior_FuelEquipmentFields::EndUseSubcategory,false,true))) {
    exteriorFuelEquipment->setEndUseSubcategory(*s);
  }

  return *exteriorFuelEquipment;
}
OptionalModelObject ReverseTranslator::translateLights( const WorkspaceObject & workspaceObject )
{
  if( workspaceObject.iddObject().type() != IddObjectType::Lights ){
    LOG(Error, "WorkspaceObject " << workspaceObject.briefDescription()
        << " is not IddObjectType: Lights");
    return boost::none;
  }

  // create the definition
  openstudio::model::LightsDefinition definition(m_model);
  
  OptionalString s = workspaceObject.name();
  if(s){
    definition.setName(*s + " Definition");
  }

  s = workspaceObject.getString(openstudio::LightsFields::DesignLevelCalculationMethod, true);
  OS_ASSERT(s);

  OptionalDouble d;
  if (istringEqual("LightingLevel", *s)){
    d = workspaceObject.getDouble(openstudio::LightsFields::LightingLevel);
    if (d){
      definition.setLightingLevel(*d);
    }else{
      LOG(Error, "LightingLevel value not found for workspace object " << workspaceObject);
    }
  }else if(istringEqual("Watts/Area", *s)){
    d = workspaceObject.getDouble(openstudio::LightsFields::WattsperZoneFloorArea);
    if (d){
      definition.setWattsperSpaceFloorArea(*d);
    }else{
      LOG(Error, "Watts/Area value not found for workspace object " << workspaceObject);
    }
  }else if(istringEqual("Watts/Person", *s)){
    d = workspaceObject.getDouble(openstudio::LightsFields::WattsperPerson);
    if (d){
      definition.setWattsperPerson(*d);
    }else{
      LOG(Error, "Watts/Person value not found for workspace object " << workspaceObject);
    }
  }else{
    LOG(Error, "Unknown DesignLevelCalculationMethod value for workspace object" << workspaceObject);
  }

  d = workspaceObject.getDouble(openstudio::LightsFields::ReturnAirFraction);
  if (d){
    definition.setReturnAirFraction(*d);
  }

  d = workspaceObject.getDouble(openstudio::LightsFields::FractionRadiant);
  if (d){
    definition.setFractionRadiant(*d);
  }

  d = workspaceObject.getDouble(openstudio::LightsFields::FractionVisible);
  if (d){
    definition.setFractionVisible(*d);
  }

  s = workspaceObject.getString(openstudio::LightsFields::ReturnAirFractionCalculatedfromPlenumTemperature);
  if (s){
    if (istringEqual("Yes", *s)){
      definition.setReturnAirFractionCalculatedfromPlenumTemperature(true);
    }else{
      definition.setReturnAirFractionCalculatedfromPlenumTemperature(false);
    }
  }

  d = workspaceObject.getDouble(openstudio::LightsFields::ReturnAirFractionFunctionofPlenumTemperatureCoefficient1);
  if (d){
    definition.setReturnAirFractionFunctionofPlenumTemperatureCoefficient1(*d);
  }

  d = workspaceObject.getDouble(openstudio::LightsFields::ReturnAirFractionFunctionofPlenumTemperatureCoefficient2);
  if (d){
    definition.setReturnAirFractionFunctionofPlenumTemperatureCoefficient2(*d);
  }

  // create the instance
  Lights lights(definition);

  s = workspaceObject.name();
  if(s){
    lights.setName(*s);
  }

  OptionalWorkspaceObject target = workspaceObject.getTarget(openstudio::LightsFields::ZoneorZoneListName);
  if (target){
    OptionalModelObject modelObject = translateAndMapWorkspaceObject(*target);
    if (modelObject){
      if (modelObject->optionalCast<Space>()){
        lights.setSpace(modelObject->cast<Space>());
      }else if (modelObject->optionalCast<SpaceType>()){
        lights.setSpaceType(modelObject->cast<SpaceType>());
      }
    }
  }

  target = workspaceObject.getTarget(openstudio::LightsFields::ScheduleName);
  if (target){
    OptionalModelObject modelObject = translateAndMapWorkspaceObject(*target);
    if (modelObject){
      if (OptionalSchedule intermediate = modelObject->optionalCast<Schedule>()){
        Schedule schedule(*intermediate);
        lights.setSchedule(schedule);
      }
    }
  }

  d = workspaceObject.getDouble(openstudio::LightsFields::FractionReplaceable);
  if (d){
    lights.setFractionReplaceable(*d);
  }

  s = workspaceObject.getString(openstudio::LightsFields::EndUseSubcategory);
  if(s){
    lights.setEndUseSubcategory(*s);
  }
       
  return lights;
}
OptionalModelObject ReverseTranslator::translateAirTerminalSingleDuctConstantVolumeReheat( const WorkspaceObject & workspaceObject )
{
  if( workspaceObject.iddObject().type() != IddObjectType::AirTerminal_SingleDuct_ConstantVolume_Reheat )
  {
     LOG(Error, "WorkspaceObject is not IddObjectType: AirTerminal_SingleDuct_ConstantVolume_Reheat");
     return boost::none;
  }

  boost::optional<WorkspaceObject> wo = workspaceObject.getTarget(AirTerminal_SingleDuct_ConstantVolume_ReheatFields::AvailabilityScheduleName);
  boost::optional<Schedule> schedule;
  boost::optional<HVACComponent> coil;
  boost::optional<AirTerminalSingleDuctConstantVolumeReheat> airTerminal;

  if( wo )
  {
    boost::optional<ModelObject> mo = translateAndMapWorkspaceObject(wo.get());
    if( mo )
    {
      if( ! (schedule = mo->optionalCast<Schedule>()) )
      {
        LOG(Error, workspaceObject.briefDescription() << " does not have an associated availability schedule");

        return boost::none;
      }
    }
  }

  wo = workspaceObject.getTarget(AirTerminal_SingleDuct_ConstantVolume_ReheatFields::ReheatCoilName);
  if( wo )
  {
    boost::optional<ModelObject> mo = translateAndMapWorkspaceObject(wo.get());
    if( mo )
    {
      if( ! coil )
      {
        //TODO: Maybe try to cast this to different types depending on ReheatCoilType
        coil = mo->optionalCast<CoilHeatingElectric>();
      }
    }
  }

  if( schedule && coil )
  {
    airTerminal = AirTerminalSingleDuctConstantVolumeReheat( m_model,schedule.get(),coil.get() );
  }

  if( airTerminal )
  {
    boost::optional<double> value;
    boost::optional<std::string> s = workspaceObject.getString(AirTerminal_SingleDuct_ConstantVolume_ReheatFields::Name);

    if( s )
    {
      airTerminal->setName(s.get());
    }

    // MaximumAirFlowRate
    value = workspaceObject.getDouble(AirTerminal_SingleDuct_ConstantVolume_ReheatFields::MaximumAirFlowRate);
    if( value )
    {
      airTerminal->setMaximumAirFlowRate(value.get());
    }
    else
    {
      s = workspaceObject.getString(AirTerminal_SingleDuct_ConstantVolume_ReheatFields::MaximumAirFlowRate);
      if( s && istringEqual(s.get(),"Autosize") )
      {
        airTerminal->autosizeMaximumAirFlowRate();
      }
      else if( s && istringEqual(s.get(),"Autocalculate") )
      {
        airTerminal->autosizeMaximumAirFlowRate();
      }
    }
  
    // MaximumHotWaterorSteamFlowRate
    value = workspaceObject.getDouble(AirTerminal_SingleDuct_ConstantVolume_ReheatFields::MaximumHotWaterorSteamFlowRate);
    if( value )
    {
      airTerminal->setMaximumHotWaterorSteamFlowRate(value.get());
    }
    else
    {
      s = workspaceObject.getString(AirTerminal_SingleDuct_ConstantVolume_ReheatFields::MaximumHotWaterorSteamFlowRate);
      if( s && istringEqual(s.get(),"Autosize") )
      {
        airTerminal->autosizeMaximumHotWaterorSteamFlowRate();
      }
      else if( s && istringEqual(s.get(),"Autocalculate") )
      {
        airTerminal->autosizeMaximumHotWaterorSteamFlowRate();
      }
    }

    // MinimumHotWaterorSteamFlowRate
    value = workspaceObject.getDouble(AirTerminal_SingleDuct_ConstantVolume_ReheatFields::MinimumHotWaterorSteamFlowRate);
    if( value )
    {
      airTerminal->setMinimumHotWaterorSteamFlowRate(value.get());
    }

    // ConvergenceTolerance
    value = workspaceObject.getDouble(AirTerminal_SingleDuct_ConstantVolume_ReheatFields::ConvergenceTolerance);
    if( value )
    {
      airTerminal->setConvergenceTolerance(value.get());
    }

    // MaximumReheatAirTemperature
    value = workspaceObject.getDouble(AirTerminal_SingleDuct_ConstantVolume_ReheatFields::MaximumReheatAirTemperature);
    if( value )
    {
      airTerminal->setMaximumReheatAirTemperature(value.get());
    }

    return airTerminal.get();
  }
  else
  {
    LOG(Error, "Unknown error translating " << workspaceObject.briefDescription());

    return boost::none;
  }
}
OptionalModelObject ReverseTranslator::translateRefrigerationCompressor( const WorkspaceObject & workspaceObject )
{
  if( workspaceObject.iddObject().type() != IddObjectType::Refrigeration_Compressor )
  {
     LOG(Error, "WorkspaceObject is not IddObjectType: Refrigeration_Compressor");
     return boost::none;
  }

  boost::optional<RefrigerationCompressor> refrigerationCompressor = RefrigerationCompressor( m_model );
  boost::optional<WorkspaceObject> wo;

  if( refrigerationCompressor )
  {
    boost::optional<double> value;
    boost::optional<std::string> s = workspaceObject.getString(Refrigeration_CompressorFields::Name);

// Name
    if( s )
    {
      refrigerationCompressor->setName(s.get());
    }

// RefrigerationCompressorPowerCurveName
    if( (wo = workspaceObject.getTarget(Refrigeration_CompressorFields::RefrigerationCompressorPowerCurveName)) )
    {
      if( boost::optional<ModelObject> mo = translateAndMapWorkspaceObject(wo.get()) )
      {
        if( boost::optional<CurveBicubic> curve = mo->optionalCast<CurveBicubic>() )
        {
          refrigerationCompressor->setRefrigerationCompressorPowerCurve(curve.get());
        }
      }
    }
// RefrigerationCompressorCapacityCurveName
    if( (wo = workspaceObject.getTarget(Refrigeration_CompressorFields::RefrigerationCompressorCapacityCurveName)) )
    {
      if( boost::optional<ModelObject> mo = translateAndMapWorkspaceObject(wo.get()) )
      {
        if( boost::optional<CurveBicubic> curve = mo->optionalCast<CurveBicubic>() )
        {
          refrigerationCompressor->setRefrigerationCompressorCapacityCurve(curve.get());
        }
      }
    }
// RatedSuperheat
    value = workspaceObject.getDouble(Refrigeration_CompressorFields::RatedSuperheat);
    if( value )
    {
      refrigerationCompressor->setRatedSuperheat(value.get());
    }
// RatedReturnGasTemperature
    value = workspaceObject.getDouble(Refrigeration_CompressorFields::RatedReturnGasTemperature);
    if( value )
    {
      refrigerationCompressor->setRatedReturnGasTemperature(value.get());
    }
// RatedLiquidTemperature
    value = workspaceObject.getDouble(Refrigeration_CompressorFields::RatedLiquidTemperature);
    if( value )
    {
      refrigerationCompressor->setRatedLiquidTemperature(value.get());
    }
// RatedSubcooling
    value = workspaceObject.getDouble(Refrigeration_CompressorFields::RatedSubcooling);
    if( value )
    {
      refrigerationCompressor->setRatedSubcooling(value.get());
    }
// EndUseSubcategory
    s = workspaceObject.getString(Refrigeration_CompressorFields::EndUseSubcategory);
    if( s )
    {
      refrigerationCompressor->setEndUseSubcategory(s.get());
    }
// ModeofOperation
// TranscriticalCompressorPowerCurveName
    if( (wo = workspaceObject.getTarget(Refrigeration_CompressorFields::TranscriticalCompressorPowerCurveName)) )
    {
      if( boost::optional<ModelObject> mo = translateAndMapWorkspaceObject(wo.get()) )
      {
        if( boost::optional<CurveBicubic> curve = mo->optionalCast<CurveBicubic>() )
        {
          refrigerationCompressor->setTranscriticalCompressorPowerCurve(curve.get());
        }
      }
    }
// TranscriticalCompressorCapacityCurveName
    if( (wo = workspaceObject.getTarget(Refrigeration_CompressorFields::TranscriticalCompressorCapacityCurveName)) )
    {
      if( boost::optional<ModelObject> mo = translateAndMapWorkspaceObject(wo.get()) )
      {
        if( boost::optional<CurveBicubic> curve = mo->optionalCast<CurveBicubic>() )
        {
          refrigerationCompressor->setTranscriticalCompressorCapacityCurve(curve.get());
        }
      }
    }

    return refrigerationCompressor.get();
  }
  else
  {
    LOG(Error, "Unknown error translating " << workspaceObject.briefDescription());

    return boost::none;
  }
}
OptionalModelObject ReverseTranslator::translateSetpointManagerScheduled( const WorkspaceObject & workspaceObject )
{
  if( workspaceObject.iddObject().type() != IddObjectType::SetpointManager_Scheduled )
  {
     LOG(Error, "WorkspaceObject is not IddObjectType: SetpointManager_Scheduled");
     return boost::none;
  }

  boost::optional<WorkspaceObject> wo = workspaceObject.getTarget(SetpointManager_ScheduledFields::ScheduleName);
  boost::optional<Schedule> schedule;

  if( wo )
  {
    boost::optional<ModelObject> mo = translateAndMapWorkspaceObject(wo.get());
    if( mo )
    {
      if( ! (schedule = mo->optionalCast<Schedule>()) )
      {
        LOG(Error, workspaceObject.briefDescription() << " does not have an associated schedule");

        return boost::none;
      }
    }
  }

  bool nodeFound = false;

  if( boost::optional<std::string> setpointNodeName = workspaceObject.getString(SetpointManager_ScheduledFields::SetpointNodeorNodeListName) )
  {
    boost::optional<Node> setpointNode = m_model.getModelObjectByName<Node>(setpointNodeName.get());

    if( setpointNode ) { nodeFound = true; }
  }

  if( ! nodeFound )
  {
    LOG(Error, workspaceObject.briefDescription() << " is not attached to a node in the model");

    return boost::none;
  }

  if( schedule )
  {
    SetpointManagerScheduled mo(m_model,schedule.get());

    // Name
    boost::optional<std::string> s = workspaceObject.getString(SetpointManager_ScheduledFields::Name);
    if( s )
    {
      mo.setName(s.get());
    }

    // Setpoint Node
    s = workspaceObject.getString(SetpointManager_ScheduledFields::SetpointNodeorNodeListName);
    if( s )
    {
      boost::optional<Node> node = m_model.getModelObjectByName<Node>(s.get());
    
      if( node )
      {
        mo.addToNode(node.get());
      }
    }

    // Control Variable
    s = workspaceObject.getString(SetpointManager_ScheduledFields::ControlVariable);
    if( s )
    {
      mo.setControlVariable(s.get());
    }

    if( mo.setpointNode() )
    {
      return mo;
    }
    else
    {
      return boost::none;
    }
  }
  else
  {
    return boost::none;
  }
}
OptionalModelObject ReverseTranslator::translateSizingZone( const WorkspaceObject & workspaceObject )
{
    boost::optional<WorkspaceObject> target = workspaceObject.getTarget(Sizing_ZoneFields::ZoneorZoneListName);

    std::vector<ThermalZone> thermalZones;

    if( target ) {

        // just one thermal zone
        boost::optional<ModelObject> mo;
        if (target->iddObject().type() == IddObjectType::Zone) {
            mo = translateAndMapWorkspaceObject(target.get());
            if( mo ) {
                if( boost::optional<Space> space = mo->optionalCast<Space>() ) {
                    boost::optional<ThermalZone> thermalZone = space->thermalZone();
                    if (thermalZone) {
                        thermalZones.push_back(*thermalZone);
                    }
                }
            }
        } else if (target->iddObject().type() == IddObjectType::ZoneList) {

            // get all thermal zones in zone list
            for (const IdfExtensibleGroup& idfGroup : target->extensibleGroups()) {
                WorkspaceExtensibleGroup workspaceGroup = idfGroup.cast<WorkspaceExtensibleGroup>();
                OptionalWorkspaceObject owo = workspaceGroup.getTarget(0);
                if (owo) {
                    mo = translateAndMapWorkspaceObject(owo.get());
                    if( mo ) {
                        if( boost::optional<Space> space = mo->optionalCast<Space>() ) {
                            boost::optional<ThermalZone> thermalZone = space->thermalZone();
                            if (thermalZone) {
                                thermalZones.push_back(*thermalZone);
                            }
                        }
                    }
                }
            }
        }
    }

    if(thermalZones.empty())
    {
        LOG(Error, "Error importing object: "
            << workspaceObject.briefDescription()
            << " Can't find associated ThermalZone(s).");

        return boost::none;
    }

    boost::optional<ModelObject> result;
    for (ThermalZone thermalZone : thermalZones) {

        // sizing zone is constructed in thermal zone ctor
        openstudio::model::SizingZone sizingZone = thermalZone.sizingZone();

        // return first sizing zone
        if (!result) {
            result = sizingZone;
        }

        boost::optional<std::string> s;
        boost::optional<double> value;

        // ZoneCoolingDesignSupplyAirTemperature

        value = workspaceObject.getDouble(Sizing_ZoneFields::ZoneCoolingDesignSupplyAirTemperature);
        if( value )
        {
            sizingZone.setZoneCoolingDesignSupplyAirTemperature(value.get());
        }

        // ZoneHeatingDesignSupplyAirTemperature

        value = workspaceObject.getDouble(Sizing_ZoneFields::ZoneHeatingDesignSupplyAirTemperature);
        if( value )
        {
            sizingZone.setZoneHeatingDesignSupplyAirTemperature(value.get());
        }

        // ZoneCoolingDesignSupplyAirHumidityRatio

        value = workspaceObject.getDouble(Sizing_ZoneFields::ZoneHeatingDesignSupplyAirHumidityRatio);
        if( value )
        {
            sizingZone.setZoneHeatingDesignSupplyAirHumidityRatio(value.get());
        }

        // ZoneHeatingDesignSupplyAirHumidityRatio

        value = workspaceObject.getDouble(Sizing_ZoneFields::ZoneHeatingDesignSupplyAirHumidityRatio);
        if( value )
        {
            sizingZone.setZoneHeatingDesignSupplyAirHumidityRatio(value.get());
        }

        // DesignSpecificationOutdoorAirObjectName

        target = workspaceObject.getTarget(Sizing_ZoneFields::DesignSpecificationOutdoorAirObjectName);
        if (target) {
            OptionalModelObject mo = translateDesignSpecificationOutdoorAir(*target);
            if (mo) {
                if (mo->optionalCast<DesignSpecificationOutdoorAir>()) {
                    std::vector<Space> spaces = thermalZone.spaces();
                    OS_ASSERT(spaces.size() == 1);
                    spaces[0].setDesignSpecificationOutdoorAir(mo->cast<DesignSpecificationOutdoorAir>());
                }
            }
        }

        // ZoneHeatingSizingFactor

        value = workspaceObject.getDouble(Sizing_ZoneFields::ZoneHeatingSizingFactor);
        if( value )
        {
            sizingZone.setZoneHeatingSizingFactor(value.get());
        }

        // ZoneCoolingSizingFactor

        value = workspaceObject.getDouble(Sizing_ZoneFields::ZoneCoolingSizingFactor);
        if( value )
        {
            sizingZone.setZoneCoolingSizingFactor(value.get());
        }

        // CoolingDesignAirFlowMethod

        s = workspaceObject.getString(Sizing_ZoneFields::CoolingDesignAirFlowMethod);
        if( s )
        {
            sizingZone.setCoolingDesignAirFlowMethod(s.get());
        }

        // CoolingDesignAirFlowRate

        value = workspaceObject.getDouble(Sizing_ZoneFields::CoolingDesignAirFlowRate);
        if( value )
        {
            sizingZone.setCoolingDesignAirFlowRate(value.get());
        }

        // CoolingMinimumAirFlowperZoneFloorArea

        value = workspaceObject.getDouble(Sizing_ZoneFields::CoolingMinimumAirFlowperZoneFloorArea);
        if( value )
        {
            sizingZone.setCoolingMinimumAirFlowperZoneFloorArea(value.get());
        }

        // CoolingMinimumAirFlow

        value = workspaceObject.getDouble(Sizing_ZoneFields::CoolingMinimumAirFlow);
        if( value )
        {
            sizingZone.setCoolingMinimumAirFlow(value.get());
        }

        // CoolingMinimumAirFlowFraction

        value = workspaceObject.getDouble(Sizing_ZoneFields::CoolingMinimumAirFlowFraction);
        if( value )
        {
            sizingZone.setCoolingMinimumAirFlowFraction(value.get());
        }

        // HeatingDesignAirFlowMethod

        s = workspaceObject.getString(Sizing_ZoneFields::HeatingDesignAirFlowMethod);
        if( s )
        {
            sizingZone.setHeatingDesignAirFlowMethod(s.get());
        }

        // HeatingDesignAirFlowRate

        value = workspaceObject.getDouble(Sizing_ZoneFields::HeatingDesignAirFlowRate);
        if( value )
        {
            sizingZone.setHeatingDesignAirFlowRate(value.get());
        }

        // HeatingMaximumAirFlowperZoneFloorArea

        value = workspaceObject.getDouble(Sizing_ZoneFields::HeatingMaximumAirFlowperZoneFloorArea);
        if( value )
        {
            sizingZone.setHeatingMaximumAirFlowperZoneFloorArea(value.get());
        }

        // HeatingMaximumAirFlow

        value = workspaceObject.getDouble(Sizing_ZoneFields::HeatingMaximumAirFlow);
        if( value )
        {
            sizingZone.setHeatingMaximumAirFlow(value.get());
        }

        // HeatingMaximumAirFlowFraction

        value = workspaceObject.getDouble(Sizing_ZoneFields::HeatingMaximumAirFlowFraction);
        if( value )
        {
            sizingZone.setHeatingMaximumAirFlowFraction(value.get());
        }

        //DesignSpecification_ZoneAirDistribution

        boost::optional<WorkspaceObject> _designSpecification
            = workspaceObject.getTarget(Sizing_ZoneFields::DesignSpecificationZoneAirDistributionObjectName);

        if( _designSpecification )
        {
            // ZoneAirDistributionEffectivenessinCoolingMode

            value = _designSpecification->getDouble(
                        DesignSpecification_ZoneAirDistributionFields::ZoneAirDistributionEffectivenessinCoolingMode);
            if( value )
            {
                sizingZone.setDesignZoneAirDistributionEffectivenessinCoolingMode(value.get());
            }

            // ZoneAirDistributionEffectivenessinHeatingMode

            value = _designSpecification->getDouble(
                        DesignSpecification_ZoneAirDistributionFields::ZoneAirDistributionEffectivenessinHeatingMode);
            if( value )
            {
                sizingZone.setDesignZoneAirDistributionEffectivenessinHeatingMode(value.get());
            }
        }

    }

    return result;
}
OptionalModelObject ReverseTranslator::translateAirTerminalSingleDuctVAVReheat( const WorkspaceObject & workspaceObject )
{
  if( workspaceObject.iddObject().type() != IddObjectType::AirTerminal_SingleDuct_VAV_Reheat )
  {
     LOG(Error, "WorkspaceObject is not IddObjectType: AirTerminal_SingleDuct_VAV_Reheat");
     return boost::none;
  }

  boost::optional<WorkspaceObject> wo = workspaceObject.getTarget(AirTerminal_SingleDuct_VAV_ReheatFields::AvailabilityScheduleName);
  boost::optional<Schedule> schedule;
  boost::optional<HVACComponent> coil;
  boost::optional<AirTerminalSingleDuctVAVReheat> airTerminal;

  if( wo )
  {
    boost::optional<ModelObject> mo = translateAndMapWorkspaceObject(wo.get());
    if( mo )
    {
      if( ! (schedule = mo->optionalCast<Schedule>()) )
      {
        LOG(Error, workspaceObject.briefDescription() << " does not have an associated availability schedule");

        return boost::none;
      }
    }
  }

  wo = workspaceObject.getTarget(AirTerminal_SingleDuct_VAV_ReheatFields::ReheatCoilName);
  if( wo )
  {
    boost::optional<ModelObject> mo = translateAndMapWorkspaceObject(wo.get());
    if( mo )
    {
      if( ! coil )
      {
        coil = mo->optionalCast<CoilHeatingGas>();
      }
    }
  }

  if( schedule && coil )
  {
    airTerminal = AirTerminalSingleDuctVAVReheat( m_model,schedule.get(),coil.get() );
  }

  if( airTerminal )
  {
    boost::optional<double> value;
    boost::optional<std::string> s = workspaceObject.getString(AirTerminal_SingleDuct_VAV_ReheatFields::Name);

    if( s )
    {
      airTerminal->setName(s.get());
    }

    // MaximumAirFlowRate
    value = workspaceObject.getDouble(AirTerminal_SingleDuct_VAV_ReheatFields::MaximumAirFlowRate);
    s = workspaceObject.getString(AirTerminal_SingleDuct_VAV_ReheatFields::MaximumAirFlowRate);
    if( value )
    {
      airTerminal->setMaximumAirFlowRate(value.get());
    }
    else if( s && istringEqual(s.get(),"Autosize") )
    {
      airTerminal->autosizeMaximumAirFlowRate();
    }
    else if( s && istringEqual(s.get(),"Autocalculate") )
    {
      airTerminal->autosizeMaximumAirFlowRate();
    }

    // ZoneMinimumAirFlowInputMethod
    s = workspaceObject.getString(AirTerminal_SingleDuct_VAV_ReheatFields::ZoneMinimumAirFlowInputMethod);
    if( s )
    {
      airTerminal->setZoneMinimumAirFlowMethod(s.get());
    }

    // ConstantMinimumAirFlowFraction
    value = workspaceObject.getDouble(AirTerminal_SingleDuct_VAV_ReheatFields::ConstantMinimumAirFlowFraction);
    if( value )
    {
      airTerminal->setConstantMinimumAirFlowFraction(value.get());
    }

    // FixedMinimumAirFlowRate
    value = workspaceObject.getDouble(AirTerminal_SingleDuct_VAV_ReheatFields::FixedMinimumAirFlowRate);
    if( value )
    {
      airTerminal->setFixedMinimumAirFlowRate(value.get());
    }

    boost::optional<WorkspaceObject> _schedule;

    // MinimumAirFlowFractionScheduleName
    _schedule = workspaceObject.getTarget(AirTerminal_SingleDuct_VAV_ReheatFields::MinimumAirFlowFractionScheduleName);
    if( _schedule )
    {
      boost::optional<ModelObject> mo = translateAndMapWorkspaceObject(_schedule.get());
      if( mo )
      {
        if( boost::optional<Schedule> schedule = mo->optionalCast<Schedule>() )
        {
          airTerminal->setMinimumAirFlowFractionSchedule(schedule.get());
        }
      }
    }
  
    // MaximumHotWaterorSteamFlowRate
    value = workspaceObject.getDouble(AirTerminal_SingleDuct_VAV_ReheatFields::MaximumHotWaterorSteamFlowRate);
    s = workspaceObject.getString(AirTerminal_SingleDuct_VAV_ReheatFields::MaximumHotWaterorSteamFlowRate);
    if( value )
    {
      airTerminal->setMaximumHotWaterOrSteamFlowRate(value.get());
    }
    else if( s && istringEqual(s.get(),"Autosize") )
    {
      airTerminal->autosizeMaximumHotWaterOrSteamFlowRate();
    }
    else if( s && istringEqual(s.get(),"Autocalculate") )
    {
      airTerminal->autosizeMaximumHotWaterOrSteamFlowRate();
    }

    // MinimumHotWaterorSteamFlowRate
    value = workspaceObject.getDouble(AirTerminal_SingleDuct_VAV_ReheatFields::MinimumHotWaterorSteamFlowRate);
    if( value )
    {
      airTerminal->setMinimumHotWaterOrStreamFlowRate(value.get());
    }

    // ConvergenceTolerance
    value = workspaceObject.getDouble(AirTerminal_SingleDuct_VAV_ReheatFields::ConvergenceTolerance);
    if( value )
    {
      airTerminal->setConvergenceTolerance(value.get());
    }

    // DamperHeatingAction
    s = workspaceObject.getString(AirTerminal_SingleDuct_VAV_ReheatFields::DamperHeatingAction);
    if( s )
    {
      airTerminal->setDamperHeatingAction(s.get());
    }

    // MaximumFlowPerZoneFloorAreaDuringReheat
    value = workspaceObject.getDouble(AirTerminal_SingleDuct_VAV_ReheatFields::MaximumFlowperZoneFloorAreaDuringReheat);
    s = workspaceObject.getString(AirTerminal_SingleDuct_VAV_ReheatFields::MaximumFlowperZoneFloorAreaDuringReheat);
    if( value )
    {
      airTerminal->setMaximumFlowPerZoneFloorAreaDuringReheat(value.get());
    }
    else if( s && istringEqual(s.get(),"Autosize") )
    {
      airTerminal->autosizeMaximumFlowPerZoneFloorAreaDuringReheat();
    }
    else if( s && istringEqual(s.get(),"Autocalculate") )
    {
      airTerminal->autosizeMaximumFlowPerZoneFloorAreaDuringReheat();
    }
    
    // MaximumFlowFractionDuringReheat
    value = workspaceObject.getDouble(AirTerminal_SingleDuct_VAV_ReheatFields::MaximumFlowFractionDuringReheat);
    s = workspaceObject.getString(AirTerminal_SingleDuct_VAV_ReheatFields::MaximumFlowFractionDuringReheat);
    if( value )
    {
      airTerminal->setMaximumFlowFractionDuringReheat(value.get());
    }
    else if( s && istringEqual(s.get(),"Autosize") )
    {
      airTerminal->autosizeMaximumFlowFractionDuringReheat();
    }
    else if( s && istringEqual(s.get(),"Autocalculate") )
    {
      airTerminal->autosizeMaximumFlowFractionDuringReheat();
    }

    // MaximumReheatAirTemperature
    value = workspaceObject.getDouble(AirTerminal_SingleDuct_VAV_ReheatFields::MaximumReheatAirTemperature);
    if( value )
    {
      airTerminal->setMaximumReheatAirTemperature(value.get());
    }

    return airTerminal.get();
  }
  else
  {
    LOG(Error, "Unknown error translating " << workspaceObject.briefDescription());

    return boost::none;
  }
}
OptionalModelObject ReverseTranslator::translateCoilCoolingDXSingleSpeed( const WorkspaceObject & workspaceObject )
{
OptionalModelObject result,temp;
  OptionalSchedule schedule;

  //get the Schedule
  OptionalWorkspaceObject owo = workspaceObject.getTarget(Coil_Cooling_DX_SingleSpeedFields::AvailabilityScheduleName);
  if(!owo)
  {
    LOG(Error, "Error importing object: "
             << workspaceObject.briefDescription()
             << " Can't find Schedule.");
    return result;
  }
  temp = translateAndMapWorkspaceObject(*owo);
  if(temp)
  {
    schedule=temp->optionalCast<Schedule>();
  }

  if( !schedule  )
  {
    LOG(Error,"Error importing object: "
             << workspaceObject.briefDescription()
             <<"Failed to convert iddObject (schedule) into ModelObject. Maybe it does not exist in model yet");
    return result;
  }

  //collect the curves
  owo = workspaceObject.getTarget(Coil_Cooling_DX_SingleSpeedFields::TotalCoolingCapacityFunctionofTemperatureCurveName);
  if(!owo)
  {
    LOG(Error, "Error importing object: "
             << workspaceObject.briefDescription()
             << " Can't find TotalCoolingCapacityFunctionOfTemperatureCurve.");
    return result;
  }
  if( owo->numSources() > 1 )
  {
    owo = owo->workspace().addObject(owo.get());
  }

  temp= translateAndMapWorkspaceObject( *owo );

  if(!temp)
  {
    LOG(Error, "Error importing object: "
             << workspaceObject.briefDescription()
             << " Can't convert workspace curve into a model curve. ");
    return result;
  }
  boost::optional<Curve> tccfot = temp->optionalCast<Curve>();
  if( ! tccfot )
  {
    LOG(Error, "Error importing object: "
             << workspaceObject.briefDescription()
             << " curve is wrong type. ");
    return result;
  }

  owo = workspaceObject.getTarget(Coil_Cooling_DX_SingleSpeedFields::EnergyInputRatioFunctionofTemperatureCurveName);
  if(!owo)
  {
    LOG(Error, "Error importing object: "
             << workspaceObject.briefDescription()
             << " Can't find EnergyInputRatioFunctionofTemperatureCurveName.");
    return result;
  }
  if( owo->numSources() > 1 )
  {
    owo = owo->workspace().addObject(owo.get());
  }
  temp = translateAndMapWorkspaceObject( *owo );
  if(!temp)
  {
    LOG(Error, "Error importing object: "
             << workspaceObject.briefDescription()
             << " Can't convert workspace curve into a model curve. ");
    return result;
  }
  boost::optional<Curve> eirfot = temp->optionalCast<Curve>();
  if( ! eirfot )
  {
    LOG(Error, "Error importing object: "
             << workspaceObject.briefDescription()
             << " curve is wrong type. ");
    return result;
  }


  owo = workspaceObject.getTarget(Coil_Cooling_DX_SingleSpeedFields::TotalCoolingCapacityFunctionofFlowFractionCurveName);
  if(!owo)
  {
    LOG(Error, "Error importing object: "
             << workspaceObject.briefDescription()
             << " Can't find TotalCoolingCapacityFunctionofFlowFractionCurveName.");
    return result;
  }
  if( owo->numSources() > 1 )
  {
    owo = owo->workspace().addObject(owo.get());
  }
  temp = translateAndMapWorkspaceObject( *owo );
  if(!temp)
  {
    LOG(Error, "Error importing object: "
             << workspaceObject.briefDescription()
             << " Can't convert workspace curve into a model curve. ");
    return result;
  }
  boost::optional<Curve> tccfoff = temp->optionalCast<Curve>();
  if( ! tccfoff )
  {
    LOG(Error, "Error importing object: "
             << workspaceObject.briefDescription()
             << " curve is wrong type. ");
    return result;
  }

  owo = workspaceObject.getTarget(Coil_Cooling_DX_SingleSpeedFields::EnergyInputRatioFunctionofFlowFractionCurveName);
  if(!owo)
  {
    LOG(Error, "Error importing object: "
             << workspaceObject.briefDescription()
             << " Can't find EnergyInputRatioFunctionofFlowFractionCurveName.");
    return result;
  }
  if( owo->numSources() > 1 )
  {
    owo = owo->workspace().addObject(owo.get());
  }
  temp = translateAndMapWorkspaceObject( *owo );
  if(!temp)
  {
    LOG(Error, "Error importing object: "
             << workspaceObject.briefDescription()
             << " Can't convert workspace curve into a model curve. ");
    return result;
  }
  boost::optional<Curve> eirfoff = temp->optionalCast<Curve>();
  if( ! eirfoff )
  {
    LOG(Error, "Error importing object: "
             << workspaceObject.briefDescription()
             << " curve is wrong type. ");
    return result;
  }

  owo = workspaceObject.getTarget(Coil_Cooling_DX_SingleSpeedFields::PartLoadFractionCorrelationCurveName);
  if(!owo)
  {
    LOG(Error, "Error importing object: "
             << workspaceObject.briefDescription()
             << " Can't find PartLoadFractionCorrelationCurveName.");
    return result;
  }
  if( owo->numSources() > 1 )
  {
    owo = owo->workspace().addObject(owo.get());
  }
  temp = translateAndMapWorkspaceObject( *owo );
  if(!temp)
  {
    LOG(Error, "Error importing object: "
             << workspaceObject.briefDescription()
             << " Can't convert workspace curve into a model curve. ");
    return result;
  }
  boost::optional<Curve> plfcc = temp->optionalCast<Curve>();
  if( ! plfcc )
  {
    LOG(Error, "Error importing object: "
             << workspaceObject.briefDescription()
             << " curve is wrong type. ");
    return result;
  }


  try {
    CoilCoolingDXSingleSpeed coil(m_model,
                                  *schedule,
                                  *tccfot,
                                  *tccfoff,
                                  *eirfot,
                                  *eirfoff,
                                  *plfcc);

    OptionalString optS = workspaceObject.name();
    if( optS )
    {
      coil.setName( *optS );
    }


    OptionalDouble d = workspaceObject.getDouble(Coil_Cooling_DX_SingleSpeedFields::GrossRatedTotalCoolingCapacity);
    if(d)
    {
      coil.setRatedTotalCoolingCapacity(*d);
    }

    d=workspaceObject.getDouble(Coil_Cooling_DX_SingleSpeedFields::GrossRatedSensibleHeatRatio);
    if(d)
    {
      coil.setRatedSensibleHeatRatio(*d);
    }

    d=workspaceObject.getDouble(Coil_Cooling_DX_SingleSpeedFields::GrossRatedCoolingCOP);
    if(d)
    {
      coil.setRatedCOP(*d);
    }

    d=workspaceObject.getDouble(Coil_Cooling_DX_SingleSpeedFields::RatedAirFlowRate);
    if(d)
    {
      coil.setRatedAirFlowRate(*d);
    }

    d=workspaceObject.getDouble(Coil_Cooling_DX_SingleSpeedFields::RatedEvaporatorFanPowerPerVolumeFlowRate);
    if(d)
    {
      coil.setRatedEvaporatorFanPowerPerVolumeFlowRate(*d);
    }

    d=workspaceObject.getDouble(Coil_Cooling_DX_SingleSpeedFields::NominalTimeforCondensateRemovaltoBegin);
    if(d)
    {
      coil.setNominalTimeForCondensateRemovalToBegin(*d);
    }

    d=workspaceObject.getDouble(Coil_Cooling_DX_SingleSpeedFields::RatioofInitialMoistureEvaporationRateandSteadyStateLatentCapacity);
    if(d)
    {
      coil.setRatioOfInitialMoistureEvaporationRateAndSteadyStateLatentCapacity(*d);
    }

    d=workspaceObject.getDouble(Coil_Cooling_DX_SingleSpeedFields::MaximumCyclingRate);
    if(d)
    {
      coil.setMaximumCyclingRate(*d);
    }

    d=workspaceObject.getDouble(Coil_Cooling_DX_SingleSpeedFields::LatentCapacityTimeConstant);
    if(d)
    {
      coil.setLatentCapacityTimeConstant(*d);
    }

    optS=workspaceObject.getString(Coil_Cooling_DX_SingleSpeedFields::CondenserAirInletNodeName);
    if(optS)
    {
      coil.setCondenserAirInletNodeName(*optS);
    }

    optS = workspaceObject.getString(Coil_Cooling_DX_SingleSpeedFields::CondenserType);
    if(optS)
    {
      coil.setCondenserType(*optS);
    }

    d=workspaceObject.getDouble(Coil_Cooling_DX_SingleSpeedFields::EvaporativeCondenserEffectiveness);
    if(d)
    {
      coil.setEvaporativeCondenserEffectiveness(*d);
    }

    d=workspaceObject.getDouble(Coil_Cooling_DX_SingleSpeedFields::EvaporativeCondenserAirFlowRate);
    if(d)
    {
      coil.setEvaporativeCondenserAirFlowRate(*d);
    }

    d=workspaceObject.getDouble(Coil_Cooling_DX_SingleSpeedFields::EvaporativeCondenserPumpRatedPowerConsumption);
    if(d)
    {
      coil.setEvaporativeCondenserPumpRatedPowerConsumption(*d);
    }

    d=workspaceObject.getDouble(Coil_Cooling_DX_SingleSpeedFields::CrankcaseHeaterCapacity);
    if(d)
    {
      coil.setCrankcaseHeaterCapacity(*d);
    }

    d=workspaceObject.getDouble(Coil_Cooling_DX_SingleSpeedFields::MaximumOutdoorDryBulbTemperatureforCrankcaseHeaterOperation);
    if(d)
    {
      coil.setMaximumOutdoorDryBulbTemperatureForCrankcaseHeaterOperation(*d);
    }

    result=coil;

  }
  catch (std::exception& e) {
    LOG(Error,"Could not reverse translate " << workspaceObject.briefDescription()
        << ", because " << e.what() << ".");
  }
  return result;
}
OptionalModelObject ReverseTranslator::translateEvaporativeFluidCoolerSingleSpeed( const WorkspaceObject & workspaceObject )
{
  if( workspaceObject.iddObject().type() != IddObjectType::EvaporativeFluidCooler_SingleSpeed )
  {
     LOG(Error, "WorkspaceObject is not IddObjectType: EvaporativeFluidCooler_SingleSpeed");
     return boost::none;
  }

  boost::optional<EvaporativeFluidCoolerSingleSpeed> evapCooler;

  evapCooler = EvaporativeFluidCoolerSingleSpeed( m_model );

  if( evapCooler )
  {
    boost::optional<double> value;
    boost::optional<std::string> s = workspaceObject.getString(EvaporativeFluidCooler_SingleSpeedFields::Name);

    if( s )
    {
      evapCooler->setName(s.get());
    }

    // DesignAirFlowRate
    value = workspaceObject.getDouble(EvaporativeFluidCooler_SingleSpeedFields::DesignAirFlowRate);
    s = workspaceObject.getString(EvaporativeFluidCooler_SingleSpeedFields::DesignAirFlowRate);
    if( value )
    {
      evapCooler->setDesignAirFlowRate(value.get());
    }
    else if( s && istringEqual(s.get(),"Autosize") )
    {
      evapCooler->autosizeDesignAirFlowRate();
    }
    else if( s && istringEqual(s.get(),"Autocalculate") )
    {
      evapCooler->autosizeDesignAirFlowRate();
    }

    // FanPoweratDesignAirFlowRate
    value = workspaceObject.getDouble(EvaporativeFluidCooler_SingleSpeedFields::DesignAirFlowRateFanPower);
    s = workspaceObject.getString(EvaporativeFluidCooler_SingleSpeedFields::DesignAirFlowRateFanPower);
    if( value )
    {
      evapCooler->setFanPoweratDesignAirFlowRate(value.get());
    }
    else if( s && istringEqual(s.get(),"Autosize") )
    {
      evapCooler->autosizeFanPoweratDesignAirFlowRate();
    }
    else if( s && istringEqual(s.get(),"Autocalculate") )
    {
      evapCooler->autosizeFanPoweratDesignAirFlowRate();
    }

    // DesignSprayWaterFlowRate
    value = workspaceObject.getDouble(EvaporativeFluidCooler_SingleSpeedFields::DesignSprayWaterFlowRate);
    if( value )
    {
      evapCooler->setDesignSprayWaterFlowRate(value.get());
    }

    // PerformanceInputMethod
    s = workspaceObject.getString(EvaporativeFluidCooler_SingleSpeedFields::PerformanceInputMethod);
    if( s )
    {
      evapCooler->setPerformanceInputMethod(s.get());
    }

    // StandardDesignCapacity
    value = workspaceObject.getDouble(EvaporativeFluidCooler_SingleSpeedFields::StandardDesignCapacity);
    if( value )
    {
      evapCooler->setStandardDesignCapacity(value.get());
    }

    // UfactorTimesAreaValueatDesignAirFlowRate
    value = workspaceObject.getDouble(EvaporativeFluidCooler_SingleSpeedFields::DesignAirFlowRateUfactorTimesAreaValue);
    s = workspaceObject.getString(EvaporativeFluidCooler_SingleSpeedFields::DesignAirFlowRateUfactorTimesAreaValue);
    if( value )
    {
      evapCooler->setUfactorTimesAreaValueatDesignAirFlowRate(value.get());
    }
    else if( s && istringEqual(s.get(),"Autosize") )
    {
      evapCooler->autosizeUfactorTimesAreaValueatDesignAirFlowRate();
    }
    else if( s && istringEqual(s.get(),"Autocalculate") )
    {
      evapCooler->autosizeUfactorTimesAreaValueatDesignAirFlowRate();
    }

    // DesignWaterFlowRate
    value = workspaceObject.getDouble(EvaporativeFluidCooler_SingleSpeedFields::DesignWaterFlowRate);
    s = workspaceObject.getString(EvaporativeFluidCooler_SingleSpeedFields::DesignWaterFlowRate);
    if( value )
    {
      evapCooler->setDesignWaterFlowRate(value.get());
    }
    else if( s && istringEqual(s.get(),"Autosize") )
    {
      evapCooler->autosizeDesignWaterFlowRate();
    }
    else if( s && istringEqual(s.get(),"Autocalculate") )
    {
      evapCooler->autosizeDesignWaterFlowRate();
    }

    // UserSpecifiedDesignCapacity
    value = workspaceObject.getDouble(EvaporativeFluidCooler_SingleSpeedFields::UserSpecifiedDesignCapacity);
    if( value )
    {
      evapCooler->setUserSpecifiedDesignCapacity(value.get());
    }

    // DesignEnteringWaterTemperature
    value = workspaceObject.getDouble(EvaporativeFluidCooler_SingleSpeedFields::DesignEnteringWaterTemperature);
    if( value )
    {
      evapCooler->setDesignEnteringWaterTemperature(value.get());
    }

    // DesignEnteringAirTemperature
    value = workspaceObject.getDouble(EvaporativeFluidCooler_SingleSpeedFields::DesignEnteringAirTemperature);
    if( value )
    {
      evapCooler->setDesignEnteringAirTemperature(value.get());
    }

    // DesignEnteringAirWetbulbTemperature
    value = workspaceObject.getDouble(EvaporativeFluidCooler_SingleSpeedFields::DesignEnteringAirWetbulbTemperature);
    if( value )
    {
      evapCooler->setDesignEnteringAirWetbulbTemperature(value.get());
    }

    // CapacityControl
    s = workspaceObject.getString(EvaporativeFluidCooler_SingleSpeedFields::CapacityControl);
    if( s )
    {
      evapCooler->setCapacityControl(s.get());
    }

    // SizingFactor
    value = workspaceObject.getDouble(EvaporativeFluidCooler_SingleSpeedFields::SizingFactor);
    if( value )
    {
      evapCooler->setSizingFactor(value.get());
    }

    // EvaporationLossMode
    s = workspaceObject.getString(EvaporativeFluidCooler_SingleSpeedFields::EvaporationLossMode);
    if( s )
    {
      evapCooler->setEvaporationLossMode(s.get());
    }

    // EvaporationLossFactor
    value = workspaceObject.getDouble(EvaporativeFluidCooler_SingleSpeedFields::EvaporationLossFactor);
    if( value )
    {
      evapCooler->setEvaporationLossFactor(value.get());
    }

    // DriftLossPercent
    value = workspaceObject.getDouble(EvaporativeFluidCooler_SingleSpeedFields::DriftLossPercent);
    if( value )
    {
      evapCooler->setDriftLossPercent(value.get());
    }

    // BlowdownCalculationMode
    s = workspaceObject.getString(EvaporativeFluidCooler_SingleSpeedFields::BlowdownCalculationMode);
    if( s )
    {
      evapCooler->setBlowdownCalculationMode(s.get());
    }

    // BlowdownConcentrationRatio
    value = workspaceObject.getDouble(EvaporativeFluidCooler_SingleSpeedFields::BlowdownConcentrationRatio);
    if( value )
    {
      evapCooler->setBlowdownConcentrationRatio(value.get());
    }

    boost::optional<WorkspaceObject> _schedule;

    // BlowdownMakeupWaterUsageScheduleName
    _schedule = workspaceObject.getTarget(EvaporativeFluidCooler_SingleSpeedFields::BlowdownMakeupWaterUsageScheduleName);
    if( _schedule )
    {
      boost::optional<ModelObject> mo = translateAndMapWorkspaceObject(_schedule.get());
      if( mo )
      {
        if( boost::optional<Schedule> schedule = mo->optionalCast<Schedule>() )
        {
          evapCooler->setBlowdownMakeupWaterUsageSchedule(schedule.get());
        }
      }
    }

    return evapCooler.get();
  }
  else
  {
    LOG(Error, "Unknown error translating " << workspaceObject.briefDescription());

    return boost::none;
  }
}
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;
}
OptionalModelObject ReverseTranslator::translateSetpointManagerMixedAir( const WorkspaceObject & workspaceObject )
{
  if( workspaceObject.iddObject().type() != IddObjectType::SetpointManager_MixedAir )
  {
     LOG(Error, "WorkspaceObject is not IddObjectType: SetpointManager_MixedAir");
     return boost::none;
  }

  bool nodeFound = false;

  if( boost::optional<std::string> setpointNodeName = workspaceObject.getString(SetpointManager_MixedAirFields::SetpointNodeorNodeListName) )
  {
    boost::optional<Node> setpointNode = m_model.getModelObjectByName<Node>(setpointNodeName.get());

    if( setpointNode ) { nodeFound = true; }
  }

  if( ! nodeFound )
  {
    LOG(Error, workspaceObject.briefDescription() << " is not attached to a node in the model");

    return boost::none;
  }

  SetpointManagerMixedAir mo(m_model);

  boost::optional<std::string> s = workspaceObject.getString(SetpointManager_MixedAirFields::Name);
  if( s )
  {
    mo.setName(s.get());
  }

  s = workspaceObject.getString(SetpointManager_MixedAirFields::ReferenceSetpointNodeName);
  if( s )
  {
    boost::optional<Node> node = m_model.getModelObjectByName<Node>(s.get());

    if( node )
    {
      mo.setReferenceSetpointNode(node.get());
    }
  }

  s = workspaceObject.getString(SetpointManager_MixedAirFields::FanInletNodeName);
  if( s )
  {
    boost::optional<Node> node = m_model.getModelObjectByName<Node>(s.get());

    if( node )
    {
      mo.setFanInletNode(node.get());
    }
  }

  s = workspaceObject.getString(SetpointManager_MixedAirFields::FanOutletNodeName);
  if( s )
  {
    boost::optional<Node> node = m_model.getModelObjectByName<Node>(s.get());

    if( node )
    {
      mo.setFanOutletNode(node.get());
    }
  }

  s = workspaceObject.getString(SetpointManager_MixedAirFields::SetpointNodeorNodeListName);
  if( s )
  {
    boost::optional<Node> node = m_model.getModelObjectByName<Node>(s.get());
  
    if( node )
    {
      mo.addToNode(node.get());
    }
  }

  if( mo.setpointNode() )
  {
    return mo;
  }
  else
  {
    return boost::none;
  }
}
OptionalModelObject ReverseTranslator::translateEvaporativeCoolerDirectResearchSpecial( const WorkspaceObject & workspaceObject )
{
  if( workspaceObject.iddObject().type() != IddObjectType::EvaporativeCooler_Direct_ResearchSpecial )
  {
     LOG(Error, "WorkspaceObject is not IddObjectType: EvaporativeCooler_Direct_ResearchSpecial");
     return boost::none;
  }

  boost::optional<Schedule> schedule;
  boost::optional<EvaporativeCoolerDirectResearchSpecial> mo;

  boost::optional<WorkspaceObject> wo = workspaceObject.getTarget(EvaporativeCooler_Direct_ResearchSpecialFields::AvailabilityScheduleName);
  if( wo )
  {
    boost::optional<ModelObject> mo2 = translateAndMapWorkspaceObject(wo.get());
    if( mo2 )
    {
      if( ! (schedule = mo2->optionalCast<Schedule>()) )
      {
        LOG(Error, workspaceObject.briefDescription() << " does not have an associated availability schedule");

        return boost::none;
      }
    }
  }

  if( schedule )
  {
    mo = EvaporativeCoolerDirectResearchSpecial(m_model,schedule.get());
  }

  if( mo )
  {
    boost::optional<std::string> s = workspaceObject.getString(EvaporativeCooler_Direct_ResearchSpecialFields::Name);
    if( s )
    {
      mo->setName(s.get());
    }

    boost::optional<double> value = workspaceObject.getDouble(EvaporativeCooler_Direct_ResearchSpecialFields::CoolerEffectiveness);
    if( s )
    {
      mo->setCoolerEffectiveness(value.get());
    }

    value = workspaceObject.getDouble(EvaporativeCooler_Direct_ResearchSpecialFields::RecirculatingWaterPumpPowerConsumption);
    if( value )
    {
      mo->setRecirculatingWaterPumpPowerConsumption(value.get());
    }

    value = workspaceObject.getDouble(EvaporativeCooler_Direct_ResearchSpecialFields::DriftLossFraction);
    if( value )
    {
      mo->setDriftLossFraction(value.get());
    }

    value = workspaceObject.getDouble(EvaporativeCooler_Direct_ResearchSpecialFields::BlowdownConcentrationRatio);
    if( value )
    {
      mo->setBlowdownConcentrationRatio(value.get());
    }

    return mo.get();
  }
  else
  {
    LOG(Error, "Unknown error translating " << workspaceObject.briefDescription());

    return boost::none;
  }
}
OptionalModelObject ReverseTranslator::translateCoilHeatingGas( const WorkspaceObject & workspaceObject )
{
  OptionalModelObject result,temp;

  OptionalSchedule schedule;

 //get the Schedule
  OptionalWorkspaceObject owo = workspaceObject.getTarget(Coil_Heating_GasFields::AvailabilityScheduleName);
  if(!owo)
  {
    LOG(Error, "Error importing object: "
             << workspaceObject.briefDescription()
             << " Can't find Schedule.");
    return result;
  }
  temp = translateAndMapWorkspaceObject(*owo);
  if(temp)
  {
    schedule=temp->optionalCast<Schedule>();
  }

  if( !schedule  )
  {
    LOG(Error, "Error importing object: "
             << workspaceObject.briefDescription()
             <<"Failed to convert iddObject (schedule) into ModelObject. Maybe it does not exist in model yet");
    return result;
  }

  try {

    openstudio::model::CoilHeatingGas coil( m_model,
                                            *schedule );
    OptionalString optS = workspaceObject.name();
    if(optS)
    {
      coil.setName(*optS);
    }
    OptionalDouble d;
    d = workspaceObject.getDouble(openstudio::Coil_Heating_GasFields::GasBurnerEfficiency);
    if(d)
    {
      coil.setGasBurnerEfficiency(*d);
    }
    d = workspaceObject.getDouble(openstudio::Coil_Heating_GasFields::NominalCapacity);
    if(d)
    {
      coil.setNominalCapacity(*d);
    }
    //skip inlet and outlet node names. That should be done FOR us by the AirLoop Translator.
    d = workspaceObject.getDouble(openstudio::Coil_Heating_GasFields::GasBurnerEfficiency);
    if(d)
    {
      coil.setGasBurnerEfficiency(*d);
    }

    d = workspaceObject.getDouble(openstudio::Coil_Heating_GasFields::NominalCapacity);
    if(d)
    {
      coil.setNominalCapacity(*d);
    }

    d = workspaceObject.getDouble(openstudio::Coil_Heating_GasFields::ParasiticElectricLoad);
    if(d)
    {
      coil.setParasiticElectricLoad(*d);
    }
    d = workspaceObject.getDouble(openstudio::Coil_Heating_GasFields::ParasiticGasLoad);
    if(d)
    {
      coil.setParasiticGasLoad(*d);
    }
    result = coil;
  }
  catch (std::exception& e) {
    LOG(Error,"Unable to reverse translate " << workspaceObject.briefDescription() << ", because "
        << e.what() << ".");
    return boost::none;
  }

  return result;
}
OptionalModelObject ReverseTranslator::translateAirLoopHVAC( const WorkspaceObject & workspaceObject )
{
  if( workspaceObject.iddObject().type() != IddObjectType::AirLoopHVAC )
  {
     LOG(Error, "WorkspaceObject is not IddObjectType: AirLoopHVAC");
     return boost::none;
  }

  OptionalModelObject result;
  boost::optional<double> val;
  boost::optional<std::string> optionalString;
  Workspace _workspace = workspaceObject.workspace();

  openstudio::model::AirLoopHVAC airLoopHVAC( m_model );

  boost::optional<std::string> supplyInletNodeName = workspaceObject.getString(AirLoopHVACFields::SupplySideInletNodeName);
  boost::optional<std::string> supplyOutletNodeName = workspaceObject.getString(AirLoopHVACFields::SupplySideOutletNodeNames);
  boost::optional<std::string> demandInletNodeName = workspaceObject.getString(AirLoopHVACFields::DemandSideInletNodeNames);
  boost::optional<std::string> demandOutletNodeName = workspaceObject.getString(AirLoopHVACFields::DemandSideOutletNodeName);

  Node supplyInletNode = airLoopHVAC.supplyInletNode();
  Node supplyOutletNode = airLoopHVAC.supplyOutletNode();
  Node demandInletNode = airLoopHVAC.demandInletNode();
  Node demandOutletNode = airLoopHVAC.demandOutletNode();

  if( supplyInletNodeName ) { supplyInletNode.setName(supplyInletNodeName.get()); }
  if( supplyOutletNodeName ) { supplyOutletNode.setName(supplyOutletNodeName.get()); }
  if( demandInletNodeName ) { demandInletNode.setName(demandInletNodeName.get()); }
  if( demandOutletNodeName ) { demandOutletNode.setName(demandOutletNodeName.get()); }

  optionalString = workspaceObject.getString(AirLoopHVACFields::Name);
  if( optionalString )
  {
    airLoopHVAC.setName(optionalString.get());
  }

  optionalString = workspaceObject.getString(AirLoopHVACFields::DesignSupplyAirFlowRate);
  if( optionalString && istringEqual(optionalString.get(),"AutoSize") )
  {
    airLoopHVAC.autosizeDesignSupplyAirFlowRate();
  }
  else if( (val = workspaceObject.getDouble(AirLoopHVACFields::DesignSupplyAirFlowRate)) )
  {
    airLoopHVAC.setDesignSupplyAirFlowRate(val.get());
  }

  // Go find the supply branch.
  // Currently only supporting one supply branch.
  // Dual ducts are not supported.
  OptionalWorkspaceObject _supplyBranchList;
  OptionalWorkspaceObject _supplyBranch;

  _supplyBranchList = workspaceObject.getTarget(AirLoopHVACFields::BranchListName);
  if( _supplyBranchList )
  {
    _supplyBranch = _supplyBranchList->getExtensibleGroup(0).cast<WorkspaceExtensibleGroup>().getTarget(BranchListExtensibleFields::BranchName);
    if( ! _supplyBranch )
    {
      LOG(Error, _supplyBranchList->briefDescription() << ": Missing supply branch");
    }
    else
    {
      // March through the equipment on the supply branch and convert them.
      for( unsigned i = 0; ! _supplyBranch->getExtensibleGroup(i).empty(); i++ )
      {
        WorkspaceExtensibleGroup eg = _supplyBranch->getExtensibleGroup(i).cast<WorkspaceExtensibleGroup>();
        boost::optional<std::string> componentName = eg.getString(BranchExtensibleFields::ComponentName);
        boost::optional<std::string> componentType = eg.getString(BranchExtensibleFields::ComponentObjectType);
        boost::optional<std::string> componentInletNodeName = eg.getString(BranchExtensibleFields::ComponentInletNodeName);
        boost::optional<std::string> componentOutletNodeName = eg.getString(BranchExtensibleFields::ComponentOutletNodeName);
        boost::optional<WorkspaceObject> wo;
        OptionalNode node;
        OptionalModelObject targetModelObject;

        if( componentName && (componentName.get() != "") && componentType && (componentType.get() != "") )
        {
          IddObjectType iddType(componentType.get());
          wo = _workspace.getObjectByTypeAndName(iddType,componentName.get());
        }

        if( wo )
        {
          targetModelObject = translateAndMapWorkspaceObject( wo.get() );
          if( !targetModelObject)
          {
            LOG(Error, "Error importing object: " << wo->briefDescription() );
            continue;
          }

          if( OptionalHVACComponent hvacComponent = targetModelObject->optionalCast<HVACComponent>() )
          {
            Node node = airLoopHVAC.supplyOutletNode();
            if( hvacComponent->addToNode(node) )
            {
              if( boost::optional<StraightComponent> straightComponent = hvacComponent->optionalCast<StraightComponent>() )
              {
                Node outletNode = straightComponent->outletModelObject()->cast<Node>();
                Node inletNode = straightComponent->inletModelObject()->cast<Node>();
                if( componentOutletNodeName )
                {
                  outletNode.setName(componentOutletNodeName.get());
                }
                if( componentInletNodeName )
                {
                  inletNode.setName(componentInletNodeName.get());
                }
              }
              else if( boost::optional<AirLoopHVACOutdoorAirSystem> oaSystem = hvacComponent->optionalCast<AirLoopHVACOutdoorAirSystem>() )
              {
                Node outletNode = oaSystem->mixedAirModelObject()->cast<Node>();
                Node inletNode = oaSystem->returnAirModelObject()->cast<Node>();
                if( componentOutletNodeName )
                {
                  outletNode.setName(componentOutletNodeName.get());
                }
                if( componentInletNodeName )
                {
                  inletNode.setName(componentInletNodeName.get());
                }
              }
            }
          }
        }
        else
        {
          LOG(Error, _supplyBranch->briefDescription() << ": Missing object listed at ComponentName " << i);
        }
      }
    }
  }
  else
  {
    LOG( Error, workspaceObject.briefDescription() << ": Missing supply branch list, "
              << "Supply equipment will be incomplete");
  }

  // March through the zone on the demand side and add branches for them.
  if( demandOutletNodeName )
  {
    // Find the zone mixer for this air loop
    std::vector<WorkspaceObject> _airLoopHVACZoneMixers;
    _airLoopHVACZoneMixers = workspaceObject.workspace().getObjectsByType(IddObjectType::AirLoopHVAC_ZoneMixer);

    boost::optional<WorkspaceObject> _airLoopHVACZoneMixer;
    for( const auto & elem : _airLoopHVACZoneMixers )
    {
      boost::optional<std::string> mixerOutletNodeName;
      mixerOutletNodeName = elem.getString(AirLoopHVAC_ZoneMixerFields::OutletNodeName);

      if( mixerOutletNodeName && mixerOutletNodeName.get() == demandOutletNodeName.get() )
      {
        _airLoopHVACZoneMixer = elem;
        break;
      }
    }
    if( _airLoopHVACZoneMixer )
    {
      for( int i = 2;
           _airLoopHVACZoneMixer->getString(i);
           i++ )
      {

        std::vector<WorkspaceObject> _zoneHVACEquipmentConnections;

        std::string mixerInletNodeName = _airLoopHVACZoneMixer->getString(i).get();

        _zoneHVACEquipmentConnections = _workspace.getObjectsByType(IddObjectType::ZoneHVAC_EquipmentConnections);

        for( const auto & _zoneHVACEquipmentConnection : _zoneHVACEquipmentConnections )
        {

          OptionalString returnAirNodeName = _zoneHVACEquipmentConnection.getString(ZoneHVAC_EquipmentConnectionsFields::ZoneReturnAirNodeName);
          OptionalString inletAirNodeName = _zoneHVACEquipmentConnection.getString(ZoneHVAC_EquipmentConnectionsFields::ZoneAirInletNodeorNodeListName);
          OptionalString zoneName = _zoneHVACEquipmentConnection.getString(ZoneHVAC_EquipmentConnectionsFields::ZoneName);
          OptionalString zoneEquipListName = _zoneHVACEquipmentConnection.getString(ZoneHVAC_EquipmentConnectionsFields::ZoneConditioningEquipmentListName);

          OptionalWorkspaceObject _zone;
          OptionalWorkspaceObject _zoneEquipmentList;
          OptionalWorkspaceObject _zoneEquipment;
          OptionalWorkspaceObject _airTerminal; 

          if( returnAirNodeName &&
              returnAirNodeName.get() == mixerInletNodeName &&
              zoneName &&
              zoneEquipListName )
          {
            _zone = _workspace.getObjectByTypeAndName(IddObjectType::Zone,*zoneName);

            _zoneEquipmentList = _workspace.getObjectByTypeAndName(IddObjectType::ZoneHVAC_EquipmentList,zoneEquipListName.get());

            if( ! _zone )
            {
              LOG( Error, 
                  airLoopHVAC.briefDescription()
                  << " is connected to a zone that does not exist." );

              break;
            }

            if( ! _zoneEquipmentList )
            {
              LOG( Error, 
                  _zone->briefDescription()
                  << " does not have a zone equipment list, but it is attached to a loop." );

              break;
            }

            for( int j = 1; (optionalString = _zoneEquipmentList->getString(j)); j = j + 4 )
            {
              boost::optional<std::string> zoneEquipmentName = _zoneEquipmentList->getString(j+1) ;
              // Possible Zone Equipment
              //
              // ZoneHVAC:AirDistributionUnit
              // AirTerminal:SingleDuct:Uncontrolled
              // ZoneHVAC:EnergyRecoveryVentilator
              // ZoneHVAC:FourPipeFanCoil
              // ZoneHVAC:OutdoorAirUnit
              // ZoneHVAC:PackagedTerminalAirConditioner
              // ZoneHVAC:PackagedTerminalHeatPump
              // ZoneHVAC:UnitHeater
              // ZoneHVAC:UnitVentilator
              // ZoneHVAC:VentilatedSlab
              // ZoneHVAC:WaterToAirHeatPump
              // ZoneHVAC:WindowAirConditioner
              // ZoneHVAC:Baseboard:RadiantConvective:Electric
              // ZoneHVAC:Baseboard:RadiantConvective:Water
              // ZoneHVAC:Baseboard:RadiantConvective:Steam
              // ZoneHVAC:Baseboard:Convective:Electric
              // ZoneHVAC:Baseboard:Convective:Water
              // ZoneHVAC:HighTemperatureRadiant
              // ZoneHVAC:LowTemperatureRadiant:VariableFlow
              // ZoneHVAC:LowTemperatureRadiant:ConstantFlow
              // ZoneHVAC:LowTemperatureRadiant:Electric
              // ZoneHVAC:Dehumidifier:DX
              // ZoneHVAC:IdealLoadsAirSystem
              // Fan:ZoneExhaust
              // WaterHeater:HeatPump
              //
              if( zoneEquipmentName )
              {
                if( istringEqual(optionalString.get(),"AirTerminal:SingleDuct:Uncontrolled") )
                {
                  _airTerminal = _workspace.getObjectByTypeAndName(IddObjectType::AirTerminal_SingleDuct_Uncontrolled,zoneEquipmentName.get());

                  break;
                }
                else if( istringEqual(optionalString.get(),"ZoneHVAC:AirDistributionUnit") )
                {
                  boost::optional<WorkspaceObject> _airDistributionUnit = 
                    _workspace.getObjectByTypeAndName(IddObjectType::ZoneHVAC_AirDistributionUnit,zoneEquipmentName.get());

                  if( _airDistributionUnit )
                  {
                    boost::optional<std::string> airUnitName;
                    boost::optional<std::string> airUnitType;

                    airUnitType = _airDistributionUnit->getString(ZoneHVAC_AirDistributionUnitFields::AirTerminalObjectType);
                    airUnitName = _airDistributionUnit->getString(ZoneHVAC_AirDistributionUnitFields::AirTerminalName);

                    if( airUnitName && airUnitType )
                    {
                      _airTerminal = _workspace.getObjectByTypeAndName(IddObjectType(airUnitType.get()),airUnitName.get());
                    }
                  }

                  break;
                }
              }
            }

            OptionalModelObject airTerminalModelObject;
            OptionalSpace space;
            OptionalStraightComponent straightComponent;
            OptionalThermalZone thermalZone;

            if( _airTerminal )
            {
              airTerminalModelObject = translateAndMapWorkspaceObject( _airTerminal.get() );
            }

            if( _zone )
            {
              if( OptionalModelObject mo = translateAndMapWorkspaceObject( _zone.get() ) )
              {
                space = mo->optionalCast<Space>();
              }
            }

            if( space )
            {
              thermalZone = space->thermalZone();
            }

            if( airTerminalModelObject )
            {
              straightComponent = airTerminalModelObject->optionalCast<StraightComponent>();
            }

            bool success = false;

            if( straightComponent && thermalZone )
            {
              success = airLoopHVAC.addBranchForZone(thermalZone.get(),straightComponent.get());
            }
            else if( thermalZone )
            {
              Model m;

              success = airLoopHVAC.addBranchForZone(thermalZone.get(),boost::none);
            }

            if( success )
            {
              if( inletAirNodeName ) { thermalZone->inletPortList().airLoopHVACModelObject()->cast<Node>().setName(inletAirNodeName.get()); }
              if( returnAirNodeName ) { thermalZone->returnAirModelObject()->cast<Node>().setName(returnAirNodeName.get()); }
            }
          }
        }
      }
    }
  }

  return airLoopHVAC;
}