private void checkTimelinesUsage(TrackEntry entry) {
   IntSet propertyIDs = this.propertyIDs;
   int n = entry.animation.timelines.size;
   Object[] timelines = entry.animation.timelines.items;
   boolean[] usage = entry.timelinesFirst.setSize(n);
   for (int i = 0; i < n; i++)
     usage[i] = propertyIDs.add(((Timeline) timelines[i]).getPropertyId());
 }
 /**
  * From last to first mixingFrom entries, sets timelinesFirst to true on last, calls
  * checkTimelineUsage on rest.
  */
 private void setTimelinesFirst(TrackEntry entry) {
   if (entry.mixingFrom != null) {
     setTimelinesFirst(entry.mixingFrom);
     checkTimelinesUsage(entry);
     return;
   }
   IntSet propertyIDs = this.propertyIDs;
   int n = entry.animation.timelines.size;
   Object[] timelines = entry.animation.timelines.items;
   boolean[] usage = entry.timelinesFirst.setSize(n);
   for (int i = 0; i < n; i++) {
     propertyIDs.add(((Timeline) timelines[i]).getPropertyId());
     usage[i] = true;
   }
 }
  private void animationsChanged() {
    animationsChanged = false;

    IntSet propertyIDs = this.propertyIDs;

    // Set timelinesFirst for all entries, from lowest track to highest.
    int i = 0, n = tracks.size;
    propertyIDs.clear();
    for (; i < n; i++) { // Find first non-null entry.
      TrackEntry entry = tracks.get(i);
      if (entry == null) continue;
      setTimelinesFirst(entry);
      i++;
      break;
    }
    for (; i < n; i++) { // Rest of entries.
      TrackEntry entry = tracks.get(i);
      if (entry != null) checkTimelinesFirst(entry);
    }
  }