private void render() {
   PerfTimer timer = PerfTimer.get(this, "render");
   SafeHtmlBuilder builder = new SafeHtmlBuilder();
   if (data != null) {
     for (Contact c : data) {
       builder.append(
           TEMPLATE.item(
               "",
               AppResources.INSTANCE.css().profilePic(),
               c.getPicURL(),
               AppResources.INSTANCE.css().detailBlock(),
               c.getName(),
               c.getEmail(),
               c.getPhone()));
     }
   } else {
     builder.append(
         TEMPLATE.loading(
             AppResources.INSTANCE.css().loading(),
             AppResources.INSTANCE.loadingImage().getURL(),
             Messages.INSTANCE.listLoading()));
   }
   getElement().setInnerHTML(builder.toSafeHtml().asString());
   timer.end();
 }
 @Override
 public void onBrowserEvent(Event event) {
   PerfTimer timer = PerfTimer.get(this, "onBrowserEvent");
   Element target = Element.as(event.getEventTarget());
   int index = getTargetItemIndex(target);
   if (index != -1) {
     // Don't need to support de-select since there is no gesture modifier
     Element.as(getElement().getChildNodes().getItem(selected))
         .removeClassName(AppResources.INSTANCE.css().selected());
     Element.as(getElement().getChildNodes().getItem(index))
         .addClassName(AppResources.INSTANCE.css().selected());
     SelectionEvent.fire(this, data.get(index));
     this.selected = index;
   }
   timer.end();
 }