Program: 1821
Project: 1821
Buggy source:
/** 
 * This version of play() is called with the entire set of start/end values. The implementation in Transition iterates through these lists and calls   {@link #play(ViewGroup,TransitionValues,TransitionValues)}with each set of start/end values on this transition. The TransitionGroup subclass overrides this method and delegates it to each of its children in succession.
 * @hide
 */
protected void play(ViewGroup sceneRoot,TransitionValuesMaps startValues,TransitionValuesMaps endValues){
  mPlayStartValuesList.clear();
  mPlayEndValuesList.clear();
  ArrayMap<View,TransitionValues> endCopy=new ArrayMap<View,TransitionValues>(endValues.viewValues);
  SparseArray<TransitionValues> endIdCopy=new SparseArray<TransitionValues>(endValues.idValues.size());
  for (int i=0; i < endValues.idValues.size(); ++i) {
    int id=endValues.idValues.keyAt(i);
    endIdCopy.put(id,endValues.idValues.valueAt(i));
  }
  LongSparseArray<TransitionValues> endItemIdCopy=new LongSparseArray<TransitionValues>(endValues.itemIdValues.size());
  for (int i=0; i < endValues.itemIdValues.size(); ++i) {
    long id=endValues.itemIdValues.keyAt(i);
    endItemIdCopy.put(id,endValues.itemIdValues.valueAt(i));
  }
  ArrayList<TransitionValues> startValuesList=new ArrayList<TransitionValues>();
  ArrayList<TransitionValues> endValuesList=new ArrayList<TransitionValues>();
  for (  View view : startValues.viewValues.keySet()) {
    TransitionValues start=null;
    TransitionValues end=null;
    boolean isInListView=false;
    if (view.getParent() instanceof ListView) {
      isInListView=true;
    }
    if (!isInListView) {
      int id=view.getId();
      start=startValues.viewValues.get(view) != null ? startValues.viewValues.get(view) : startValues.idValues.get(id);
      if (endValues.viewValues.get(view) != null) {
        end=endValues.viewValues.get(view);
        endCopy.remove(view);
      }
 else {
        end=endValues.idValues.get(id);
        View removeView=null;
        for (        View viewToRemove : endCopy.keySet()) {
          if (viewToRemove.getId() == id) {
            removeView=viewToRemove;
          }
        }
        if (removeView != null) {
          endCopy.remove(removeView);
        }
      }
      endIdCopy.remove(id);
      if (isValidTarget(view,id)) {
        startValuesList.add(start);
        endValuesList.add(end);
      }
    }
 else {
      ListView parent=(ListView)view.getParent();
      if (parent.getAdapter().hasStableIds()) {
        int position=parent.getPositionForView(view);
        long itemId=parent.getItemIdAtPosition(position);
        start=startValues.itemIdValues.get(itemId);
        endItemIdCopy.remove(itemId);
        startValuesList.add(start);
        endValuesList.add(end);
      }
    }
  }
  int startItemIdCopySize=startValues.itemIdValues.size();
  for (int i=0; i < startItemIdCopySize; ++i) {
    long id=startValues.itemIdValues.keyAt(i);
    if (isValidTarget(null,id)) {
      TransitionValues start=startValues.itemIdValues.get(id);
      TransitionValues end=endValues.itemIdValues.get(id);
      endItemIdCopy.remove(id);
      startValuesList.add(start);
      endValuesList.add(end);
    }
  }
  for (  View view : endCopy.keySet()) {
    int id=view.getId();
    if (isValidTarget(view,id)) {
      TransitionValues start=startValues.viewValues.get(view) != null ? startValues.viewValues.get(view) : startValues.idValues.get(id);
      TransitionValues end=endCopy.get(view);
      endIdCopy.remove(id);
      startValuesList.add(start);
      endValuesList.add(end);
    }
  }
  int endIdCopySize=endIdCopy.size();
  for (int i=0; i < endIdCopySize; ++i) {
    int id=endIdCopy.keyAt(i);
    if (isValidTarget(null,id)) {
      TransitionValues start=startValues.idValues.get(id);
      TransitionValues end=endIdCopy.get(id);
      startValuesList.add(start);
      endValuesList.add(end);
    }
  }
  int endItemIdCopySize=endItemIdCopy.size();
  for (int i=0; i < endItemIdCopySize; ++i) {
    long id=endItemIdCopy.keyAt(i);
    TransitionValues start=startValues.itemIdValues.get(id);
    TransitionValues end=endItemIdCopy.get(id);
    startValuesList.add(start);
    endValuesList.add(end);
  }
  for (int i=0; i < startValuesList.size(); ++i) {
    TransitionValues start=startValuesList.get(i);
    TransitionValues end=endValuesList.get(i);
    Animator animator=play(sceneRoot,start,end);
    if (animator != null) {
      mAnimatorMap.put(new Pair(start,end),animator);
      mPlayStartValuesList.add(start);
      mPlayEndValuesList.add(end);
    }
  }
}

Fixed version (ground truth):
/** 
 * This version of play() is called with the entire set of start/end values. The implementation in Transition iterates through these lists and calls   {@link #play(ViewGroup,TransitionValues,TransitionValues)}with each set of start/end values on this transition. The TransitionGroup subclass overrides this method and delegates it to each of its children in succession.
 * @hide
 */
protected void play(ViewGroup sceneRoot,TransitionValuesMaps startValues,TransitionValuesMaps endValues){
  if (DBG) {
    Log.d(LOG_TAG,"String_Node_Str" + this);
  }
  mPlayStartValuesList.clear();
  mPlayEndValuesList.clear();
  ArrayMap<View,TransitionValues> endCopy=new ArrayMap<View,TransitionValues>(endValues.viewValues);
  SparseArray<TransitionValues> endIdCopy=new SparseArray<TransitionValues>(endValues.idValues.size());
  for (int i=0; i < endValues.idValues.size(); ++i) {
    int id=endValues.idValues.keyAt(i);
    endIdCopy.put(id,endValues.idValues.valueAt(i));
  }
  LongSparseArray<TransitionValues> endItemIdCopy=new LongSparseArray<TransitionValues>(endValues.itemIdValues.size());
  for (int i=0; i < endValues.itemIdValues.size(); ++i) {
    long id=endValues.itemIdValues.keyAt(i);
    endItemIdCopy.put(id,endValues.itemIdValues.valueAt(i));
  }
  ArrayList<TransitionValues> startValuesList=new ArrayList<TransitionValues>();
  ArrayList<TransitionValues> endValuesList=new ArrayList<TransitionValues>();
  for (  View view : startValues.viewValues.keySet()) {
    TransitionValues start=null;
    TransitionValues end=null;
    boolean isInListView=false;
    if (view.getParent() instanceof ListView) {
      isInListView=true;
    }
    if (!isInListView) {
      int id=view.getId();
      start=startValues.viewValues.get(view) != null ? startValues.viewValues.get(view) : startValues.idValues.get(id);
      if (endValues.viewValues.get(view) != null) {
        end=endValues.viewValues.get(view);
        endCopy.remove(view);
      }
 else {
        end=endValues.idValues.get(id);
        View removeView=null;
        for (        View viewToRemove : endCopy.keySet()) {
          if (viewToRemove.getId() == id) {
            removeView=viewToRemove;
          }
        }
        if (removeView != null) {
          endCopy.remove(removeView);
        }
      }
      endIdCopy.remove(id);
      if (isValidTarget(view,id)) {
        startValuesList.add(start);
        endValuesList.add(end);
      }
    }
 else {
      ListView parent=(ListView)view.getParent();
      if (parent.getAdapter().hasStableIds()) {
        int position=parent.getPositionForView(view);
        long itemId=parent.getItemIdAtPosition(position);
        start=startValues.itemIdValues.get(itemId);
        endItemIdCopy.remove(itemId);
        startValuesList.add(start);
        endValuesList.add(end);
      }
    }
  }
  int startItemIdCopySize=startValues.itemIdValues.size();
  for (int i=0; i < startItemIdCopySize; ++i) {
    long id=startValues.itemIdValues.keyAt(i);
    if (isValidTarget(null,id)) {
      TransitionValues start=startValues.itemIdValues.get(id);
      TransitionValues end=endValues.itemIdValues.get(id);
      endItemIdCopy.remove(id);
      startValuesList.add(start);
      endValuesList.add(end);
    }
  }
  for (  View view : endCopy.keySet()) {
    int id=view.getId();
    if (isValidTarget(view,id)) {
      TransitionValues start=startValues.viewValues.get(view) != null ? startValues.viewValues.get(view) : startValues.idValues.get(id);
      TransitionValues end=endCopy.get(view);
      endIdCopy.remove(id);
      startValuesList.add(start);
      endValuesList.add(end);
    }
  }
  int endIdCopySize=endIdCopy.size();
  for (int i=0; i < endIdCopySize; ++i) {
    int id=endIdCopy.keyAt(i);
    if (isValidTarget(null,id)) {
      TransitionValues start=startValues.idValues.get(id);
      TransitionValues end=endIdCopy.get(id);
      startValuesList.add(start);
      endValuesList.add(end);
    }
  }
  int endItemIdCopySize=endItemIdCopy.size();
  for (int i=0; i < endItemIdCopySize; ++i) {
    long id=endItemIdCopy.keyAt(i);
    TransitionValues start=startValues.itemIdValues.get(id);
    TransitionValues end=endItemIdCopy.get(id);
    startValuesList.add(start);
    endValuesList.add(end);
  }
  for (int i=0; i < startValuesList.size(); ++i) {
    TransitionValues start=startValuesList.get(i);
    TransitionValues end=endValuesList.get(i);
    if (start != null || end != null) {
      if (start == null || !start.equals(end)) {
        if (DBG) {
          View view=(end != null) ? end.view : start.view;
          Log.d(LOG_TAG,"String_Node_Str" + view);
          if (start == null || end == null) {
            if (start == null) {
              Log.d(LOG_TAG,"String_Node_Str" + ((start == null) ? "String_Node_Str" : "String_Node_Str"));
            }
          }
 else {
            for (            String key : start.values.keySet()) {
              Object startValue=start.values.get(key);
              Object endValue=end.values.get(key);
              if (startValue != endValue && !startValue.equals(endValue)) {
                Log.d(LOG_TAG,"String_Node_Str" + key + "String_Node_Str"+ startValue+ "String_Node_Str"+ endValue+ "String_Node_Str");
              }
            }
          }
        }
        Animator animator=play(sceneRoot,start,end);
        if (animator != null) {
          mAnimatorMap.put(new Pair(start,end),animator);
          mPlayStartValuesList.add(start);
          mPlayEndValuesList.add(end);
        }
      }
 else       if (DBG) {
        View view=(end != null) ? end.view : start.view;
        Log.d(LOG_TAG,"String_Node_Str" + view);
      }
    }
  }
}