Program: 54125
Project: 54125
Buggy source:
@Override public Animator createAnimator(final ViewGroup sceneRoot,TransitionValues startValues,TransitionValues endValues){
  if (startValues == null || endValues == null) {
    return null;
  }
  if (sRectEvaluator == null) {
    sRectEvaluator=new RectEvaluator();
  }
  Map<String,Object> startParentVals=startValues.values;
  Map<String,Object> endParentVals=endValues.values;
  ViewGroup startParent=(ViewGroup)startParentVals.get(PROPNAME_PARENT);
  ViewGroup endParent=(ViewGroup)endParentVals.get(PROPNAME_PARENT);
  if (startParent == null || endParent == null) {
    return null;
  }
  final View view=endValues.view;
  if (parentMatches(startParent,endParent)) {
    Rect startBounds=(Rect)startValues.values.get(PROPNAME_BOUNDS);
    Rect endBounds=(Rect)endValues.values.get(PROPNAME_BOUNDS);
    final int startLeft=startBounds.left;
    final int endLeft=endBounds.left;
    final int startTop=startBounds.top;
    final int endTop=endBounds.top;
    final int startRight=startBounds.right;
    final int endRight=endBounds.right;
    final int startBottom=startBounds.bottom;
    final int endBottom=endBounds.bottom;
    final int startWidth=startRight - startLeft;
    final int startHeight=startBottom - startTop;
    final int endWidth=endRight - endLeft;
    final int endHeight=endBottom - endTop;
    Rect startClip=(Rect)startValues.values.get(PROPNAME_CLIP);
    Rect endClip=(Rect)endValues.values.get(PROPNAME_CLIP);
    int numChanges=0;
    if ((startWidth != 0 && startHeight != 0) || (endWidth != 0 && endHeight != 0)) {
      if (startLeft != endLeft || startTop != endTop)       ++numChanges;
      if (startRight != endRight || startBottom != endBottom)       ++numChanges;
    }
    if ((startClip != null && !startClip.equals(endClip)) || (startClip == null && endClip != null)) {
      ++numChanges;
    }
    if (numChanges > 0) {
      Animator anim;
      if (!mResizeClip || (startClip == null && endClip == null)) {
        ViewUtils.setLeftTopRightBottom(view,startLeft,startTop,startRight,startBottom);
        if (numChanges == 2) {
          if (startWidth == endWidth && startHeight == endHeight) {
            anim=AnimatorUtils.ofPointF(view,POSITION_PROPERTY,getPathMotion(),startLeft,startTop,endLeft,endTop);
          }
 else {
            ViewBounds viewBounds=new ViewBounds(view);
            Animator topLeftAnimator=AnimatorUtils.ofPointF(viewBounds,TOP_LEFT_PROPERTY,getPathMotion(),startLeft,startTop,endLeft,endTop);
            Animator bottomRightAnimator=AnimatorUtils.ofPointF(viewBounds,BOTTOM_RIGHT_PROPERTY,getPathMotion(),startRight,startBottom,endRight,endBottom);
            AnimatorSet set=new AnimatorSet();
            set.playTogether(topLeftAnimator,bottomRightAnimator);
            set.addListener(viewBounds);
            anim=set;
          }
        }
 else         if (startLeft != endLeft || startTop != endTop) {
          anim=AnimatorUtils.ofPointF(view,TOP_LEFT_ONLY_PROPERTY,getPathMotion(),startLeft,startTop,endLeft,endTop);
        }
 else {
          anim=AnimatorUtils.ofPointF(view,BOTTOM_RIGHT_ONLY_PROPERTY,getPathMotion(),startRight,startBottom,endRight,endBottom);
        }
      }
 else {
        int maxWidth=Math.max(startWidth,endWidth);
        int maxHeight=Math.max(startHeight,endHeight);
        ViewUtils.setLeftTopRightBottom(view,startLeft,startTop,startLeft + maxWidth,startTop + maxHeight);
        Animator positionAnimator=null;
        if (startLeft != endLeft || startTop != endTop) {
          positionAnimator=AnimatorUtils.ofPointF(view,POSITION_PROPERTY,getPathMotion(),startLeft,startTop,endLeft,endTop);
        }
        final Rect finalClip=endClip;
        if (startClip == null) {
          startClip=new Rect(0,0,startWidth,startHeight);
        }
        if (endClip == null) {
          endClip=new Rect(0,0,endWidth,endHeight);
        }
        ObjectAnimator clipAnimator=null;
        if (!startClip.equals(endClip)) {
          ViewUtils.setClipBounds(view,startClip);
          clipAnimator=ObjectAnimator.ofObject(view,"String_Node_Str",sRectEvaluator,startClip,endClip);
          clipAnimator.addListener(new AnimatorListenerAdapter(){
            private boolean mIsCanceled;
            @Override public void onAnimationCancel(            Animator animation){
              mIsCanceled=true;
            }
            @Override public void onAnimationEnd(            Animator animation){
              if (!mIsCanceled) {
                ViewUtils.setClipBounds(view,finalClip);
                ViewUtils.setLeftTopRightBottom(view,endLeft,endTop,endRight,endBottom);
              }
            }
          }
);
        }
        anim=TransitionUtils.mergeAnimators(positionAnimator,clipAnimator);
      }
      if (view.getParent() instanceof ViewGroup) {
        final ViewGroup parent=(ViewGroup)view.getParent();
        ViewGroupUtils.suppressLayout(parent,true);
        TransitionListener transitionListener=new TransitionListenerAdapter(){
          boolean mCanceled=false;
          @Override public void onTransitionCancel(          Transition transition){
            ViewGroupUtils.suppressLayout(parent,false);
            mCanceled=true;
          }
          @Override public void onTransitionEnd(          Transition transition){
            if (!mCanceled) {
              ViewGroupUtils.suppressLayout(parent,false);
            }
          }
          @Override public void onTransitionPause(          Transition transition){
            ViewGroupUtils.suppressLayout(parent,false);
          }
          @Override public void onTransitionResume(          Transition transition){
            ViewGroupUtils.suppressLayout(parent,true);
          }
        }
;
        addListener(transitionListener);
      }
      return anim;
    }
  }
 else {
    int startX=(Integer)startValues.values.get(PROPNAME_WINDOW_X);
    int startY=(Integer)startValues.values.get(PROPNAME_WINDOW_Y);
    int endX=(Integer)endValues.values.get(PROPNAME_WINDOW_X);
    int endY=(Integer)endValues.values.get(PROPNAME_WINDOW_Y);
    if (startX != endX || startY != endY) {
      sceneRoot.getLocationInWindow(tempLocation);
      Bitmap bitmap=Bitmap.createBitmap(view.getWidth(),view.getHeight(),Bitmap.Config.ARGB_8888);
      Canvas canvas=new Canvas(bitmap);
      view.draw(canvas);
      final BitmapDrawable drawable=new BitmapDrawable(sceneRoot.getContext().getResources(),bitmap);
      Animator anim;
      anim=AnimatorUtils.ofPointF(drawable,DRAWABLE_ORIGIN_PROPERTY,getPathMotion(),startX - tempLocation[0],startY - tempLocation[1],endX - tempLocation[0],endY - tempLocation[1]);
      if (anim != null) {
        final float transitionAlpha=ViewUtils.getTransitionAlpha(view);
        ViewUtils.setTransitionAlpha(view,0);
        ViewOverlayUtils.addOverlay(sceneRoot,drawable);
        anim.addListener(new AnimatorListenerAdapter(){
          @Override public void onAnimationEnd(          Animator animation){
            ViewOverlayUtils.removeOverlay(sceneRoot,drawable);
            ViewUtils.setTransitionAlpha(view,transitionAlpha);
          }
        }
);
      }
      return anim;
    }
  }
  return null;
}

Fixed version (ground truth):
@Override public Animator createAnimator(final ViewGroup sceneRoot,TransitionValues startValues,TransitionValues endValues){
  if (startValues == null || endValues == null) {
    return null;
  }
  if (sRectEvaluator == null) {
    sRectEvaluator=new RectEvaluator();
  }
  Map<String,Object> startParentVals=startValues.values;
  Map<String,Object> endParentVals=endValues.values;
  ViewGroup startParent=(ViewGroup)startParentVals.get(PROPNAME_PARENT);
  ViewGroup endParent=(ViewGroup)endParentVals.get(PROPNAME_PARENT);
  if (startParent == null || endParent == null) {
    return null;
  }
  final View view=endValues.view;
  if (parentMatches(startParent,endParent)) {
    Rect startBounds=(Rect)startValues.values.get(PROPNAME_BOUNDS);
    Rect endBounds=(Rect)endValues.values.get(PROPNAME_BOUNDS);
    final int startLeft=startBounds.left;
    final int endLeft=endBounds.left;
    final int startTop=startBounds.top;
    final int endTop=endBounds.top;
    final int startRight=startBounds.right;
    final int endRight=endBounds.right;
    final int startBottom=startBounds.bottom;
    final int endBottom=endBounds.bottom;
    final int startWidth=startRight - startLeft;
    final int startHeight=startBottom - startTop;
    final int endWidth=endRight - endLeft;
    final int endHeight=endBottom - endTop;
    Rect startClip=(Rect)startValues.values.get(PROPNAME_CLIP);
    Rect endClip=(Rect)endValues.values.get(PROPNAME_CLIP);
    int numChanges=0;
    if ((startWidth != 0 && startHeight != 0) || (endWidth != 0 && endHeight != 0)) {
      if (startLeft != endLeft || startTop != endTop)       ++numChanges;
      if (startRight != endRight || startBottom != endBottom)       ++numChanges;
    }
    if ((startClip != null && !startClip.equals(endClip)) || (startClip == null && endClip != null)) {
      ++numChanges;
    }
    if (numChanges > 0) {
      Animator anim;
      if (!mResizeClip || (startClip == null && endClip == null)) {
        ViewUtils.setLeftTopRightBottom(view,startLeft,startTop,startRight,startBottom);
        if (numChanges == 2) {
          if (startWidth == endWidth && startHeight == endHeight) {
            anim=AnimatorUtils.ofPointF(view,POSITION_PROPERTY,getPathMotion(),startLeft,startTop,endLeft,endTop);
          }
 else {
            ViewBounds viewBounds=new ViewBounds(view);
            Animator topLeftAnimator=AnimatorUtils.ofPointF(viewBounds,TOP_LEFT_PROPERTY,getPathMotion(),startLeft,startTop,endLeft,endTop);
            Animator bottomRightAnimator=AnimatorUtils.ofPointF(viewBounds,BOTTOM_RIGHT_PROPERTY,getPathMotion(),startRight,startBottom,endRight,endBottom);
            AnimatorSet set=new AnimatorSet();
            set.playTogether(topLeftAnimator,bottomRightAnimator);
            set.addListener(viewBounds);
            anim=set;
          }
        }
 else         if (startLeft != endLeft || startTop != endTop) {
          anim=AnimatorUtils.ofPointF(view,TOP_LEFT_ONLY_PROPERTY,getPathMotion(),startLeft,startTop,endLeft,endTop);
        }
 else {
          anim=AnimatorUtils.ofPointF(view,BOTTOM_RIGHT_ONLY_PROPERTY,getPathMotion(),startRight,startBottom,endRight,endBottom);
        }
      }
 else {
        int maxWidth=Math.max(startWidth,endWidth);
        int maxHeight=Math.max(startHeight,endHeight);
        ViewUtils.setLeftTopRightBottom(view,startLeft,startTop,startLeft + maxWidth,startTop + maxHeight);
        Animator positionAnimator=null;
        if (startLeft != endLeft || startTop != endTop) {
          positionAnimator=AnimatorUtils.ofPointF(view,POSITION_PROPERTY,getPathMotion(),startLeft,startTop,endLeft,endTop);
        }
        final Rect finalClip=endClip;
        if (startClip == null) {
          startClip=new Rect(0,0,startWidth,startHeight);
        }
        if (endClip == null) {
          endClip=new Rect(0,0,endWidth,endHeight);
        }
        ObjectAnimator clipAnimator=null;
        if (!startClip.equals(endClip)) {
          ViewUtils.setClipBounds(view,startClip);
          clipAnimator=ObjectAnimator.ofObject(view,ChangeClipBounds.VIEW_CLIP_BOUNDS,sRectEvaluator,startClip,endClip);
          clipAnimator.addListener(new AnimatorListenerAdapter(){
            private boolean mIsCanceled;
            @Override public void onAnimationCancel(            Animator animation){
              mIsCanceled=true;
            }
            @Override public void onAnimationEnd(            Animator animation){
              if (!mIsCanceled) {
                ViewUtils.setClipBounds(view,finalClip);
                ViewUtils.setLeftTopRightBottom(view,endLeft,endTop,endRight,endBottom);
              }
            }
          }
);
        }
        anim=TransitionUtils.mergeAnimators(positionAnimator,clipAnimator);
      }
      if (view.getParent() instanceof ViewGroup) {
        final ViewGroup parent=(ViewGroup)view.getParent();
        ViewGroupUtils.suppressLayout(parent,true);
        TransitionListener transitionListener=new TransitionListenerAdapter(){
          boolean mCanceled=false;
          @Override public void onTransitionCancel(          Transition transition){
            ViewGroupUtils.suppressLayout(parent,false);
            mCanceled=true;
          }
          @Override public void onTransitionEnd(          Transition transition){
            if (!mCanceled) {
              ViewGroupUtils.suppressLayout(parent,false);
            }
          }
          @Override public void onTransitionPause(          Transition transition){
            ViewGroupUtils.suppressLayout(parent,false);
          }
          @Override public void onTransitionResume(          Transition transition){
            ViewGroupUtils.suppressLayout(parent,true);
          }
        }
;
        addListener(transitionListener);
      }
      return anim;
    }
  }
 else {
    int startX=(Integer)startValues.values.get(PROPNAME_WINDOW_X);
    int startY=(Integer)startValues.values.get(PROPNAME_WINDOW_Y);
    int endX=(Integer)endValues.values.get(PROPNAME_WINDOW_X);
    int endY=(Integer)endValues.values.get(PROPNAME_WINDOW_Y);
    if (startX != endX || startY != endY) {
      sceneRoot.getLocationInWindow(tempLocation);
      Bitmap bitmap=Bitmap.createBitmap(view.getWidth(),view.getHeight(),Bitmap.Config.ARGB_8888);
      Canvas canvas=new Canvas(bitmap);
      view.draw(canvas);
      final BitmapDrawable drawable=new BitmapDrawable(sceneRoot.getContext().getResources(),bitmap);
      Animator anim;
      anim=AnimatorUtils.ofPointF(drawable,DRAWABLE_ORIGIN_PROPERTY,getPathMotion(),startX - tempLocation[0],startY - tempLocation[1],endX - tempLocation[0],endY - tempLocation[1]);
      if (anim != null) {
        final float transitionAlpha=ViewUtils.getTransitionAlpha(view);
        ViewUtils.setTransitionAlpha(view,0);
        ViewOverlayUtils.addOverlay(sceneRoot,drawable);
        anim.addListener(new AnimatorListenerAdapter(){
          @Override public void onAnimationEnd(          Animator animation){
            ViewOverlayUtils.removeOverlay(sceneRoot,drawable);
            ViewUtils.setTransitionAlpha(view,transitionAlpha);
          }
        }
);
      }
      return anim;
    }
  }
  return null;
}