boost::optional<IdfObject> ForwardTranslator::translateZoneHVACEquipmentList( ZoneHVACEquipmentList & modelObject )
{
  OptionalString s;
  OptionalDouble d;
  OptionalModelObject temp;

  std::vector<ModelObject> objects = modelObject.equipment();

  if (objects.empty()){
    // do not write out this object
    return boost::none;
  }

  IdfObject idfObject(IddObjectType::ZoneHVAC_EquipmentList);

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

  for( std::vector<ModelObject>::iterator it = objects.begin();
       it != objects.end();
       it++ )
  {
    unsigned coolingPriority = modelObject.coolingPriority(*it);
    unsigned heatingPriority = modelObject.heatingPriority(*it);

    boost::optional<IdfObject> _equipment = translateAndMapModelObject(*it);

    if( _equipment )
    {
      IdfExtensibleGroup eg = idfObject.pushExtensibleGroup();

      eg.setString(ZoneHVAC_EquipmentListExtensibleFields::ZoneEquipmentObjectType,_equipment->iddObject().name()); 
      eg.setString(ZoneHVAC_EquipmentListExtensibleFields::ZoneEquipmentName,_equipment->name().get()); 
      eg.setUnsigned(ZoneHVAC_EquipmentListExtensibleFields::ZoneEquipmentCoolingSequence,coolingPriority); 
      eg.setUnsigned(ZoneHVAC_EquipmentListExtensibleFields::ZoneEquipmentHeatingorNoLoadSequence,heatingPriority); 
    }
  }

  m_idfObjects.push_back(idfObject);

  return idfObject;
}
boost::optional<IdfObject> ForwardTranslator::translateZoneHVACEquipmentList( ZoneHVACEquipmentList & modelObject )
{
  OptionalString s;
  OptionalDouble d;
  OptionalModelObject temp;

  std::vector<ModelObject> objects = modelObject.equipment();

  if (objects.empty()){
    // do not write out this object
    return boost::none;
  }

  std::vector<ModelObject> coolingVector = modelObject.equipmentInCoolingOrder();
  std::vector<ModelObject> heatingVector = modelObject.equipmentInHeatingOrder();

  std::vector<ModelObject> airChillers;
  std::vector<ModelObject> stdEquipment;

  for( const auto & elem : objects )
  {
    if (boost::optional<RefrigerationAirChiller> airChiller = elem.optionalCast<RefrigerationAirChiller>()) {
      airChillers.push_back(airChiller.get());
    } else {
      stdEquipment.push_back(elem);
    }
  }

  boost::optional<RefrigerationAirChiller> airChiller;
  std::map<ModelObject, unsigned> coolingMap;
  unsigned chillerSetCoolingPriority = 0;
  unsigned priority = 1;
  int airChillerOffset = -1;
  for( const auto & elem : coolingVector )
  {
    if (airChillers.size() > 0 && (airChiller = elem.optionalCast<RefrigerationAirChiller>()) )
    {
      if (chillerSetCoolingPriority == 0) {
        chillerSetCoolingPriority = priority;
      }
      airChillerOffset++;
    }
    else {
      coolingMap.insert ( std::pair<ModelObject,unsigned>(elem, ((airChillerOffset > 0) ? (priority - airChillerOffset) : priority) ) );
    }
    priority++;
  }

  std::map<ModelObject, unsigned> heatingMap;
  unsigned chillerSetHeatingPriority = 0;
  priority = 1;
  airChillerOffset = -1;
  for( const auto & elem : heatingVector )
  {
    if (airChillers.size() > 0 && (airChiller= elem.optionalCast<RefrigerationAirChiller>()) )
    {
      if (chillerSetHeatingPriority == 0) {
        chillerSetHeatingPriority = priority;
      }
      airChillerOffset++;
    }
    else {
      heatingMap.insert ( std::pair<ModelObject,unsigned>(elem, ((airChillerOffset > 0) ? (priority - airChillerOffset) : priority) ) );
    }
    priority++;
  }

  IdfObject idfObject(IddObjectType::ZoneHVAC_EquipmentList);

  // Name
  std::string name;
  s = modelObject.thermalZone().name();
  if(s)
  {
    name = s.get() + " Equipment List";
    idfObject.setName(name);
  }

  for( auto & elem : stdEquipment )
  {
    unsigned coolingPriority = coolingMap[elem];
    unsigned heatingPriority = heatingMap[elem];

    boost::optional<IdfObject> _equipment = translateAndMapModelObject(elem);

    if( _equipment && (! elem.optionalCast<ZoneVentilationDesignFlowRate>()) )
    {
      IdfExtensibleGroup eg = idfObject.pushExtensibleGroup();

      eg.setString(ZoneHVAC_EquipmentListExtensibleFields::ZoneEquipmentObjectType,_equipment->iddObject().name()); 
      eg.setString(ZoneHVAC_EquipmentListExtensibleFields::ZoneEquipmentName,_equipment->name().get()); 
      eg.setUnsigned(ZoneHVAC_EquipmentListExtensibleFields::ZoneEquipmentCoolingSequence,coolingPriority); 
      eg.setUnsigned(ZoneHVAC_EquipmentListExtensibleFields::ZoneEquipmentHeatingorNoLoadSequence,heatingPriority); 
    }
  }

  if (!airChillers.empty()) {
    // ZoneHVAC:RefrigerationChillerSet
    // Name
      IdfObject _chillerSet(IddObjectType::ZoneHVAC_RefrigerationChillerSet);

      m_idfObjects.push_back(_chillerSet);

      _chillerSet.setName(name + " Refrigeration Chiller Set");

    // AvailabilityScheduleName
      boost::optional<Schedule> availabilitySchedule = modelObject.model().alwaysOnDiscreteSchedule();

      if( availabilitySchedule )
      {
        boost::optional<IdfObject> _availabilitySchedule = translateAndMapModelObject(availabilitySchedule.get());

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

    // ZoneName
      boost::optional<ThermalZone> thermalZone = modelObject.thermalZone();

      if( thermalZone )
      {
        boost::optional<IdfObject> _thermalZone = translateAndMapModelObject(thermalZone.get());

        if( _thermalZone && _thermalZone->name() )
        {
          _chillerSet.setString(ZoneHVAC_RefrigerationChillerSetFields::ZoneName,_thermalZone->name().get());
        }
      }

    // AirInletNodeName
      _chillerSet.setString(ZoneHVAC_RefrigerationChillerSetFields::AirInletNodeName,"");

    // AirOutletNodeName
      _chillerSet.setString(ZoneHVAC_RefrigerationChillerSetFields::AirOutletNodeName,"");

    // AirChiller (extensible)
      for( auto & elem : airChillers )
      {
        boost::optional<IdfObject> _airChiller = translateAndMapModelObject(elem);

        if( _airChiller )
        {
          IdfExtensibleGroup eg = _chillerSet.pushExtensibleGroup();

          eg.setString(ZoneHVAC_RefrigerationChillerSetExtensibleFields::AirChillerName,_airChiller->name().get()); 
        }
      }

    IdfExtensibleGroup eg = idfObject.pushExtensibleGroup();

    eg.setString(ZoneHVAC_EquipmentListExtensibleFields::ZoneEquipmentObjectType,_chillerSet.iddObject().name()); 
    eg.setString(ZoneHVAC_EquipmentListExtensibleFields::ZoneEquipmentName,_chillerSet.name().get()); 
    eg.setUnsigned(ZoneHVAC_EquipmentListExtensibleFields::ZoneEquipmentCoolingSequence, chillerSetCoolingPriority); 
    eg.setUnsigned(ZoneHVAC_EquipmentListExtensibleFields::ZoneEquipmentHeatingorNoLoadSequence, chillerSetHeatingPriority); 
  }

  m_idfObjects.push_back(idfObject);

  return idfObject;
}