@Override
 public int getItemViewType(int position) {
   Object currentObject = dataSet.get(position);
   if (currentObject instanceof Campaign) {
     if (position == selectedPosition) {
       Campaign camp = (Campaign) currentObject;
       if (TimeUtils.isCampaignExpired(camp)) {
         return V_TYPE_CAMP_EXPANDED_EXPIRED;
       }
       return VIEW_TYPE_CAMPAIGN_EXPANDED;
     } else if (selectedPosition != -1) {
       return VIEW_TYPE_CAMPAIGN_SMALL;
     } else {
       return VIEW_TYPE_CAMPAIGN;
     }
   } else if (currentObject instanceof String) {
     return VIEW_TYPE_CAMPAIGN_FOOTER;
   } else {
     return VIEW_TYPE_REPORT_BACK;
   }
 }
  @Override
  public void onBindViewHolder(final RecyclerView.ViewHolder holder, final int position) {
    if (position == dataSet.size() - 3) {
      campaignAdapterClickListener.onScrolledToBottom();
    }

    Resources resources = holder.itemView.getResources();
    Context context = holder.itemView.getContext();

    if (getItemViewType(position) == VIEW_TYPE_CAMPAIGN) {
      final Campaign campaign = (Campaign) dataSet.get(position);
      CampaignViewHolder campaignViewHolder = (CampaignViewHolder) holder;
      campaignViewHolder.title.setText(campaign.title);

      int height = resources.getDimensionPixelSize(R.dimen.campaign_height);

      CharSequence tag = (CharSequence) campaignViewHolder.imageView.getTag();
      if (!TextUtils.equals(campaign.imagePath, tag)) {
        Picasso.with(context)
            .load(campaign.imagePath)
            .resize(0, height)
            .into(campaignViewHolder.imageView);
        campaignViewHolder.imageView.setTag(campaign.imagePath);
      }

      if (campaign.userIsSignedUp) {
        campaignViewHolder.signedupIndicator.setVisibility(View.VISIBLE);
      } else {
        campaignViewHolder.signedupIndicator.setVisibility(View.GONE);
      }

      campaignViewHolder.root.setOnClickListener(
          new View.OnClickListener() {
            @Override
            public void onClick(View v) {
              selectedPosition = position;
              campaignAdapterClickListener.onCampaignExpanded(position);
              notifyItemChanged(position);
            }
          });

      ColorMatrix cm = new ColorMatrix();
      if (TimeUtils.isCampaignExpired(campaign)) {
        cm.setSaturation(0);
        campaignViewHolder.imageView.setColorFilter(new ColorMatrixColorFilter(cm));
      } else {
        cm.setSaturation(1);
        campaignViewHolder.imageView.setColorFilter(new ColorMatrixColorFilter(cm));
      }
    }
    if (getItemViewType(position) == VIEW_TYPE_CAMPAIGN_SMALL) {
      final Campaign campaign = (Campaign) dataSet.get(position);
      CampaignViewHolder smallCampaignViewHolder = (CampaignViewHolder) holder;
      smallCampaignViewHolder.title.setText(campaign.title);

      int height = resources.getDimensionPixelSize(R.dimen.campaign_small_height);

      CharSequence tag = (CharSequence) smallCampaignViewHolder.imageView.getTag();
      if (!TextUtils.equals(campaign.imagePath, tag)) {
        Picasso.with(context)
            .load(campaign.imagePath)
            .resize(0, height)
            .into(smallCampaignViewHolder.imageView);
        smallCampaignViewHolder.imageView.setTag(campaign.imagePath);
      }
      smallCampaignViewHolder.root.setOnClickListener(
          new View.OnClickListener() {
            @Override
            public void onClick(View v) {
              selectedPosition = position;
              campaignAdapterClickListener.onCampaignExpanded(position);
              notifyItemChanged(position);
            }
          });

      if (campaign.userIsSignedUp) {
        smallCampaignViewHolder.signedupIndicator.setVisibility(View.VISIBLE);
      } else {
        smallCampaignViewHolder.signedupIndicator.setVisibility(View.GONE);
      }

      ColorMatrix cm = new ColorMatrix();
      if (TimeUtils.isCampaignExpired(campaign)) {
        cm.setSaturation(0);
        smallCampaignViewHolder.imageView.setColorFilter(new ColorMatrixColorFilter(cm));
      } else {
        cm.setSaturation(1);
        smallCampaignViewHolder.imageView.setColorFilter(new ColorMatrixColorFilter(cm));
      }
    } else if (getItemViewType(position) == V_TYPE_CAMP_EXPANDED_EXPIRED) {
      final Campaign campaign = (Campaign) dataSet.get(position);
      final ExpandedExpireCampaignViewHolder viewHolder = (ExpandedExpireCampaignViewHolder) holder;

      viewHolder.title.setText(campaign.title);
      viewHolder.callToAction.setText(campaign.callToAction);

      int height = resources.getDimensionPixelSize(R.dimen.campaign_height_expanded);

      CharSequence tag = (CharSequence) viewHolder.imageView.getTag();

      if (!TextUtils.equals(campaign.imagePath, tag)) {
        Picasso.with(context).load(campaign.imagePath).resize(0, height).into(viewHolder.imageView);
        viewHolder.imageView.setTag(campaign.imagePath);
      }
      viewHolder.imageView.setOnClickListener(
          new View.OnClickListener() {
            @Override
            public void onClick(View v) {
              selectedPosition = -1;
              notifyItemChanged(position);
            }
          });

      final SlantedBackgroundDrawable background =
          new SlantedBackgroundDrawable(
              false, Color.WHITE, shadowColor, slantHeight, widthOvershoot, heightShadowOvershoot);
      viewHolder.slantedBg.setBackground(background);
      viewHolder.refreshCopy.setOnClickListener(
          new View.OnClickListener() {
            @Override
            public void onClick(View v) {
              campaignAdapterClickListener.onNetworkCampaignRefresh();
              // FIXME show progress bar
            }
          });

      ColorMatrix cm = new ColorMatrix();
      cm.setSaturation(0);
      viewHolder.imageView.setColorFilter(new ColorMatrixColorFilter(cm));
    } else if (getItemViewType(position) == VIEW_TYPE_CAMPAIGN_EXPANDED) {
      final Campaign campaign = (Campaign) dataSet.get(position);
      ExpandedCampaignViewHolder viewHolder = (ExpandedCampaignViewHolder) holder;

      viewHolder.title.setText(campaign.title);
      viewHolder.callToAction.setText(campaign.callToAction);

      int height = resources.getDimensionPixelSize(R.dimen.campaign_height_expanded);

      CharSequence tag = (CharSequence) viewHolder.imageView.getTag();

      if (!TextUtils.equals(campaign.imagePath, tag)) {
        Picasso.with(context).load(campaign.imagePath).resize(0, height).into(viewHolder.imageView);
        viewHolder.imageView.setTag(campaign.imagePath);
      }
      viewHolder.imageView.setOnClickListener(
          new View.OnClickListener() {
            @Override
            public void onClick(View v) {
              selectedPosition = -1;
              notifyItemChanged(position);
            }
          });

      if (campaign.userIsSignedUp) {
        viewHolder.signedupIndicator.setVisibility(View.VISIBLE);
        viewHolder.alreadySignedUp.setVisibility(View.VISIBLE);
        viewHolder.notSignedUp.setVisibility(View.GONE);
      } else {
        viewHolder.signedupIndicator.setVisibility(View.GONE);
        viewHolder.alreadySignedUp.setVisibility(View.GONE);
        viewHolder.notSignedUp.setVisibility(View.VISIBLE);
      }

      SlantedBackgroundDrawable background =
          new SlantedBackgroundDrawable(
              false, Color.WHITE, shadowColor, slantHeight, widthOvershoot, heightShadowOvershoot);
      viewHolder.slantedBg.setBackground(background);
      viewHolder.campaignDetailsWrapper.setOnClickListener(
          new View.OnClickListener() {
            @Override
            public void onClick(View v) {
              campaignAdapterClickListener.onCampaignClicked(campaign.id, campaign.userIsSignedUp);
            }
          });

      // If campaign.endTime isn't specified by the server, then don't show the expires label
      if (campaign.endTime == 0) {
        viewHolder.expire_label.setVisibility(View.GONE);
        viewHolder.daysWrapper.setVisibility(View.GONE);
      } else {
        viewHolder.expire_label.setVisibility(View.VISIBLE);
        viewHolder.daysWrapper.setVisibility(View.VISIBLE);

        List<String> campExpTime = TimeUtils.getTimeUntilExpiration(campaign.endTime);
        int dayInt = Integer.parseInt(campExpTime.get(0));
        viewHolder.daysLabel.setText(resources.getQuantityString(R.plurals.days, dayInt));
        viewHolder.days.setText(String.valueOf(dayInt));
      }
    } else if (getItemViewType(position) == VIEW_TYPE_REPORT_BACK) {
      final ReportBack reportBack = (ReportBack) dataSet.get(position);
      ReportBackViewHolder reportBackViewHolder = (ReportBackViewHolder) holder;

      Picasso.with(context).load(reportBack.getImagePath()).into(reportBackViewHolder.root);

      reportBackViewHolder.root.setOnClickListener(
          new View.OnClickListener() {
            @Override
            public void onClick(View v) {
              campaignAdapterClickListener.onReportBackClicked(
                  reportBack.id, reportBack.campaign.id);
            }
          });
    } else if (getItemViewType(position) == VIEW_TYPE_CAMPAIGN_FOOTER) {
      SectionTitleViewHolder sectionTitleViewHolder = (SectionTitleViewHolder) holder;
      sectionTitleViewHolder.textView.setText(resources.getString(R.string.people_doing_stuff));
    }
  }