/**
   * Overwrites a section of the Part (starting at the specified index) with the Units contained in
   * the given Part. WARNING: DOES NOT WORK IF GIVEN PART WILL EXTEND OVER END OF THIS PART. TODO:
   * Fix this. //rk Maybe I fixed it
   *
   * @param part the Part to paste into this
   * @param index the slot at which to start pasting over
   */
  public void pasteOver(Part part, int index) {
    // Trace.log(3, "pasteOver " + part + " onto " + index);
    int limit = size();
    int incoming = part.size();
    if (index + incoming < limit) {
      limit = index + incoming;
    }

    for (int i = 0, j = index; j < limit; i++, j++) {
      Unit unit = part.getUnit(i);
      if (unit != null) {
        Unit newUnit = unit.copy();
        setUnit(j, newUnit);
      } else {
        setUnit(j, null);
      }
    }
  }
  /**
   * Deletes the unit at the specified index, adjusting the rhythm value of the preceding Unit.
   *
   * @param unitIndex the slot containing the Unit to delete
   */
  public void delUnit(int unitIndex) {
    if (unitIndex < 0) {
      return;
    }
    // FIX: he try-catch is because there is an occasional out-of-range error
    // for the index. This is clearly a hack to avoid being affected by it.
    try {
      Unit unit = slots.get(unitIndex);

      if (unit != null) {
        // Trace.log(0, "delUnit at " + unitIndex + ", was " + unit);

        int rv = unit.getRhythmValue();
        slots.set(unitIndex, null);
        unitCount--;
        Unit prevUnit = getPrevUnit(unitIndex);

        // Trace.log(3, "prevUnit = " + prevUnit);

        // If there was a Unit before it, we need to adjust its rv.

        if (prevUnit != null) {
          // Trace.log(0, "in delUnit, setting rhythmValue");
          prevUnit.setRhythmValue(prevUnit.getRhythmValue() + rv);
        }
        // If there was no Unit before it, then we just deleted the
        // 0 slot, which must never be empty, so put something appropriate there.
        else if (this instanceof imp.data.MelodyPart) {
          setUnit(0, new Rest());
        } else if (this instanceof imp.data.ChordPart) {
          setUnit(0, new Chord(NOCHORD));
        }
      }
    } catch (Exception e) {
    }
  }
  /**
   * Modified from pasteOver for time warping Overwrites a section of the Part (starting at the
   * specified index) with the Units contained in the given Part.
   *
   * @param part the Part to paste into this
   * @param index the slot at which to start pasting over
   */
  public void altPasteOver(Part part, int index) {
    int limit = size();
    int incoming = part.size();
    if (index + incoming < limit) {
      limit = index + incoming;
    }

    // How to prevent long duration last note??

    //   int lastSlot = index + incoming - 1;

    //   setUnit(lastSlot, new Rest());

    for (int i = 0, j = index; j < limit; i++, j++) {
      Unit unit = part.getUnit(i);
      if (unit != null) {
        Unit newUnit = unit.copy();
        int rhythmValue = newUnit.getRhythmValue();
        setUnit(j, newUnit);
      } else {
        setUnit(j, null);
      }
    }
  }
  public void splitUnit(int slotIndex) {
    Unit origSplitUnit = getUnit(slotIndex);

    // check to see if there is a unit to split
    if (origSplitUnit != null) {
      return;
    }

    int prevIndex = getPrevIndex(slotIndex);
    origSplitUnit = getUnit(prevIndex);
    int origRhythmValue = origSplitUnit.getRhythmValue();

    // if previous unit extends into this slot, we need to split it
    if (prevIndex + origRhythmValue >= slotIndex) {
      Unit splitUnit = origSplitUnit.copy();
      splitUnit.setRhythmValue(origRhythmValue + prevIndex - slotIndex);
      setUnit(slotIndex, splitUnit); // this call shortens the original note too
    } else {
      // nothing to split, but if we actually did get here, things would be
      // broken since the slot to split at is null
      // Trace.log(3, "Error: SplitUnitCommand found inconsistencies with the Part");
    }
  }