code: public boolean merge(AbstractTransition another) {
          if (!isCompatible(another)) {
              return false;
          }
          if (another.mId != null) {
              if (mId == null) {
                  mId = another.mId;
              } else {
                  StringBuilder sb = new StringBuilder(mId.length() + another.mId.length());
                  sb.append(mId);
                  sb.append("_MERGED_");
                  sb.append(another.mId);
                  mId = sb.toString();
              }
          }
          mUpdateStateAfterUpdateProgress |= another.mUpdateStateAfterUpdateProgress;
          mSetupList.addAll(another.mSetupList);
          Collections.sort(mSetupList, new Comparator<S>() {
              @Override
              public int compare(S lhs, S rhs) {
                  if (lhs instanceof AbstractTransitionBuilder && rhs instanceof AbstractTransitionBuilder) {
                      AbstractTransitionBuilder left = (AbstractTransitionBuilder) lhs;
                      AbstractTransitionBuilder right = (AbstractTransitionBuilder) rhs;
                      float startLeft = left.mReverse ? left.mEnd : left.mStart;
                      float startRight = right.mReverse ? right.mEnd : right.mStart;
                      return (int) ((startRight - startLeft) * 1000);
                  }
                  return 0;
              }
          });
  
          return true;
      }
docs: Merge another AbstractTransition's states into this object, such that the other AbstractTransition
  can be discarded.
  
  @param another
  @return true if the merge is successful.