diff --git a/Fltk/visibilityWindow.cpp b/Fltk/visibilityWindow.cpp
index a45d6b26c72b548b5aa8f11068e3d40b83eb8c8b..38fb2db8c3b5a8592108226d2f3bf73cfd398e04 100644
--- a/Fltk/visibilityWindow.cpp
+++ b/Fltk/visibilityWindow.cpp
@@ -33,12 +33,16 @@
 #endif
 
 class Vis {
+ private:
+  std::string _name;
  public:
-  Vis(){}
+  Vis() {}
+  Vis(std::string &name) : _name(name) {}
   virtual ~Vis(){}
   virtual int getTag() const = 0;
   virtual int getDim() const { return -1; }
-  virtual std::string getName() const = 0;
+  virtual std::string getName() const { return _name; }
+  virtual std::string getType() const = 0;
   virtual char getVisibility() const = 0;
   virtual void setVisibility(char val, bool recursive=false) = 0;
 };
@@ -48,10 +52,11 @@ class VisModel : public Vis {
   GModel *_model;
   int _tag;
  public:
-  VisModel(GModel *model, int tag) : _model(model), _tag(tag) {}
+  VisModel(GModel *model, int tag, std::string &name)
+    : _model(model), _tag(tag), Vis(name) {}
   ~VisModel(){}
   int getTag() const { return _tag; }
-  std::string getName() const { return "Model"; }
+  std::string getType() const { return "Model"; }
   char getVisibility() const { return _model->getVisibility(); }
   void setVisibility(char val, bool recursive=false){ _model->setVisibility(val); }
 };
@@ -59,20 +64,16 @@ class VisModel : public Vis {
 class VisElementary : public Vis {
  private:
   GEntity *_e;
-  int _dim;
  public:
-  VisElementary(GVertex *e) : _e(e), _dim(0) {}
-  VisElementary(GEdge *e) : _e(e), _dim(1) {}
-  VisElementary(GFace *e) : _e(e), _dim(2) {}
-  VisElementary(GRegion *e) : _e(e), _dim(3) {}
+  VisElementary(GEntity *e, std::string &name) : _e(e), Vis(name) {}
   ~VisElementary(){}
   int getTag() const { return _e->tag(); }
-  int getDim() const { return _dim; }
-  std::string getName() const
+  int getDim() const { return _e->dim(); }
+  std::string getType() const
   {
-    if(_dim == 0) return "Point";
-    else if(_dim == 1) return "Line";
-    else if(_dim == 2) return "Surface";
+    if(_e->dim() == 0) return "Point";
+    else if(_e->dim() == 1) return "Line";
+    else if(_e->dim() == 2) return "Surface";
     else return "Volume";
   }
   char getVisibility() const { return _e->getVisibility(); }
@@ -88,12 +89,12 @@ class VisPhysical : public Vis {
   char _visible;
   std::vector<GEntity*> _list;
  public:
-  VisPhysical(int tag, int dim, std::vector<GEntity*> list) 
-    : _tag(tag), _dim(dim), _visible(1), _list(list)  {}
+  VisPhysical(int tag, int dim, std::vector<GEntity*> list, std::string &name) 
+    : _tag(tag), _dim(dim), _visible(1), _list(list), Vis(name)  {}
   ~VisPhysical(){}
   int getTag() const { return _tag; }
   int getDim() const { return _dim; }
-  std::string getName() const
+  std::string getType() const
   {
     if(_dim == 0) return "Point";
     else if(_dim == 1) return "Line";
@@ -117,7 +118,7 @@ class VisPartition : public Vis {
   VisPartition(int tag) : _tag(tag), _visible(1) {}
   ~VisPartition(){}
   int getTag() const { return _tag; }
-  std::string getName() const { return "Partition"; }
+  std::string getType() const { return "Partition"; }
   char getVisibility() const { return _visible; }
   void setVisibility(char val, bool recursive=false)
   {
@@ -134,7 +135,6 @@ class VisPartition : public Vis {
 
 class VisibilityList { // singleton
  private:
-  std::map<int, std::pair<std::string, int> > _labels;
   std::vector<Vis*> _entities;
   int _sortMode;
   static VisibilityList *_instance;
@@ -152,7 +152,7 @@ class VisibilityList { // singleton
     return _instance;
   }
   class VisLessThan {
-  public:
+   public:
     bool operator()(const Vis *v1, const Vis *v2) const
     {
       switch(instance()->getSortMode()){
@@ -160,13 +160,9 @@ class VisibilityList { // singleton
       case -1: return v1->getDim() > v2->getDim() ? true : false;
       case  2: return v1->getTag() < v2->getTag() ? true : false;
       case -2: return v1->getTag() > v2->getTag() ? true : false;
-      case  3: 
-        return strcmp(instance()->getLabel(v1->getTag()).c_str(), 
-                      instance()->getLabel(v2->getTag()).c_str()) < 0 ? 
+      case  3: return strcmp(v1->getName().c_str(), v2->getName().c_str()) < 0 ?
           true : false;
-      default: 
-        return strcmp(instance()->getLabel(v1->getTag()).c_str(), 
-                      instance()->getLabel(v2->getTag()).c_str()) > 0 ? 
+      default: return strcmp(v1->getName().c_str(), v2->getName().c_str()) > 0 ?
           true : false;
       }
     }
@@ -174,46 +170,45 @@ class VisibilityList { // singleton
   // repopulate the list with current data of the given type
   void update(VisibilityType type)
   {
-    _labels.clear();
-    for(unsigned int i = 0; i < _entities.size(); i++)
-      delete _entities[i];
-    _entities.clear();
-    GModel *m = GModel::current();
+    std::map<int, std::string> oldLabels;
 #if defined(HAVE_PARSER)
     for(std::map<std::string, std::vector<double> >::iterator it = gmsh_yysymbols.begin();
         it != gmsh_yysymbols.end(); ++it)
-      for(unsigned int i = 0; i < it->second.size(); i++)
-        instance()->setLabel((int)it->second[i], it->first, 0);
+      if(it->first.size())
+        for(unsigned int i = 0; i < it->second.size(); i++)
+          oldLabels[(int)it->second[i]] = std::string("(") + it->first + ")";
 #endif
+    for(unsigned int i = 0; i < _entities.size(); i++)
+      delete _entities[i];
+    _entities.clear();
+    GModel *m = GModel::current();
     if(type == Models){
       for(unsigned int i = 0; i < GModel::list.size(); i++){
-        _entities.push_back(new VisModel(GModel::list[i], i));
         std::string name = GModel::list[i]->getName();
         if(GModel::list[i] == GModel::current()) name += " (Active)";
-        setLabel(i, name, 1);
+        _entities.push_back(new VisModel(GModel::list[i], i, name));
       }
     }
     else if(type == ElementaryEntities){
-      for(GModel::piter it = m->firstElementaryName(); it != m->lastElementaryName(); ++it)
-        setLabel(it->first.second, it->second, 1);
-      for(GModel::viter it = m->firstVertex(); it != m->lastVertex(); it++)
-        _entities.push_back(new VisElementary(*it));
-      for(GModel::eiter it = m->firstEdge(); it != m->lastEdge(); it++)
-        _entities.push_back(new VisElementary(*it));
-      for(GModel::fiter it = m->firstFace(); it != m->lastFace(); it++)
-        _entities.push_back(new VisElementary(*it));
-      for(GModel::riter it = m->firstRegion(); it != m->lastRegion(); it++)
-        _entities.push_back(new VisElementary(*it));
+      std::vector<GEntity*> entities;
+      m->getEntities(entities);
+      for(unsigned int i = 0; i < entities.size(); i++){
+        GEntity *ge = entities[i];
+        std::string name = m->getElementaryName(ge->dim(), ge->tag());
+        if(name.empty()) name = oldLabels[ge->tag()];
+        _entities.push_back(new VisElementary(ge, name));
+      }
     }
     else if(type == PhysicalEntities){
-      for(GModel::piter it = m->firstPhysicalName(); it != m->lastPhysicalName(); ++it)
-        setLabel(it->first.second, it->second, 1);
       std::map<int, std::vector<GEntity*> > groups[4];
       m->getPhysicalGroups(groups);
       for(int i = 0; i < 4; i++){
         std::map<int, std::vector<GEntity*> >::const_iterator it = groups[i].begin();
-        for(; it != groups[i].end(); ++it)
-          _entities.push_back(new VisPhysical(it->first, i, it->second));
+        for(; it != groups[i].end(); ++it){
+          std::string name = m->getPhysicalName(i, it->first);
+          if(name.empty()) name = oldLabels[it->first];
+          _entities.push_back(new VisPhysical(it->first, i, it->second, name));
+        }
       }
     }
     else if(type == MeshPartitions){
@@ -242,16 +237,11 @@ class VisibilityList { // singleton
         GModel::list[i]->setVisibility(0);
     }
     else if(type == ElementaryEntities || type == PhysicalEntities){
-      GModel *m = GModel::current();
       // elementary or physical mode: set all entities in the model invisible
-      for(GModel::viter it = m->firstVertex(); it != m->lastVertex(); it++)
-        (*it)->setVisibility(0);
-      for(GModel::eiter it = m->firstEdge(); it != m->lastEdge(); it++)
-        (*it)->setVisibility(0);
-      for(GModel::fiter it = m->firstFace(); it != m->lastFace(); it++)
-        (*it)->setVisibility(0);
-      for(GModel::riter it = m->firstRegion(); it != m->lastRegion(); it++)
-        (*it)->setVisibility(0);
+      std::vector<GEntity*> entities;
+      GModel::current()->getEntities(entities);
+      for(unsigned int i = 0; i < entities.size(); i++)
+        entities[i]->setVisibility(0);
     }
     // this is superfluous in elementary mode, but we don't care
     for(int i = 0; i < getNumEntities(); i++) setVisibility(i, 0);
@@ -261,27 +251,16 @@ class VisibilityList { // singleton
   // get the browser line for the nth entity in the list
   std::string getBrowserLine(int n)
   {
-    int tag = _entities[n]->getTag();
     std::ostringstream sstream;
-    sstream << "\t" << _entities[n]->getName() << "\t" << tag << "\t";
-    if(_labels.count(tag)){
-      if(_labels[tag].second)
-        sstream << "@b";
-      sstream << _labels[tag].first;
-    }
+    sstream << "\t" << _entities[n]->getType() 
+            << "\t" << _entities[n]->getTag() 
+            << "\t" << _entities[n]->getName();
     return sstream.str();
   }
   // set the sort mode
   void setSortMode(int mode){ _sortMode = (_sortMode != mode) ? mode : -mode; }
   // get the sort mode
   int getSortMode(){ return _sortMode; }
-  // associate a label with a tag (quality=0 for "old-style" unreliable labels)
-  void setLabel(int tag, std::string label, int quality)
-  { 
-    if(label.size()) _labels[tag] = std::pair<std::string, int>(label, quality); 
-  }
-  // get the label associated with a tag
-  std::string getLabel(int tag){ return _labels[tag].first; }
 };
 
 VisibilityList *VisibilityList::_instance = 0;
@@ -501,7 +480,7 @@ static void _add_physical_group(int dim, int num, std::vector<GEntity*> &ge,
 {
   if(ge.empty()) return;
   std::string name = ge[0]->model()->getPhysicalName(dim, num);
-  if(name.empty() && oldLabels.count(num)) name = oldLabels[num];
+  if(name.empty()) name = oldLabels[num];
   if(name.size()) name = std::string(" <<") + name + ">>";
 
   Fl_Tree_Item *n;
@@ -597,8 +576,9 @@ static void _rebuild_tree_browser(bool force)
 #if defined(HAVE_PARSER)
     for(std::map<std::string, std::vector<double> >::iterator it = gmsh_yysymbols.begin();
         it != gmsh_yysymbols.end(); ++it)
-      for(unsigned int i = 0; i < it->second.size(); i++)
-        oldLabels[(int)it->second[i]] = it->first;
+      if(it->first.size())
+        for(unsigned int i = 0; i < it->second.size(); i++)
+          oldLabels[(int)it->second[i]] = std::string("(") + it->first + ")";
 #endif
     for(int i = 3; i >= 0; i--)
       for(std::map<int, std::vector<GEntity*> >::iterator it = groups[i].begin();
diff --git a/Geo/GModel.cpp b/Geo/GModel.cpp
index aece6243d61ad8273b053746bf05867abac807af..dbbb41910bfaa2d676f9ae36f62e9a289dd0d216 100644
--- a/Geo/GModel.cpp
+++ b/Geo/GModel.cpp
@@ -384,6 +384,13 @@ int GModel::getPhysicalNumber(const int &dim, const std::string &name)
   return -1;
 }
 
+std::string GModel::getElementaryName(int dim, int number)
+{
+  if(elementaryNames.count(std::pair<int, int>(dim, number)))
+    return elementaryNames[std::pair<int, int>(dim, number)];
+  return "";
+}
+
 void GModel::setSelection(int val)
 {
   std::vector<GEntity*> entities;
diff --git a/Geo/GModel.h b/Geo/GModel.h
index 5604637ad5ace8a90f6846ad6cbd6834807d2c8a..4e85fb499e2002191957b21fe8b51523a54de50d 100644
--- a/Geo/GModel.h
+++ b/Geo/GModel.h
@@ -244,6 +244,10 @@ class GModel
   // "dim" and name "name". return -1 if not found
   int getPhysicalNumber(const int &dim, const std::string & name);
 
+  // get the name (if any) of a given elementary entity of dimension
+  // "dim" and id number "num"
+  std::string getElementaryName(int dim, int num);
+
   // set the selection flag on all entities
   void setSelection(int val);
 
diff --git a/Geo/GModelIO_MED.cpp b/Geo/GModelIO_MED.cpp
index 3c389208c145dd1cc5d25cf1b5101d8d8934e0d2..f8f2d5cdee8ccbe8d1cd407bc5b04a00440b2663 100644
--- a/Geo/GModelIO_MED.cpp
+++ b/Geo/GModelIO_MED.cpp
@@ -306,14 +306,15 @@ int GModel::readMED(const std::string &name, int meshIndex)
       Msg::Error("Could not read info for MED family %d", i + 1);
     }
     else{
-      elementaryNames[std::pair<int, int>(-1, -familyNum)] = familyName;
-      if(numGroups > 0){
-        GEntity *ge; // family tags are unique (for all dimensions)
-        if((ge = getRegionByTag(-familyNum))){}
-        else if((ge = getFaceByTag(-familyNum))){}
-        else if((ge = getEdgeByTag(-familyNum))){}
-        else ge = getVertexByTag(-familyNum);
-        if(ge){
+      // family tags are unique (for all dimensions)
+      GEntity *ge;
+      if((ge = getRegionByTag(-familyNum))){}
+      else if((ge = getFaceByTag(-familyNum))){}
+      else if((ge = getEdgeByTag(-familyNum))){}
+      else ge = getVertexByTag(-familyNum);
+      if(ge){      
+        elementaryNames[std::pair<int, int>(ge->dim(), -familyNum)] = familyName;
+        if(numGroups > 0){
           for(int j = 0; j < numGroups; j++) {
             char tmp[MED_TAILLE_LNOM + 1];
             strncpy(tmp, &groupNames[j * MED_TAILLE_LNOM], MED_TAILLE_LNOM);