@Override
  public View getView(int position, View convertView, ViewGroup parent) {
    if ((mRowInfo == null) || (position > mRowInfo.size())) {
      // If we have no row info, mAgendaAdapter returns the view.
      return mAgendaAdapter.getView(position, convertView, parent);
    }

    RowInfo row = mRowInfo.get(position);
    if (row.mType == TYPE_DAY) {
      ViewHolder holder = null;
      View agendaDayView = null;
      if ((convertView != null) && (convertView.getTag() != null)) {
        // Listview may get confused and pass in a different type of
        // view since we keep shifting data around. Not a big problem.
        Object tag = convertView.getTag();
        if (tag instanceof ViewHolder) {
          agendaDayView = convertView;
          holder = (ViewHolder) tag;
          holder.julianDay = row.mDay;
        }
      }

      if (holder == null) {
        // Create a new AgendaView with a ViewHolder for fast access to
        // views w/o calling findViewById()
        holder = new ViewHolder();
        agendaDayView = mInflater.inflate(R.layout.agenda_day, parent, false);
        holder.dayView = (TextView) agendaDayView.findViewById(R.id.day);
        holder.dateView = (TextView) agendaDayView.findViewById(R.id.date);
        holder.julianDay = row.mDay;
        holder.grayed = false;
        agendaDayView.setTag(holder);
      }

      // Re-use the member variable "mTime" which is set to the local
      // time zone.
      // It's difficult to find and update all these adapters when the
      // home tz changes so check it here and update if needed.
      String tz = Utils.getTimeZone(mContext, mTZUpdater);
      if (!TextUtils.equals(tz, mTmpTime.timezone)) {
        mTimeZone = tz;
        mTmpTime = new Time(tz);
      }

      // Build the text for the day of the week.
      // Should be yesterday/today/tomorrow (if applicable) + day of the week

      Time date = mTmpTime;
      long millis = date.setJulianDay(row.mDay);
      int flags = DateUtils.FORMAT_SHOW_WEEKDAY;
      mStringBuilder.setLength(0);

      String dayViewText = Utils.getDayOfWeekString(row.mDay, mTodayJulianDay, millis, mContext);

      // Build text for the date
      // Format should be month day

      mStringBuilder.setLength(0);
      flags = DateUtils.FORMAT_SHOW_DATE;
      String dateViewText =
          DateUtils.formatDateRange(mContext, mFormatter, millis, millis, flags, mTimeZone)
              .toString();

      if (AgendaWindowAdapter.BASICLOG) {
        dayViewText += " P:" + position;
        dateViewText += " P:" + position;
      }
      holder.dayView.setText(dayViewText);
      holder.dateView.setText(dateViewText);

      // Set the background of the view, it is grayed for day that are in the past and today
      if (row.mDay > mTodayJulianDay) {
        agendaDayView.setBackgroundResource(R.drawable.agenda_item_bg_primary);
        holder.grayed = false;
      } else {
        agendaDayView.setBackgroundResource(R.drawable.agenda_item_bg_secondary);
        holder.grayed = true;
      }
      return agendaDayView;
    } else if (row.mType == TYPE_MEETING) {
      View itemView = mAgendaAdapter.getView(row.mPosition, convertView, parent);
      AgendaAdapter.ViewHolder holder = ((AgendaAdapter.ViewHolder) itemView.getTag());
      TextView title = holder.title;
      // The holder in the view stores information from the cursor, but the cursor has no
      // notion of multi-day event and the start time of each instance of a multi-day event
      // is the same.  RowInfo has the correct info , so take it from there.
      holder.startTimeMilli = row.mEventStartTimeMilli;
      boolean allDay = holder.allDay;
      if (AgendaWindowAdapter.BASICLOG) {
        title.setText(title.getText() + " P:" + position);
      } else {
        title.setText(title.getText());
      }

      // if event in the past or started already, un-bold the title and set the background
      if ((!allDay && row.mEventStartTimeMilli <= System.currentTimeMillis())
          || (allDay && row.mDay <= mTodayJulianDay)) {
        itemView.setBackgroundResource(R.drawable.agenda_item_bg_secondary);
        title.setTypeface(Typeface.DEFAULT);
        holder.grayed = true;
      } else {
        itemView.setBackgroundResource(R.drawable.agenda_item_bg_primary);
        title.setTypeface(Typeface.DEFAULT_BOLD);
        holder.grayed = false;
      }
      holder.julianDay = row.mDay;
      return itemView;
    } else {
      // Error
      throw new IllegalStateException("Unknown event type:" + row.mType);
    }
  }