void BuildingsPanel::Update() {
    //std::cout << "BuildingsPanel::Update" << std::endl;

    // remove old indicators
    for (std::vector<BuildingIndicator*>::iterator it = m_building_indicators.begin(); it != m_building_indicators.end(); ++it) {
        DetachChild(*it);
        delete (*it);
    }
    m_building_indicators.clear();

    TemporaryPtr<const Planet> planet = GetPlanet(m_planet_id);
    if (!planet) {
        ErrorLogger() << "BuildingsPanel::Update couldn't get planet with id " << m_planet_id;
        return;
    }
    const std::set<int>& buildings = planet->BuildingIDs();
    int system_id = planet->SystemID();

    const int indicator_size = static_cast<int>(Value(Width() * 1.0 / m_columns));

    int this_client_empire_id = HumanClientApp::GetApp()->EmpireID();
    const std::set<int>& this_client_known_destroyed_objects = GetUniverse().EmpireKnownDestroyedObjectIDs(this_client_empire_id);
    const std::set<int>& this_client_stale_object_info = GetUniverse().EmpireStaleKnowledgeObjectIDs(this_client_empire_id);

    // get existing / finished buildings and use them to create building indicators
    for (std::set<int>::const_iterator it = buildings.begin(); it != buildings.end(); ++it) {
        int object_id = *it;

        // skip known destroyed and stale info objects
        if (this_client_known_destroyed_objects.find(object_id) != this_client_known_destroyed_objects.end())
            continue;
        if (this_client_stale_object_info.find(object_id) != this_client_stale_object_info.end())
            continue;

        TemporaryPtr<const Building> building = GetBuilding(object_id);
        if (!building) {
            ErrorLogger() << "BuildingsPanel::Update couldn't get building with id: " << object_id << " on planet " << planet->Name();
            continue;
        }

        if (building->SystemID() != system_id || building->PlanetID() != m_planet_id)
            continue;

        BuildingIndicator* ind = new BuildingIndicator(GG::X(indicator_size), object_id);
        m_building_indicators.push_back(ind);

        GG::Connect(ind->RightClickedSignal,    BuildingRightClickedSignal);
    }

    // get in-progress buildings
    const Empire* empire = GetEmpire(planet->Owner());
    if (!empire)
        return;

    const ProductionQueue& queue = empire->GetProductionQueue();

    int queue_index = 0;
    for (ProductionQueue::const_iterator queue_it = queue.begin(); queue_it != queue.end(); ++queue_it, ++queue_index) {
        const ProductionQueue::Element elem = *queue_it;

        if (elem.item.build_type != BT_BUILDING) continue;  // don't show in-progress ships in BuildingsPanel...
        if (elem.location != m_planet_id) continue;         // don't show buildings located elsewhere

        double total_cost;
        int total_turns;
        boost::tie(total_cost, total_turns) = empire->ProductionCostAndTime(elem);

        double progress = std::max(0.0f, empire->ProductionStatus(queue_index));
        double turns_completed = total_turns * std::min<double>(1.0, progress / total_cost);
        BuildingIndicator* ind = new BuildingIndicator(GG::X(indicator_size), elem.item.name,
                                                       turns_completed, total_turns);
        m_building_indicators.push_back(ind);
    }
}