boost::optional<IdfObject> ForwardTranslator::translateZoneHVACPackagedTerminalAirConditioner( 
    ZoneHVACPackagedTerminalAirConditioner & modelObject )
{
  boost::optional<std::string> s;
  boost::optional<double> value;

  IdfObject idfObject(IddObjectType::ZoneHVAC_PackagedTerminalAirConditioner);

  m_idfObjects.push_back(idfObject);

  // Name

  std::string baseName = modelObject.name().get();

  idfObject.setName(baseName);

  std::string mixedAirNodeName = baseName + " Mixed Air Node";

  std::string coolingCoilOutletNodeName = baseName + " Cooling Coil Outlet Node";

  std::string heatingCoilOutletNodeName = baseName + " Heating Coil Outlet Node";

  std::string reliefAirNodeName = baseName + " Relief Air Node";

  std::string oaNodeName = baseName + " OA Node";

  // AvailabilityScheduleName

  if( boost::optional<Schedule> schedule = modelObject.availabilitySchedule() )
  {
    if( boost::optional<IdfObject> _schedule = translateAndMapModelObject(schedule.get()) )
    {
      idfObject.setString(ZoneHVAC_PackagedTerminalAirConditionerFields::AvailabilityScheduleName,_schedule->name().get());
    }
  }

  // AirInletNodeName

  boost::optional<std::string> airInletNodeName;

  if( boost::optional<Node> node = modelObject.inletNode() )
  {
    if( (s = node->name()) )
    {
      airInletNodeName = s;

      idfObject.setString(ZoneHVAC_PackagedTerminalAirConditionerFields::AirInletNodeName,s.get());
    }
  }

  // AirOutletNodeName

  boost::optional<std::string> airOutletNodeName;

  if( boost::optional<Node> node = modelObject.outletNode() )
  {
    if( (s = node->name()) )
    {
      airOutletNodeName = s;

      idfObject.setString(ZoneHVAC_PackagedTerminalAirConditionerFields::AirOutletNodeName,s.get());
    }
  }

  // OutdoorAirMixerObjectType
  idfObject.setString(ZoneHVAC_PackagedTerminalAirConditionerFields::OutdoorAirMixerObjectType,
                      modelObject.outdoorAirMixerObjectType());

  // OutdoorAirMixerName
  
  std::string oaMixerName = modelObject.name().get() + " OA Mixer";  

  idfObject.setString(ZoneHVAC_PackagedTerminalAirConditionerFields::OutdoorAirMixerName,oaMixerName);

  IdfObject _outdoorAirMixer(IddObjectType::OutdoorAir_Mixer);
  _outdoorAirMixer.setName(oaMixerName);
  m_idfObjects.push_back(_outdoorAirMixer);

  _outdoorAirMixer.setString(OutdoorAir_MixerFields::MixedAirNodeName,mixedAirNodeName);

  _outdoorAirMixer.setString(OutdoorAir_MixerFields::OutdoorAirStreamNodeName,oaNodeName);

  IdfObject _oaNodeList(openstudio::IddObjectType::OutdoorAir_NodeList);
  _oaNodeList.setString(0,oaNodeName);
  m_idfObjects.push_back(_oaNodeList);

  _outdoorAirMixer.setString(OutdoorAir_MixerFields::ReliefAirStreamNodeName,reliefAirNodeName);

  if(airInletNodeName)
  {
    _outdoorAirMixer.setString(OutdoorAir_MixerFields::ReturnAirStreamNodeName,airInletNodeName.get());
  }

  // SupplyAirFlowRateDuringCoolingOperation

  if( modelObject.isSupplyAirFlowRateDuringCoolingOperationAutosized() )
  {
    idfObject.setString(ZoneHVAC_PackagedTerminalAirConditionerFields::SupplyAirFlowRateDuringCoolingOperation,"Autosize");
  }
  else if( (value = modelObject.supplyAirFlowRateDuringCoolingOperation()) )
  {
    idfObject.setDouble(ZoneHVAC_PackagedTerminalAirConditionerFields::SupplyAirFlowRateDuringCoolingOperation,value.get());
  }

  // SupplyAirFlowRateDuringHeatingOperation

  if( modelObject.isSupplyAirFlowRateDuringHeatingOperationAutosized() )
  {
    idfObject.setString(ZoneHVAC_PackagedTerminalAirConditionerFields::SupplyAirFlowRateDuringHeatingOperation,"Autosize");
  }
  else if( (value = modelObject.supplyAirFlowRateDuringHeatingOperation()) )
  {
    idfObject.setDouble(ZoneHVAC_PackagedTerminalAirConditionerFields::SupplyAirFlowRateDuringHeatingOperation,value.get());
  }

  // SupplyAirFlowRateWhenNoCoolingorHeatingisNeeded

  if( modelObject.isSupplyAirFlowRateWhenNoCoolingorHeatingisNeededAutosized() )
  {
    idfObject.setString(ZoneHVAC_PackagedTerminalAirConditionerFields::SupplyAirFlowRateWhenNoCoolingorHeatingisNeeded,"Autosize");
  } 
  else if( (value = modelObject.supplyAirFlowRateWhenNoCoolingorHeatingisNeeded()) )
  {
    idfObject.setDouble(ZoneHVAC_PackagedTerminalAirConditionerFields::SupplyAirFlowRateWhenNoCoolingorHeatingisNeeded,value.get());
  }

  // OutdoorAirFlowRateDuringCoolingOperation
  
  if( modelObject.isOutdoorAirFlowRateDuringCoolingOperationAutosized() )
  {
    idfObject.setString(ZoneHVAC_PackagedTerminalAirConditionerFields::OutdoorAirFlowRateDuringCoolingOperation,"Autosize");
  }
  else if( (value = modelObject.outdoorAirFlowRateDuringCoolingOperation()) )
  {
    idfObject.setDouble(ZoneHVAC_PackagedTerminalAirConditionerFields::OutdoorAirFlowRateDuringCoolingOperation,value.get());
  }

  // OutdoorAirFlowRateDuringHeatingOperation
  
  if( modelObject.isOutdoorAirFlowRateDuringHeatingOperationAutosized() )
  {
    idfObject.setString(ZoneHVAC_PackagedTerminalAirConditionerFields::OutdoorAirFlowRateDuringHeatingOperation,"Autosize");
  }
  else if( (value = modelObject.outdoorAirFlowRateDuringHeatingOperation()) )
  {
    idfObject.setDouble(ZoneHVAC_PackagedTerminalAirConditionerFields::OutdoorAirFlowRateDuringHeatingOperation,value.get());
  }

  // OutdoorAirFlowRateWhenNoCoolingorHeatingisNeeded
  
  if( modelObject.isOutdoorAirFlowRateWhenNoCoolingorHeatingisNeededAutosized() )
  {
    idfObject.setString(ZoneHVAC_PackagedTerminalAirConditionerFields::OutdoorAirFlowRateWhenNoCoolingorHeatingisNeeded,"Autosize");
  }
  else if( (value = modelObject.outdoorAirFlowRateWhenNoCoolingorHeatingisNeeded()) )
  {
    idfObject.setDouble(ZoneHVAC_PackagedTerminalAirConditionerFields::OutdoorAirFlowRateWhenNoCoolingorHeatingisNeeded,value.get());
  }

  // SupplyAirFanObjectType

  HVACComponent supplyAirFan = modelObject.supplyAirFan();

  if( boost::optional<IdfObject> _supplyAirFan = translateAndMapModelObject(supplyAirFan) )
  {
    idfObject.setString(ZoneHVAC_PackagedTerminalAirConditionerFields::SupplyAirFanObjectType,_supplyAirFan->iddObject().name() );

    idfObject.setString(ZoneHVAC_PackagedTerminalAirConditionerFields::SupplyAirFanName,_supplyAirFan->name().get());

    if( airOutletNodeName )
    {
      if( _supplyAirFan->iddObject().type() == IddObjectType::Fan_ConstantVolume )
      {
        _supplyAirFan->setString(Fan_ConstantVolumeFields::AirInletNodeName,heatingCoilOutletNodeName);

        _supplyAirFan->setString(Fan_ConstantVolumeFields::AirOutletNodeName,airOutletNodeName.get());
      }
    }
  }

  // HeatingCoilObjectType
  
  HVACComponent heatingCoil = modelObject.heatingCoil();

  if( boost::optional<IdfObject> _heatingCoil = translateAndMapModelObject(heatingCoil) )
  {
    idfObject.setString(ZoneHVAC_PackagedTerminalAirConditionerFields::HeatingCoilObjectType,_heatingCoil->iddObject().name() );

    idfObject.setString(ZoneHVAC_PackagedTerminalAirConditionerFields::HeatingCoilName,_heatingCoil->name().get() ); 

    if( _heatingCoil->iddObject().type() == IddObjectType::Coil_Heating_Water )
    {
      _heatingCoil->setString(Coil_Heating_WaterFields::AirInletNodeName,coolingCoilOutletNodeName);

      _heatingCoil->setString(Coil_Heating_WaterFields::AirOutletNodeName,heatingCoilOutletNodeName);
    }
    else if( _heatingCoil->iddObject().type() == IddObjectType::Coil_Heating_Gas )
    {
      _heatingCoil->setString(Coil_Heating_GasFields::AirInletNodeName,coolingCoilOutletNodeName);

      _heatingCoil->setString(Coil_Heating_GasFields::AirOutletNodeName,heatingCoilOutletNodeName);
    }
    else if( _heatingCoil->iddObject().type() == IddObjectType::Coil_Heating_Electric )
    {
      _heatingCoil->setString(Coil_Heating_ElectricFields::AirInletNodeName,coolingCoilOutletNodeName);

      _heatingCoil->setString(Coil_Heating_ElectricFields::AirOutletNodeName,heatingCoilOutletNodeName);
    }
  }

  // CoolingCoilObjectType

  HVACComponent coolingCoil = modelObject.coolingCoil();

  boost::optional<IdfObject> _coolingCoil;

  if( boost::optional<CoilCoolingDXSingleSpeed> dxCoil = coolingCoil.optionalCast<CoilCoolingDXSingleSpeed>() )
  {
    _coolingCoil = translateCoilCoolingDXSingleSpeedWithoutUnitary(dxCoil.get());

    m_map.insert(std::make_pair(coolingCoil.handle(),_coolingCoil.get()));
  }
  else
  {
    _coolingCoil = translateAndMapModelObject(coolingCoil);
  }

  if( _coolingCoil )
  {
    idfObject.setString(ZoneHVAC_PackagedTerminalAirConditionerFields::CoolingCoilObjectType,_coolingCoil->iddObject().name() );

    idfObject.setString(ZoneHVAC_PackagedTerminalAirConditionerFields::CoolingCoilName,_coolingCoil->name().get() );

    if( _coolingCoil->iddObject().type() == IddObjectType::Coil_Cooling_DX_SingleSpeed )
    {
      _coolingCoil->setString(Coil_Cooling_DX_SingleSpeedFields::AirInletNodeName,mixedAirNodeName);

      _coolingCoil->setString(Coil_Cooling_DX_SingleSpeedFields::AirOutletNodeName,coolingCoilOutletNodeName);
    }
  }

  // FanPlacement

  idfObject.setString(ZoneHVAC_PackagedTerminalAirConditionerFields::FanPlacement,modelObject.fanPlacement());

  // SupplyAirFanOperatingModeScheduleName
  
  if( boost::optional<Schedule> schedule = modelObject.supplyAirFanOperatingModeSchedule() )
  {
    if( boost::optional<IdfObject> _schedule = translateAndMapModelObject(schedule.get()) )
    {
      idfObject.setString(ZoneHVAC_PackagedTerminalAirConditionerFields::SupplyAirFanOperatingModeScheduleName,_schedule->name().get());
    }
  }

  return idfObject;
}
boost::optional<IdfObject> ForwardTranslator::translateZoneHVACFourPipeFanCoil(
    ZoneHVACFourPipeFanCoil & modelObject )
{
  boost::optional<std::string> s;
  boost::optional<double> value;

  IdfObject idfObject(IddObjectType::ZoneHVAC_FourPipeFanCoil);

  // Get model object name and define node names for future use
  // Model Name
  std::string baseName = modelObject.name().get();
  // Node Names
  std::string mixedAirNodeName = baseName + " Mixed Air Node";
  std::string fanOutletNodeName = baseName + " Fan Outlet Node";
  std::string coolingCoilOutletNodeName = baseName + " Cooling Coil Outlet Node";
  std::string reliefAirNodeName = baseName + " Relief Air Node";
  std::string oaNodeName = baseName + " OA Node";

  boost::optional<AirLoopHVAC> t_airLoopHVAC = modelObject.airLoopHVAC();

  // AirInletNodeName
  boost::optional<std::string> airInletNodeName;
  if( boost::optional<Node> node = modelObject.inletNode() )
  {
    if( (s = node->name()) )
    {
      airInletNodeName = s;
      idfObject.setString(ZoneHVAC_FourPipeFanCoilFields::AirInletNodeName,s.get() );
    }
  }
  // AirOutletNodeName
  boost::optional<std::string> airOutletNodeName;
  if( boost::optional<Node> node = modelObject.outletNode() )
  {
    if( (s = node->name()) )
    {
      airOutletNodeName = s;
      idfObject.setString(ZoneHVAC_FourPipeFanCoilFields::AirOutletNodeName,s.get() );
    }
  }

  // hook up required objects
  try {
    // AvailabilityScheduleName
    Schedule availabilitySchedule = modelObject.availabilitySchedule();
    translateAndMapModelObject(availabilitySchedule);
    idfObject.setString(ZoneHVAC_FourPipeFanCoilFields::AvailabilityScheduleName,
                        availabilitySchedule.name().get() );

    // Supply Air Fan
    HVACComponent supplyAirFan = modelObject.supplyAirFan();
    if( boost::optional<IdfObject> _supplyAirFan = translateAndMapModelObject(supplyAirFan) )
    {
      // SupplyAirFanObjectType
      idfObject.setString(ZoneHVAC_FourPipeFanCoilFields::SupplyAirFanObjectType,_supplyAirFan->iddObject().name() );

      // SupplyAirFanName
      idfObject.setString(ZoneHVAC_FourPipeFanCoilFields::SupplyAirFanName,_supplyAirFan->name().get() );
      // Supply Air Fan Inlet and Outlet Nodes
      if( airOutletNodeName && airInletNodeName )
      {
        // If there is an AirLoopHVAC then we provide no mixer
        std::string fanInletNodeName;
        if( t_airLoopHVAC ) {
          fanInletNodeName = airInletNodeName.get();
        } else {
          fanInletNodeName = mixedAirNodeName;
        }

        if( _supplyAirFan->iddObject().type() == IddObjectType::Fan_ConstantVolume )
        {
          _supplyAirFan->setString(Fan_ConstantVolumeFields::AirInletNodeName,fanInletNodeName );
          _supplyAirFan->setString(Fan_ConstantVolumeFields::AirOutletNodeName,fanOutletNodeName );
        }
        else if( _supplyAirFan->iddObject().type() == IddObjectType::Fan_OnOff )
        {
          
          _supplyAirFan->setString(Fan_OnOffFields::AirInletNodeName,fanInletNodeName );
          _supplyAirFan->setString(Fan_OnOffFields::AirOutletNodeName,fanOutletNodeName );
        }
        else if( _supplyAirFan->iddObject().type() == IddObjectType::Fan_VariableVolume )
        {
          _supplyAirFan->setString(Fan_VariableVolumeFields::AirInletNodeName,fanInletNodeName );
          _supplyAirFan->setString(Fan_VariableVolumeFields::AirOutletNodeName,fanOutletNodeName );
        }
      }
    }

    // Cooling Coil
    HVACComponent coolingCoil = modelObject.coolingCoil();
    if( boost::optional<IdfObject> _coolingCoil = translateAndMapModelObject(coolingCoil) )
    {
      // CoolingCoilObjectType
      idfObject.setString(ZoneHVAC_FourPipeFanCoilFields::CoolingCoilObjectType,_coolingCoil->iddObject().name() );
      // CoolingCoilName
      idfObject.setString(ZoneHVAC_FourPipeFanCoilFields::CoolingCoilName,_coolingCoil->name().get() );
      // Cooling Coil Inlet and Outlet Nodes
      if( _coolingCoil->iddObject().type() == IddObjectType::Coil_Cooling_Water )
      {
        _coolingCoil->setString(Coil_Cooling_WaterFields::AirInletNodeName,fanOutletNodeName );
        _coolingCoil->setString(Coil_Cooling_WaterFields::AirOutletNodeName,coolingCoilOutletNodeName );
      }
    }

    // Heating Coil
    HVACComponent heatingCoil = modelObject.heatingCoil();
    if( boost::optional<IdfObject> _heatingCoil = translateAndMapModelObject(heatingCoil) )
    {
      // HeatingCoilObjectType
      idfObject.setString(ZoneHVAC_FourPipeFanCoilFields::HeatingCoilObjectType,_heatingCoil->iddObject().name() );
      // HeatingCoilName
      idfObject.setString(ZoneHVAC_FourPipeFanCoilFields::HeatingCoilName,_heatingCoil->name().get() );
      // Heating Coil Inlet and Outlet Nodes
      if( _heatingCoil->iddObject().type() == IddObjectType::Coil_Heating_Water )
      {
        _heatingCoil->setString(Coil_Heating_WaterFields::AirInletNodeName,coolingCoilOutletNodeName );
        _heatingCoil->setString(Coil_Heating_WaterFields::AirOutletNodeName,airOutletNodeName.get() );
      }
    }
  }
  catch (std::exception& e) {
    LOG(Error,"Could not translate " << modelObject.briefDescription() << ", because "
        << e.what() << ".");
    return boost::none;
  }

  m_idfObjects.push_back(idfObject);

  // Name
  idfObject.setName(baseName);

  // CapacityControlMethod
  idfObject.setString(ZoneHVAC_FourPipeFanCoilFields::CapacityControlMethod,
                      modelObject.capacityControlMethod());

  // MaximumSupplyAirFlowRate
  if( modelObject.isMaximumSupplyAirFlowRateAutosized() )
  {
    idfObject.setString(ZoneHVAC_FourPipeFanCoilFields::MaximumSupplyAirFlowRate,"Autosize");
  }
  else if( (value = modelObject.maximumSupplyAirFlowRate()) )
  {
    idfObject.setDouble(ZoneHVAC_FourPipeFanCoilFields::MaximumSupplyAirFlowRate,value.get());
  }

  // LowSpeedSupplyAirFlowRatio
  if(! modelObject.isLowSpeedSupplyAirFlowRatioDefaulted() )
  {
    idfObject.setDouble(ZoneHVAC_FourPipeFanCoilFields::LowSpeedSupplyAirFlowRatio,modelObject.lowSpeedSupplyAirFlowRatio() );
  }

  // MediumSpeedSupplyAirFlowRatio
  if(! (modelObject.isMediumSpeedSupplyAirFlowRatioDefaulted()) )
  {
    idfObject.setDouble(ZoneHVAC_FourPipeFanCoilFields::MediumSpeedSupplyAirFlowRatio,modelObject.mediumSpeedSupplyAirFlowRatio() );
  }

  // MaximumOutdoorAirFlowRate
  if( modelObject.isMaximumOutdoorAirFlowRateAutosized() )
  {
    idfObject.setString(ZoneHVAC_FourPipeFanCoilFields::MaximumOutdoorAirFlowRate,"Autosize");
  }
  else if( (value = modelObject.maximumOutdoorAirFlowRate()) )
  {
    idfObject.setDouble(ZoneHVAC_FourPipeFanCoilFields::MaximumOutdoorAirFlowRate,value.get());
  }

  // OutdoorAirScheduleName
  if( boost::optional<Schedule> schedule = modelObject.outdoorAirSchedule() )
  {
    if( boost::optional<IdfObject> _schedule = translateAndMapModelObject(schedule.get()) )
    {
      idfObject.setString(ZoneHVAC_FourPipeFanCoilFields::OutdoorAirScheduleName,_schedule->name().get());
    }
  }

  if( ! t_airLoopHVAC ) {
    // OutdoorAirMixerObjectType
    idfObject.setString(ZoneHVAC_FourPipeFanCoilFields::OutdoorAirMixerObjectType,
                        modelObject.outdoorAirMixerObjectType());

    // OutdoorAirMixerName
    std::string oaMixerName = modelObject.name().get() + " OA Mixer";
    idfObject.setString(ZoneHVAC_FourPipeFanCoilFields::OutdoorAirMixerName,oaMixerName);

    // Create Outdoor Air Mixer
    IdfObject _outdoorAirMixer(IddObjectType::OutdoorAir_Mixer);
    _outdoorAirMixer.setName(oaMixerName);
    m_idfObjects.push_back(_outdoorAirMixer);

    _outdoorAirMixer.setString(OutdoorAir_MixerFields::MixedAirNodeName,mixedAirNodeName);
    _outdoorAirMixer.setString(OutdoorAir_MixerFields::OutdoorAirStreamNodeName,oaNodeName);
    _outdoorAirMixer.setString(OutdoorAir_MixerFields::ReliefAirStreamNodeName,reliefAirNodeName);
    if(airInletNodeName)
    {
      _outdoorAirMixer.setString(OutdoorAir_MixerFields::ReturnAirStreamNodeName,airInletNodeName.get());
    }

    // Create Outdoor Air Node List
    IdfObject _oaNodeList(openstudio::IddObjectType::OutdoorAir_NodeList);
    _oaNodeList.setString(0,oaNodeName);
    m_idfObjects.push_back(_oaNodeList);
  }

  // MaximumColdWaterFlowRate
  if( modelObject.isMaximumColdWaterFlowRateAutosized() )
  {
    idfObject.setString(ZoneHVAC_FourPipeFanCoilFields::MaximumColdWaterFlowRate,"Autosize");
  }
  else if( (value = modelObject.maximumColdWaterFlowRate()) )
  {
    idfObject.setDouble(ZoneHVAC_FourPipeFanCoilFields::MaximumColdWaterFlowRate,value.get());
  }

  // MinimumColdWaterFlowRate
  if(! modelObject.isMinimumColdWaterFlowRateDefaulted() )
  {
    idfObject.setDouble(ZoneHVAC_FourPipeFanCoilFields::MinimumColdWaterFlowRate,modelObject.minimumColdWaterFlowRate() );
  }

  // CoolingConvergenceTolerance
  if(! modelObject.isCoolingConvergenceToleranceDefaulted() )
  {
    idfObject.setDouble(ZoneHVAC_FourPipeFanCoilFields::CoolingConvergenceTolerance,modelObject.coolingConvergenceTolerance() );
  }

  // MaximumHotWaterFlowRate
  if( modelObject.isMaximumHotWaterFlowRateAutosized() )
  {
    idfObject.setString(ZoneHVAC_FourPipeFanCoilFields::MaximumHotWaterFlowRate,"Autosize");
  }
  else if( (value = modelObject.maximumHotWaterFlowRate()) )
  {
    idfObject.setDouble(ZoneHVAC_FourPipeFanCoilFields::MaximumHotWaterFlowRate,value.get());
  }

  // MinimumHotWaterFlowRate
  if(! modelObject.isMinimumHotWaterFlowRateDefaulted() )
  {
    idfObject.setDouble(ZoneHVAC_FourPipeFanCoilFields::MinimumHotWaterFlowRate,modelObject.minimumHotWaterFlowRate() );
  }

  // HeatingConvergenceTolerance
  if(! modelObject.isHeatingConvergenceToleranceDefaulted() )
  {
    idfObject.setDouble(ZoneHVAC_FourPipeFanCoilFields::HeatingConvergenceTolerance,modelObject.heatingConvergenceTolerance() );
  }

  return idfObject;
}
boost::optional<IdfObject> ForwardTranslator::translateZoneHVACTerminalUnitVariableRefrigerantFlow( ZoneHVACTerminalUnitVariableRefrigerantFlow & modelObject )
{
  boost::optional<std::string> s;
  boost::optional<double> value;

  IdfObject idfObject(IddObjectType::ZoneHVAC_TerminalUnit_VariableRefrigerantFlow);

  m_idfObjects.push_back(idfObject);

  // Name

  s = modelObject.name();
  if( s )
  {
    idfObject.setName(*s);
  }

  // TerminalUnitAvailabilityschedule

  if( boost::optional<model::Schedule> schedule = modelObject.terminalUnitAvailabilityschedule() )
  {
    if( boost::optional<IdfObject> _schedule = translateAndMapModelObject(schedule.get()) )
    {
      idfObject.setString(ZoneHVAC_TerminalUnit_VariableRefrigerantFlowFields::TerminalUnitAvailabilitySchedule,_schedule->name().get());
    }
  }

  // SupplyAirFlowRateDuringCoolingOperation
  
  if( modelObject.isSupplyAirFlowRateDuringCoolingOperationAutosized() )
  {
    idfObject.setString(ZoneHVAC_TerminalUnit_VariableRefrigerantFlowFields::CoolingSupplyAirFlowRate,"Autosize");
  }
  else if( (value = modelObject.supplyAirFlowRateDuringCoolingOperation()) )
  {
    idfObject.setDouble(ZoneHVAC_TerminalUnit_VariableRefrigerantFlowFields::CoolingSupplyAirFlowRate,value.get()); 
  }
  
  // SupplyAirFlowRateWhenNoCoolingisNeeded

  if( modelObject.isSupplyAirFlowRateWhenNoCoolingisNeededAutosized() )
  {
    idfObject.setString(ZoneHVAC_TerminalUnit_VariableRefrigerantFlowFields::NoCoolingSupplyAirFlowRate,"Autosize");
  }
  else if( (value = modelObject.supplyAirFlowRateWhenNoCoolingisNeeded()) )
  {
    idfObject.setDouble(ZoneHVAC_TerminalUnit_VariableRefrigerantFlowFields::NoCoolingSupplyAirFlowRate,value.get());
  }

  // SupplyAirFlowRateDuringHeatingOperation
  
  if( modelObject.isSupplyAirFlowRateDuringHeatingOperationAutosized() )
  {
    idfObject.setString(ZoneHVAC_TerminalUnit_VariableRefrigerantFlowFields::HeatingSupplyAirFlowRate,"Autosize");
  }
  else if( (value = modelObject.supplyAirFlowRateDuringHeatingOperation()) )
  {
    idfObject.setDouble(ZoneHVAC_TerminalUnit_VariableRefrigerantFlowFields::HeatingSupplyAirFlowRate,value.get()); 
  }
  
  // SupplyAirFlowRateWhenNoHeatingisNeeded

  if( modelObject.isSupplyAirFlowRateWhenNoHeatingisNeededAutosized() )
  {
    idfObject.setString(ZoneHVAC_TerminalUnit_VariableRefrigerantFlowFields::NoHeatingSupplyAirFlowRate,"Autosize");
  }
  else if( (value = modelObject.supplyAirFlowRateWhenNoHeatingisNeeded()) )
  {
    idfObject.setDouble(ZoneHVAC_TerminalUnit_VariableRefrigerantFlowFields::NoHeatingSupplyAirFlowRate,value.get());
  }

  // OutdoorAirFlowRateDuringCoolingOperation

  if( modelObject.isOutdoorAirFlowRateDuringCoolingOperationAutosized() )
  {
    idfObject.setString(ZoneHVAC_TerminalUnit_VariableRefrigerantFlowFields::CoolingOutdoorAirFlowRate,"Autosize");
  }
  else if( (value = modelObject.outdoorAirFlowRateDuringCoolingOperation()) )
  {
    idfObject.setDouble(ZoneHVAC_TerminalUnit_VariableRefrigerantFlowFields::CoolingOutdoorAirFlowRate,value.get());
  }

  // OutdoorAirFlowRateDuringHeatingOperation

  if( modelObject.isOutdoorAirFlowRateDuringHeatingOperationAutosized() )
  {
    idfObject.setString(ZoneHVAC_TerminalUnit_VariableRefrigerantFlowFields::HeatingOutdoorAirFlowRate,"Autosize");
  }
  else if( (value = modelObject.outdoorAirFlowRateDuringHeatingOperation()) )
  {
    idfObject.setDouble(ZoneHVAC_TerminalUnit_VariableRefrigerantFlowFields::HeatingOutdoorAirFlowRate,value.get());
  }

  // OutdoorAirFlowRateWhenNoCoolingorHeatingisNeeded

  if( modelObject.isOutdoorAirFlowRateWhenNoCoolingorHeatingisNeededAutosized() )
  {
    idfObject.setString(ZoneHVAC_TerminalUnit_VariableRefrigerantFlowFields::NoLoadOutdoorAirFlowRate,"Autosize");
  }
  else if( (value = modelObject.outdoorAirFlowRateWhenNoCoolingorHeatingisNeeded()) )
  {
    idfObject.setDouble(ZoneHVAC_TerminalUnit_VariableRefrigerantFlowFields::NoLoadOutdoorAirFlowRate,value.get());
  }

  // SupplyAirFanOperatingModeScheduleName

  if( boost::optional<model::Schedule> schedule = modelObject.supplyAirFanOperatingModeSchedule() )
  {
    if( boost::optional<IdfObject> _schedule = translateAndMapModelObject(schedule.get()) )
    {
      idfObject.setString(ZoneHVAC_TerminalUnit_VariableRefrigerantFlowFields::SupplyAirFanOperatingModeScheduleName,_schedule->name().get());
    }
  }

  // SupplyAirFanplacement

  idfObject.setString(ZoneHVAC_TerminalUnit_VariableRefrigerantFlowFields::SupplyAirFanPlacement,"DrawThrough");

  model::ModelObject fan = modelObject.supplyAirFan();

  // Node Names

  std::string inletNodeName;
  std::string outletNodeName;
  std::string mixerOutletNodeName;
  std::string coolOutletNodeName;
  std::string heatOutletNodeName;
  std::string oaNodeName;

  if( boost::optional<model::Node> node = modelObject.inletNode() )
  {
    inletNodeName = node->name().get();      
  } 

  if( boost::optional<model::Node> node = modelObject.outletNode() )
  {
    outletNodeName = node->name().get();
  }

  mixerOutletNodeName = modelObject.name().get() + " Mixer Outlet Node";

  coolOutletNodeName = modelObject.name().get() + " Cooling Coil Outlet Node";

  heatOutletNodeName = modelObject.name().get() + " Heating Coil Outlet Node";

  oaNodeName = modelObject.name().get() + " Outdoor Air Node";

  // TerminalUnitAirInletNodeName

  idfObject.setString(ZoneHVAC_TerminalUnit_VariableRefrigerantFlowFields::TerminalUnitAirInletNodeName,inletNodeName);

  // TerminalUnitAirOutletNodeName

  idfObject.setString(ZoneHVAC_TerminalUnit_VariableRefrigerantFlowFields::TerminalUnitAirOutletNodeName,outletNodeName);

  if( boost::optional<IdfObject> _fan = translateAndMapModelObject(fan) )
  {
    // SupplyAirFanObjectType

    idfObject.setString(ZoneHVAC_TerminalUnit_VariableRefrigerantFlowFields::SupplyAirFanObjectType,_fan->iddObject().name());

    // SupplyAirFanObjectName

    idfObject.setString(ZoneHVAC_TerminalUnit_VariableRefrigerantFlowFields::SupplyAirFanObjectName,_fan->name().get());

    if( fan.iddObject().type() == model::FanOnOff::iddObjectType() ) {
      _fan->setString(Fan_OnOffFields::AirInletNodeName,heatOutletNodeName);
      _fan->setString(Fan_OnOffFields::AirOutletNodeName,outletNodeName);
    } else if( fan.iddObject().type() == model::FanConstantVolume::iddObjectType() ) {
      _fan->setString(Fan_ConstantVolumeFields::AirInletNodeName,heatOutletNodeName);
      _fan->setString(Fan_ConstantVolumeFields::AirOutletNodeName,outletNodeName);
    } else {
      LOG(Error, "VRF named " << modelObject.name().get() << " uses an unsupported fan type.");
    }
  }

  // OutdoorAirMixer

  IdfObject _outdoorAirMixer(IddObjectType::OutdoorAir_Mixer);
  _outdoorAirMixer.setName(modelObject.name().get() + " OA Mixer");
  m_idfObjects.push_back(_outdoorAirMixer);

  _outdoorAirMixer.setString(OutdoorAir_MixerFields::MixedAirNodeName,mixerOutletNodeName);

  _outdoorAirMixer.setString(OutdoorAir_MixerFields::ReturnAirStreamNodeName,inletNodeName);

  IdfObject _oaNodeList(openstudio::IddObjectType::OutdoorAir_NodeList);
  _oaNodeList.setString(0,oaNodeName);
  m_idfObjects.push_back(_oaNodeList);

  _outdoorAirMixer.setString(OutdoorAir_MixerFields::ReliefAirStreamNodeName,modelObject.name().get() + " Relief Node Name");

  _outdoorAirMixer.setString(OutdoorAir_MixerFields::OutdoorAirStreamNodeName,oaNodeName);

  // OutsideAirMixerObjectType

  idfObject.setString(ZoneHVAC_TerminalUnit_VariableRefrigerantFlowFields::OutsideAirMixerObjectType,_outdoorAirMixer.iddObject().name());

  // OutsideAirMixerObjectName

  idfObject.setString(ZoneHVAC_TerminalUnit_VariableRefrigerantFlowFields::OutsideAirMixerObjectName,_outdoorAirMixer.name().get());

  model::ModelObject coolingCoil = modelObject.coolingCoil();
  
  if( boost::optional<IdfObject> _coolingCoil = translateAndMapModelObject(coolingCoil) )
  {
    // CoolingCoilObjectType

    idfObject.setString(ZoneHVAC_TerminalUnit_VariableRefrigerantFlowFields::CoolingCoilObjectType,_coolingCoil->iddObject().name());

    // CoolingCoilObjectName
    
    idfObject.setString(ZoneHVAC_TerminalUnit_VariableRefrigerantFlowFields::CoolingCoilObjectName,_coolingCoil->name().get());

    _coolingCoil->setString(Coil_Cooling_DX_VariableRefrigerantFlowFields::CoilAirInletNode,mixerOutletNodeName);

    _coolingCoil->setString(Coil_Cooling_DX_VariableRefrigerantFlowFields::CoilAirOutletNode,coolOutletNodeName);
  }

  model::ModelObject heatingCoil = modelObject.heatingCoil();
  
  if( boost::optional<IdfObject> _heatingCoil = translateAndMapModelObject(heatingCoil) )
  {
    // HeatingCoilObjectType

    idfObject.setString(ZoneHVAC_TerminalUnit_VariableRefrigerantFlowFields::HeatingCoilObjectType,_heatingCoil->iddObject().name());

    // HeatingCoilObjectName
    
    idfObject.setString(ZoneHVAC_TerminalUnit_VariableRefrigerantFlowFields::HeatingCoilObjectName,_heatingCoil->name().get());

    _heatingCoil->setString(Coil_Heating_DX_VariableRefrigerantFlowFields::CoilAirInletNode,coolOutletNodeName);

    _heatingCoil->setString(Coil_Heating_DX_VariableRefrigerantFlowFields::CoilAirOutletNode,heatOutletNodeName);
  }

  // ZoneTerminalUnitOnParasiticElectricEnergyUse

  if( (value = modelObject.zoneTerminalUnitOnParasiticElectricEnergyUse()) )
  {
    idfObject.setDouble(ZoneHVAC_TerminalUnit_VariableRefrigerantFlowFields::ZoneTerminalUnitOnParasiticElectricEnergyUse,value.get());
  }

  // ZoneTerminalUnitOffParasiticElectricEnergyUse

  if( (value = modelObject.zoneTerminalUnitOffParasiticElectricEnergyUse()) )
  {
    idfObject.setDouble(ZoneHVAC_TerminalUnit_VariableRefrigerantFlowFields::ZoneTerminalUnitOffParasiticElectricEnergyUse,value.get());
  }

  // RatedTotalHeatingCapacitySizingRatio

  if( (value = modelObject.ratedTotalHeatingCapacitySizingRatio()) )
  {
    idfObject.setDouble(ZoneHVAC_TerminalUnit_VariableRefrigerantFlowFields::RatedTotalHeatingCapacitySizingRatio,value.get());
  }

  return idfObject;
}
boost::optional<IdfObject> ForwardTranslator::translateZoneHVACWaterToAirHeatPump( 
    ZoneHVACWaterToAirHeatPump& modelObject)
{
  boost::optional<std::string> s;
  boost::optional<double> value;

  IdfObject idfObject(IddObjectType::ZoneHVAC_WaterToAirHeatPump);

  m_idfObjects.push_back(idfObject);

  // Name
  std::string baseName = modelObject.name().get();

  idfObject.setName(baseName);

  std::string mixedAirNodeName = baseName + " Mixed Air Node";

  std::string coolingCoilOutletNodeName = baseName + " Cooling Coil Outlet Node";

  std::string heatingCoilOutletNodeName = baseName + " Heating Coil Outlet Node";

  std::string fanOutletNodeName = baseName + " Fan Outlet Node";

  std::string reliefAirNodeName = baseName + " Relief Air Node";

  std::string oaNodeName = baseName + " OA Node";

  // AvailabilityScheduleName
  if( boost::optional<Schedule> schedule = modelObject.availabilitySchedule() )
  {
    if( boost::optional<IdfObject> _schedule = translateAndMapModelObject(schedule.get()) )
    {
      idfObject.setString(ZoneHVAC_WaterToAirHeatPumpFields::AvailabilityScheduleName,_schedule->name().get());
    }
  }

  // AirInletNodeName
  boost::optional<std::string> airInletNodeName;

  if( boost::optional<Node> node = modelObject.inletNode() )
  {
    if( s = node->name() )
    {
      airInletNodeName = s;

      idfObject.setString(ZoneHVAC_WaterToAirHeatPumpFields::AirInletNodeName,s.get());
    }
  }

  // AirOutletNodeName
  boost::optional<std::string> airOutletNodeName;

  if( boost::optional<Node> node = modelObject.outletNode() )
  {
    if( s = node->name() )
    {
      airOutletNodeName = s;

      idfObject.setString(ZoneHVAC_WaterToAirHeatPumpFields::AirOutletNodeName,s.get());
    }
  }

  // Outdoor Air Mixer

  std::string oaMixerName = baseName + " OA Mixer";  

  IdfObject _outdoorAirMixer(IddObjectType::OutdoorAir_Mixer);
  _outdoorAirMixer.setName(oaMixerName);
  m_idfObjects.push_back(_outdoorAirMixer);

  _outdoorAirMixer.setString(OutdoorAir_MixerFields::MixedAirNodeName,mixedAirNodeName);

  _outdoorAirMixer.setString(OutdoorAir_MixerFields::OutdoorAirStreamNodeName,oaNodeName);

  IdfObject _oaNodeList(openstudio::IddObjectType::OutdoorAir_NodeList);
  _oaNodeList.setString(0,oaNodeName);
  m_idfObjects.push_back(_oaNodeList);

  _outdoorAirMixer.setString(OutdoorAir_MixerFields::ReliefAirStreamNodeName,reliefAirNodeName);

  if(airInletNodeName)
  {
    _outdoorAirMixer.setString(OutdoorAir_MixerFields::ReturnAirStreamNodeName,airInletNodeName.get());
  }

  // OutdoorAirMixerObjectType
  idfObject.setString(ZoneHVAC_WaterToAirHeatPumpFields::OutdoorAirMixerObjectType,
                      _outdoorAirMixer.iddObject().name());

  // OutdoorAirMixerName
  idfObject.setString(ZoneHVAC_WaterToAirHeatPumpFields::OutdoorAirMixerName,oaMixerName);

  // SupplyAirFlowRateDuringCoolingOperation
  if( modelObject.isSupplyAirFlowRateDuringCoolingOperationAutosized() )
  {
    idfObject.setString(ZoneHVAC_WaterToAirHeatPumpFields::SupplyAirFlowRateDuringCoolingOperation,"Autosize");
  }
  else if( value = modelObject.supplyAirFlowRateDuringCoolingOperation() )
  {
    idfObject.setDouble(ZoneHVAC_WaterToAirHeatPumpFields::SupplyAirFlowRateDuringCoolingOperation,value.get());
  }

  // SupplyAirFlowRateDuringHeatingOperation
  if( modelObject.isSupplyAirFlowRateDuringHeatingOperationAutosized() )
  {
    idfObject.setString(ZoneHVAC_WaterToAirHeatPumpFields::SupplyAirFlowRateDuringHeatingOperation,"Autosize");
  }
  else if( value = modelObject.supplyAirFlowRateDuringHeatingOperation() )
  {
    idfObject.setDouble(ZoneHVAC_WaterToAirHeatPumpFields::SupplyAirFlowRateDuringHeatingOperation,value.get());
  }

  // SupplyAirFlowRateWhenNoCoolingorHeatingisNeeded
  if( modelObject.isSupplyAirFlowRateWhenNoCoolingorHeatingisNeededAutosized() )
  {
    idfObject.setString(ZoneHVAC_WaterToAirHeatPumpFields::SupplyAirFlowRateWhenNoCoolingorHeatingisNeeded,"Autosize");
  } 
  else if( value = modelObject.supplyAirFlowRateWhenNoCoolingorHeatingisNeeded() )
  {
    idfObject.setDouble(ZoneHVAC_WaterToAirHeatPumpFields::SupplyAirFlowRateWhenNoCoolingorHeatingisNeeded,value.get());
  }

  // OutdoorAirFlowRateDuringCoolingOperation
  if( modelObject.isOutdoorAirFlowRateDuringCoolingOperationAutosized() )
  {
    idfObject.setString(ZoneHVAC_WaterToAirHeatPumpFields::OutdoorAirFlowRateDuringCoolingOperation,"Autosize");
  }
  else if( value = modelObject.outdoorAirFlowRateDuringCoolingOperation() )
  {
    idfObject.setDouble(ZoneHVAC_WaterToAirHeatPumpFields::OutdoorAirFlowRateDuringCoolingOperation,value.get());
  }

  // OutdoorAirFlowRateDuringHeatingOperation
  if( modelObject.isOutdoorAirFlowRateDuringHeatingOperationAutosized() )
  {
    idfObject.setString(ZoneHVAC_WaterToAirHeatPumpFields::OutdoorAirFlowRateDuringHeatingOperation,"Autosize");
  }
  else if( value = modelObject.outdoorAirFlowRateDuringHeatingOperation() )
  {
    idfObject.setDouble(ZoneHVAC_WaterToAirHeatPumpFields::OutdoorAirFlowRateDuringHeatingOperation,value.get());
  }

  // OutdoorAirFlowRateWhenNoCoolingorHeatingisNeeded  
  if( modelObject.isOutdoorAirFlowRateWhenNoCoolingorHeatingisNeededAutosized() )
  {
    idfObject.setString(ZoneHVAC_WaterToAirHeatPumpFields::OutdoorAirFlowRateWhenNoCoolingorHeatingisNeeded,"Autosize");
  }
  else if( value = modelObject.outdoorAirFlowRateWhenNoCoolingorHeatingisNeeded() )
  {
    idfObject.setDouble(ZoneHVAC_WaterToAirHeatPumpFields::OutdoorAirFlowRateWhenNoCoolingorHeatingisNeeded,value.get());
  }

  // SupplyAirFanObjectType and Name
  HVACComponent supplyAirFan = modelObject.supplyAirFan();

  if( boost::optional<IdfObject> _supplyAirFan = translateAndMapModelObject(supplyAirFan) )
  {
    idfObject.setString(ZoneHVAC_WaterToAirHeatPumpFields::SupplyAirFanObjectType,_supplyAirFan->iddObject().name() );

    idfObject.setString(ZoneHVAC_WaterToAirHeatPumpFields::SupplyAirFanName,_supplyAirFan->name().get());

    if( _supplyAirFan->iddObject().type() == IddObjectType::Fan_OnOff )
    {
      _supplyAirFan->setString(Fan_OnOffFields::AirInletNodeName,mixedAirNodeName);

      _supplyAirFan->setString(Fan_OnOffFields::AirOutletNodeName,fanOutletNodeName);
    }
  }

  // HeatingCoilObjectType and Name  
  HVACComponent heatingCoil = modelObject.heatingCoil();

  if( boost::optional<IdfObject> _heatingCoil = translateAndMapModelObject(heatingCoil) )
  {
    idfObject.setString(ZoneHVAC_WaterToAirHeatPumpFields::HeatingCoilObjectType,_heatingCoil->iddObject().name() );

    idfObject.setString(ZoneHVAC_WaterToAirHeatPumpFields::HeatingCoilName,_heatingCoil->name().get() ); 

    if( _heatingCoil->iddObject().type() == IddObjectType::Coil_Heating_WaterToAirHeatPump_EquationFit )
    {
      _heatingCoil->setString(Coil_Heating_WaterToAirHeatPump_EquationFitFields::AirInletNodeName,coolingCoilOutletNodeName);

      _heatingCoil->setString(Coil_Heating_WaterToAirHeatPump_EquationFitFields::AirOutletNodeName,heatingCoilOutletNodeName);
    }
  }

  // CoolingCoilObjectType and Name
  HVACComponent coolingCoil = modelObject.coolingCoil();

  if( boost::optional<IdfObject> _coolingCoil = translateAndMapModelObject(coolingCoil) )
  {
    idfObject.setString(ZoneHVAC_WaterToAirHeatPumpFields::CoolingCoilObjectType,_coolingCoil->iddObject().name() );

    idfObject.setString(ZoneHVAC_WaterToAirHeatPumpFields::CoolingCoilName,_coolingCoil->name().get() );

    if( _coolingCoil->iddObject().type() == IddObjectType::Coil_Cooling_WaterToAirHeatPump_EquationFit)
    {
      _coolingCoil->setString(Coil_Cooling_WaterToAirHeatPump_EquationFitFields::AirInletNodeName,fanOutletNodeName);

      _coolingCoil->setString(Coil_Cooling_WaterToAirHeatPump_EquationFitFields::AirOutletNodeName,coolingCoilOutletNodeName);
    }
  }

  //Maximum Cycling Rate
  if( value = modelObject.maximumCyclingRate() )
  {
    idfObject.setDouble(ZoneHVAC_WaterToAirHeatPumpFields::MaximumCyclingRate,value.get());
  }

  //Heat Pump Time Constant
  if( value = modelObject.heatPumpTimeConstant() )
  {
    idfObject.setDouble(ZoneHVAC_WaterToAirHeatPumpFields::HeatPumpTimeConstant,value.get());
  }

  //Fraction of On-Cycle Power Use
  if( value = modelObject.fractionofOnCyclePowerUse())
  {
    idfObject.setDouble(ZoneHVAC_WaterToAirHeatPumpFields::FractionofOnCyclePowerUse,value.get());
  }

  //Heat Pump Fan Delay Time
  if( value = modelObject.heatPumpFanDelayTime() )
  {
    idfObject.setDouble(ZoneHVAC_WaterToAirHeatPumpFields::HeatPumpFanDelayTime,value.get());
  }

  // SupplementalHeatingCoilObjectType and SupplementalHeatingCoilName
  HVACComponent supplementalHeatingCoil = modelObject.supplementalHeatingCoil();

  if( boost::optional<IdfObject> _supplementalHeatingCoil = translateAndMapModelObject(supplementalHeatingCoil) )
  {
    idfObject.setString(ZoneHVAC_WaterToAirHeatPumpFields::SupplementalHeatingCoilObjectType,_supplementalHeatingCoil->iddObject().name() );

    idfObject.setString(ZoneHVAC_WaterToAirHeatPumpFields::SupplementalHeatingCoilName,_supplementalHeatingCoil->name().get() );

    if( airOutletNodeName )
    {
      if( _supplementalHeatingCoil->iddObject().type() == IddObjectType::Coil_Heating_Gas )
      {
        _supplementalHeatingCoil->setString(Coil_Heating_GasFields::AirInletNodeName,heatingCoilOutletNodeName);

        _supplementalHeatingCoil->setString(Coil_Heating_GasFields::AirOutletNodeName,airOutletNodeName.get());
      }
      else if( _supplementalHeatingCoil->iddObject().type() == IddObjectType::Coil_Heating_Electric )
      {
        _supplementalHeatingCoil->setString(Coil_Heating_ElectricFields::AirInletNodeName,heatingCoilOutletNodeName);

        _supplementalHeatingCoil->setString(Coil_Heating_ElectricFields::AirOutletNodeName,airOutletNodeName.get());
      }
      else if( _supplementalHeatingCoil->iddObject().type() == IddObjectType::Coil_Heating_Water )
      {
        _supplementalHeatingCoil->setString(Coil_Heating_WaterFields::AirInletNodeName,heatingCoilOutletNodeName);

        _supplementalHeatingCoil->setString(Coil_Heating_WaterFields::AirOutletNodeName,airOutletNodeName.get());
      }
    }
  }

  // MaximumSupplyAirTemperaturefromSupplementalHeater
  if( modelObject.isMaximumSupplyAirTemperaturefromSupplementalHeaterAutosized() )
  {
    idfObject.setString(ZoneHVAC_WaterToAirHeatPumpFields::MaximumSupplyAirTemperaturefromSupplementalHeater,"Autosize"); 
  }
  else if( value = modelObject.maximumSupplyAirTemperaturefromSupplementalHeater() )
  {
    idfObject.setDouble(ZoneHVAC_WaterToAirHeatPumpFields::MaximumSupplyAirTemperaturefromSupplementalHeater,value.get());
  }

  // MaximumOutdoorDryBulbTemperatureforSupplementalHeaterOperation
  if( value = modelObject.maximumOutdoorDryBulbTemperatureforSupplementalHeaterOperation() )
  {
    idfObject.setDouble(ZoneHVAC_WaterToAirHeatPumpFields::MaximumOutdoorDryBulbTemperatureforSupplementalHeaterOperation,value.get());
  }

  //Outdoor Dry-bulb Temperature Sensor Node Name
  idfObject.setString(ZoneHVAC_WaterToAirHeatPumpFields::OutdoorDryBulbTemperatureSensorNodeName,"");

  // FanPlacement
  idfObject.setString(ZoneHVAC_WaterToAirHeatPumpFields::FanPlacement,modelObject.fanPlacement());

  // SupplyAirFanOperatingModeScheduleName
  if( boost::optional<Schedule> schedule = modelObject.supplyAirFanOperatingModeSchedule() )
  {
    if( boost::optional<IdfObject> _schedule = translateAndMapModelObject(schedule.get()) )
    {
      idfObject.setString(ZoneHVAC_WaterToAirHeatPumpFields::SupplyAirFanOperatingModeScheduleName,_schedule->name().get());
    }
  }

  return idfObject;
}
boost::optional<IdfObject> ForwardTranslator::translateAirLoopHVACUnitaryHeatCoolVAVChangeoverBypass( AirLoopHVACUnitaryHeatCoolVAVChangeoverBypass & modelObject )
{
  boost::optional<std::string> s;
  boost::optional<double> d;

  // Name
  IdfObject unitarySystem = createRegisterAndNameIdfObject(openstudio::IddObjectType::AirLoopHVAC_UnitaryHeatCool_VAVChangeoverBypass, modelObject);

  // Availability Schedule Name
  if( boost::optional<Schedule> availabilitySchedule = modelObject.availabilitySchedule() )
  {
    boost::optional<IdfObject> _availabilitySchedule = translateAndMapModelObject(availabilitySchedule.get());

    if( _availabilitySchedule && _availabilitySchedule->name() )
    {
      unitarySystem.setString(AirLoopHVAC_UnitaryHeatCool_VAVChangeoverBypassFields::AvailabilityScheduleName,_availabilitySchedule->name().get());
    }
  }

  //  SystemAirFlowRateDuringCoolingOperation
  if( modelObject.isSystemAirFlowRateDuringCoolingOperationAutosized() ) {
    unitarySystem.setString(AirLoopHVAC_UnitaryHeatCool_VAVChangeoverBypassFields::CoolingSupplyAirFlowRate,"AutoSize");
  } else if( (d = modelObject.systemAirFlowRateDuringCoolingOperation()) ) {
    unitarySystem.setDouble(AirLoopHVAC_UnitaryHeatCool_VAVChangeoverBypassFields::CoolingSupplyAirFlowRate,d.get());
  }

  //  SystemAirFlowRateDuringHeatingOperation
  if( modelObject.isSystemAirFlowRateDuringHeatingOperationAutosized() ) {
    unitarySystem.setString(AirLoopHVAC_UnitaryHeatCool_VAVChangeoverBypassFields::HeatingSupplyAirFlowRate,"AutoSize");
  } else if( (d = modelObject.systemAirFlowRateDuringHeatingOperation()) ) {
    unitarySystem.setDouble(AirLoopHVAC_UnitaryHeatCool_VAVChangeoverBypassFields::HeatingSupplyAirFlowRate,d.get());
  }
  
  //  SystemAirFlowRateWhenNoCoolingorHeatingisNeeded
  if( modelObject.isSystemAirFlowRateWhenNoCoolingorHeatingisNeededAutosized() ) {
    unitarySystem.setString(AirLoopHVAC_UnitaryHeatCool_VAVChangeoverBypassFields::NoLoadSupplyAirFlowRate,"AutoSize");
  } else if( (d = modelObject.systemAirFlowRateWhenNoCoolingorHeatingisNeeded()) ) {
    unitarySystem.setDouble(AirLoopHVAC_UnitaryHeatCool_VAVChangeoverBypassFields::NoLoadSupplyAirFlowRate,d.get());
  } 
  
  //  OutdoorAirFlowRateDuringCoolingOperation
  if( modelObject.isOutdoorAirFlowRateDuringCoolingOperationAutosized() ) {
    unitarySystem.setString(AirLoopHVAC_UnitaryHeatCool_VAVChangeoverBypassFields::CoolingOutdoorAirFlowRate,"AutoSize");
  } else if( (d = modelObject.outdoorAirFlowRateDuringCoolingOperation()) ) {
    unitarySystem.setDouble(AirLoopHVAC_UnitaryHeatCool_VAVChangeoverBypassFields::CoolingOutdoorAirFlowRate,d.get());
  }
  
  //  OutdoorAirFlowRateDuringHeatingOperation
  if( modelObject.isOutdoorAirFlowRateDuringHeatingOperationAutosized() ) {
    unitarySystem.setString(AirLoopHVAC_UnitaryHeatCool_VAVChangeoverBypassFields::HeatingOutdoorAirFlowRate,"AutoSize");
  } else if( (d = modelObject.outdoorAirFlowRateDuringHeatingOperation()) ) {
    unitarySystem.setDouble(AirLoopHVAC_UnitaryHeatCool_VAVChangeoverBypassFields::HeatingOutdoorAirFlowRate,d.get());
  }
  
  //  OutdoorAirFlowRateWhenNoCoolingorHeatingisNeeded
  if( modelObject.isOutdoorAirFlowRateWhenNoCoolingorHeatingisNeededAutosized() ) {
    unitarySystem.setString(AirLoopHVAC_UnitaryHeatCool_VAVChangeoverBypassFields::NoLoadOutdoorAirFlowRate,"AutoSize");
  } else if( (d = modelObject.outdoorAirFlowRateWhenNoCoolingorHeatingisNeeded()) ) {
    unitarySystem.setDouble(AirLoopHVAC_UnitaryHeatCool_VAVChangeoverBypassFields::NoLoadOutdoorAirFlowRate,d.get());
  } 

  //  OutdoorAirFlowRateMultiplierScheduleName
  if( boost::optional<Schedule> schedule = modelObject.outdoorAirFlowRateMultiplierSchedule() ) {
    if( boost::optional<IdfObject> _schedule = translateAndMapModelObject(schedule.get()) ) {
      unitarySystem.setString(AirLoopHVAC_UnitaryHeatCool_VAVChangeoverBypassFields::OutdoorAirFlowRateMultiplierScheduleName,_schedule->name().get());
    }
  }

  boost::optional<std::string> airInletNodeName;
  boost::optional<std::string> airOutletNodeName;

  // Air Inlet Node Name
  if( boost::optional<ModelObject> mo = modelObject.inletModelObject() )
  {
    if( boost::optional<Node> node = mo->optionalCast<Node>() )
    {
      airInletNodeName = node->name().get();
      unitarySystem.setString(AirLoopHVAC_UnitaryHeatCool_VAVChangeoverBypassFields::AirInletNodeName,node->name().get());
    }
  }

  // Air Outlet Node Name
  if( boost::optional<ModelObject> mo = modelObject.outletModelObject() )
  {
    if( boost::optional<Node> node = mo->optionalCast<Node>() )
    {
      airOutletNodeName = node->name().get();
      unitarySystem.setString(AirLoopHVAC_UnitaryHeatCool_VAVChangeoverBypassFields::AirOutletNodeName,node->name().get());
    }
  }

  std::string baseName = modelObject.name().get();

  //  BypassDuctMixerNodeName
  std::string bypassDuctMixerNodeName = baseName + " Bypass Duct Mixer Node";
  unitarySystem.setString(AirLoopHVAC_UnitaryHeatCool_VAVChangeoverBypassFields::BypassDuctMixerNodeName,bypassDuctMixerNodeName);
  
  //  BypassDuctSplitterNodeName
  std::string bypassDuctSplitterNodeName = baseName + " Bypass Duct Splitter Node";
  unitarySystem.setString(AirLoopHVAC_UnitaryHeatCool_VAVChangeoverBypassFields::BypassDuctSplitterNodeName,bypassDuctSplitterNodeName);
  
  //  OutdoorAirMixerObjectType
  unitarySystem.setString(AirLoopHVAC_UnitaryHeatCool_VAVChangeoverBypassFields::OutdoorAirMixerObjectType,"OutdoorAir:Mixer");
  
  //  OutdoorAirMixerName
  std::string outdoorAirMixerName = baseName + " Outdoor Air Mixer";
  unitarySystem.setString(AirLoopHVAC_UnitaryHeatCool_VAVChangeoverBypassFields::OutdoorAirMixerName,outdoorAirMixerName);

  //  SupplyAirFanName
  boost::optional<IdfObject> _fan;
  if( boost::optional<HVACComponent> fan = modelObject.supplyAirFan() ) {
    if( (_fan = translateAndMapModelObject(fan.get())) ) {
      unitarySystem.setString(AirLoopHVAC_UnitaryHeatCool_VAVChangeoverBypassFields::SupplyAirFanObjectType,_fan->iddObject().name());
      unitarySystem.setString(AirLoopHVAC_UnitaryHeatCool_VAVChangeoverBypassFields::SupplyAirFanName,_fan->name().get());
    }
  }
  
  bool blowThroughFan = false;
  //  SupplyAirFanPlacement
  if( (s = modelObject.supplyAirFanPlacement()) ) {
    unitarySystem.setString(AirLoopHVAC_UnitaryHeatCool_VAVChangeoverBypassFields::SupplyAirFanPlacement,s.get());
    if( istringEqual(s.get(),"BlowThrough") ) {
      blowThroughFan = true;
    }
  }
  
  //  SupplyAirFanOperatingModeScheduleName
  if( boost::optional<Schedule> schedule = modelObject.supplyAirFanOperatingModeSchedule() ) {
    if( boost::optional<IdfObject> _schedule = translateAndMapModelObject(schedule.get()) ) {
      unitarySystem.setString(AirLoopHVAC_UnitaryHeatCool_VAVChangeoverBypassFields::SupplyAirFanOperatingModeScheduleName,_schedule->name().get()); 
    }
  }

  // Heating Coil Object Type
  // Heating Coil Name
  boost::optional<IdfObject> _heatingCoil;
  if( boost::optional<HVACComponent> heatingCoil = modelObject.heatingCoil() )
  {
    _heatingCoil = translateAndMapModelObject(heatingCoil.get());

    if( _heatingCoil && _heatingCoil->name() )
    {
      unitarySystem.setString(AirLoopHVAC_UnitaryHeatCool_VAVChangeoverBypassFields::HeatingCoilObjectType,_heatingCoil->iddObject().name());
      unitarySystem.setString(AirLoopHVAC_UnitaryHeatCool_VAVChangeoverBypassFields::HeatingCoilName,_heatingCoil->name().get());
    }
  }

  // Cooling Coil Object Type
  // Cooling Coil Name
  boost::optional<IdfObject> _coolingCoil;
  if( boost::optional<HVACComponent> coolingCoil = modelObject.coolingCoil() )
  {
    if( boost::optional<CoilCoolingDXSingleSpeed> dxCoil = coolingCoil->optionalCast<CoilCoolingDXSingleSpeed>() ) {
      _coolingCoil = translateCoilCoolingDXSingleSpeedWithoutUnitary(dxCoil.get());
      m_map.insert(std::make_pair(coolingCoil->handle(),_coolingCoil.get()));
    } else {
      _coolingCoil = translateAndMapModelObject(coolingCoil.get());
    }

    if( _coolingCoil && _coolingCoil->name() )
    {
      unitarySystem.setString(AirLoopHVAC_UnitaryHeatCool_VAVChangeoverBypassFields::CoolingCoilObjectType,_coolingCoil->iddObject().name());
      unitarySystem.setString(AirLoopHVAC_UnitaryHeatCool_VAVChangeoverBypassFields::CoolingCoilName,_coolingCoil->name().get());
    }
  }

  //  PriorityControlMode
  if( (s = modelObject.priorityControlMode()) ) {
    unitarySystem.setString(AirLoopHVAC_UnitaryHeatCool_VAVChangeoverBypassFields::PriorityControlMode,s.get());
  }
  
  //  MinimumOutletAirTemperatureDuringCoolingOperation
  if( (d = modelObject.minimumOutletAirTemperatureDuringCoolingOperation()) ) {
    unitarySystem.setDouble(AirLoopHVAC_UnitaryHeatCool_VAVChangeoverBypassFields::MinimumOutletAirTemperatureDuringCoolingOperation,d.get());
  }
  
  //  MaximumOutletAirTemperatureDuringHeatingOperation)(Maximum Outlet Air Temperature During Heating Operation))
  if( (d = modelObject.maximumOutletAirTemperatureDuringHeatingOperation()) ) {
    unitarySystem.setDouble(AirLoopHVAC_UnitaryHeatCool_VAVChangeoverBypassFields::MaximumOutletAirTemperatureDuringHeatingOperation,d.get());
  } 
  
  // DehumidificationControlType
  if( (s = modelObject.dehumidificationControlType()) ) {
    unitarySystem.setString(AirLoopHVAC_UnitaryHeatCool_VAVChangeoverBypassFields::DehumidificationControlType,s.get());
  }

  if( _fan && _coolingCoil && _heatingCoil )
  {
    std::string fanOutletNodeName;
    std::string fanInletNodeName;
    std::string heatOutletNodeName;
    std::string heatInletNodeName;
    std::string coolOutletNodeName;
    std::string coolInletNodeName;
    std::string mixedAirNodeName;

    if( blowThroughFan ) {
      mixedAirNodeName = baseName + " Mixed Air Node";
      fanInletNodeName = mixedAirNodeName;
      fanOutletNodeName = baseName + " Fan Outlet Node";
      coolInletNodeName = fanOutletNodeName;
      coolOutletNodeName = baseName + " Cooling Coil Outlet Node";
      heatInletNodeName = coolOutletNodeName;
      heatOutletNodeName = bypassDuctSplitterNodeName;
    } else {
      mixedAirNodeName = baseName + " Mixed Air Node";
      coolInletNodeName = mixedAirNodeName;
      coolOutletNodeName = baseName + " Cooling Coil Outlet Node";
      heatInletNodeName = coolOutletNodeName;
      heatOutletNodeName = baseName + " Heating Coil Outlet Node";
      fanInletNodeName = heatOutletNodeName;
      fanOutletNodeName = bypassDuctSplitterNodeName;
    }

    if( _fan->iddObject().type() == IddObjectType::Fan_ConstantVolume )
    {
      _fan->setString(Fan_ConstantVolumeFields::AirInletNodeName,fanInletNodeName);
      _fan->setString(Fan_ConstantVolumeFields::AirOutletNodeName,fanOutletNodeName);
    }
    else if( _fan->iddObject().type() == IddObjectType::Fan_VariableVolume )
    {
      _fan->setString(Fan_VariableVolumeFields::AirInletNodeName,fanInletNodeName);
      _fan->setString(Fan_VariableVolumeFields::AirOutletNodeName,fanOutletNodeName);
    }
    else if( _fan->iddObject().type() == IddObjectType::Fan_OnOff )
    {
      _fan->setString(Fan_OnOffFields::AirInletNodeName,fanInletNodeName);
      _fan->setString(Fan_OnOffFields::AirOutletNodeName,fanOutletNodeName);
    }

    fixSPMsForUnitarySystem(modelObject,fanInletNodeName,fanOutletNodeName);

    if( _coolingCoil->iddObject().type() == IddObjectType::Coil_Cooling_DX_SingleSpeed )
    {
      _coolingCoil->setString(Coil_Cooling_DX_SingleSpeedFields::AirInletNodeName,coolInletNodeName);
      _coolingCoil->setString(Coil_Cooling_DX_SingleSpeedFields::AirOutletNodeName,coolOutletNodeName);
    }
    else if( _coolingCoil->iddObject().type() == IddObjectType::Coil_Cooling_DX_TwoSpeed )
    {
      _coolingCoil->setString(Coil_Cooling_DX_TwoSpeedFields::AirInletNodeName,coolInletNodeName);
      _coolingCoil->setString(Coil_Cooling_DX_TwoSpeedFields::AirOutletNodeName,coolOutletNodeName);
    }
    else if( _coolingCoil->iddObject().type() == IddObjectType::Coil_Cooling_Water )
    {
      _coolingCoil->setString(Coil_Cooling_WaterFields::AirInletNodeName,coolInletNodeName);
      _coolingCoil->setString(Coil_Cooling_WaterFields::AirOutletNodeName,coolOutletNodeName);
    }
    else if( _coolingCoil->iddObject().type() == IddObjectType::Coil_Cooling_WaterToAirHeatPump_EquationFit )
    {
      _coolingCoil->setString(Coil_Cooling_WaterToAirHeatPump_EquationFitFields::AirInletNodeName,coolInletNodeName);
      _coolingCoil->setString(Coil_Cooling_WaterToAirHeatPump_EquationFitFields::AirOutletNodeName,coolOutletNodeName);
    }

    if( _heatingCoil->iddObject().type() == IddObjectType::Coil_Heating_DX_SingleSpeed )
    {
      _heatingCoil->setString(Coil_Heating_DX_SingleSpeedFields::AirInletNodeName,heatInletNodeName);
      _heatingCoil->setString(Coil_Heating_DX_SingleSpeedFields::AirOutletNodeName,heatOutletNodeName);
    }
    else if( _heatingCoil->iddObject().type() == IddObjectType::Coil_Heating_Electric )
    {
      _heatingCoil->setString(Coil_Heating_ElectricFields::AirInletNodeName,heatInletNodeName);
      _heatingCoil->setString(Coil_Heating_ElectricFields::AirOutletNodeName,heatOutletNodeName);
    }
    else if( _heatingCoil->iddObject().type() == IddObjectType::Coil_Heating_Gas )
    {
      _heatingCoil->setString(Coil_Heating_GasFields::AirInletNodeName,heatInletNodeName);
      _heatingCoil->setString(Coil_Heating_GasFields::AirOutletNodeName,heatOutletNodeName);
    }
    else if( _heatingCoil->iddObject().type() == IddObjectType::Coil_Heating_Water )
    {
      _heatingCoil->setString(Coil_Heating_WaterFields::AirInletNodeName,heatInletNodeName);
      _heatingCoil->setString(Coil_Heating_WaterFields::AirOutletNodeName,heatOutletNodeName);
    }
    else if( _heatingCoil->iddObject().type() == IddObjectType::Coil_Heating_Desuperheater )
    {
      _heatingCoil->setString(Coil_Heating_DesuperheaterFields::AirInletNodeName,heatInletNodeName);
      _heatingCoil->setString(Coil_Heating_DesuperheaterFields::AirOutletNodeName,heatOutletNodeName);
    }
    else if( _heatingCoil->iddObject().type() == IddObjectType::Coil_Heating_WaterToAirHeatPump_EquationFit )
    {
      _heatingCoil->setString(Coil_Heating_WaterToAirHeatPump_EquationFitFields::AirInletNodeName,heatInletNodeName);
      _heatingCoil->setString(Coil_Heating_WaterToAirHeatPump_EquationFitFields::AirOutletNodeName,heatOutletNodeName);
    }

    IdfObject _outdoorAirMixer(IddObjectType::OutdoorAir_Mixer);
    _outdoorAirMixer.setName(outdoorAirMixerName);
    m_idfObjects.push_back(_outdoorAirMixer);

    std::string oaNodeName = baseName + " OA Node";
    _outdoorAirMixer.setString(OutdoorAir_MixerFields::MixedAirNodeName,mixedAirNodeName);
    _outdoorAirMixer.setString(OutdoorAir_MixerFields::OutdoorAirStreamNodeName,oaNodeName);

    IdfObject _oaNodeList(openstudio::IddObjectType::OutdoorAir_NodeList);
    _oaNodeList.setString(0,oaNodeName);
    m_idfObjects.push_back(_oaNodeList);
    _outdoorAirMixer.setString(OutdoorAir_MixerFields::ReliefAirStreamNodeName,baseName + " Relief Air Node");
    _outdoorAirMixer.setString(OutdoorAir_MixerFields::ReturnAirStreamNodeName,bypassDuctMixerNodeName);
  }

  return unitarySystem;
}