@Override
 public boolean apply(Track input) {
   boolean contains = true;
   for (String contId : contIds) {
     contains &= input.getId().contains(contId);
     if (!contains) break;
   }
   return contains;
 }
  /**
   * Test loading a session with a bedtools analysis track
   *
   * @throws Exception
   */
  @Test
  public void testLoadBedtools_Subtract() throws Exception {
    String toolPath = "/usr/local/bin/bedtools";
    boolean haveTool = PluginSpecReader.isToolPathValid(toolPath);
    Assume.assumeTrue(haveTool);

    String sessionPath = TestUtils.DATA_DIR + "sessions/GSM_bedtools_subtract.xml";

    rewriteRestoreSession(sessionPath);

    String trackAname = "GSM1004654_100k.bed";
    String trackBname = "GSM1004654_10k.bed";
    String analId = "BEDTools Remove/Subtract";

    FeatureTrack analTrack = null, trackA = null, trackB = null;
    for (Track track : IGV.getInstance().getAllTracks()) {
      if (track.getId().equals(analId)) {
        analTrack = (FeatureTrack) track;
      } else if (track.getName().equals(trackAname)) {
        trackA = (FeatureTrack) track;
      } else if (track.getName().equals(trackBname)) {
        trackB = (FeatureTrack) track;
      }
    }

    String chr = "chr2";
    int start = 177932002;
    int end = 180561093;

    List<Feature> aFeatures = trackA.getFeatures(chr, start, end);
    List<Feature> bFeatures = trackB.getFeatures(chr, start, end);
    List<Feature> analFeatures = analTrack.getFeatures(chr, start, end);

    // Fairly coarse check, these actually might not exactly be true
    // due to splitting of exons
    int checked = 0;
    for (Feature afeat : analFeatures) {
      if (afeat.getStart() < start || afeat.getStart() > end) continue;
      // This particular feature splits funny, it's not a bug, at least not with IGV
      if (afeat.getStart() == 178625608) continue;

      assertTrue(listContainsFeature(aFeatures, afeat));
      assertFalse(listContainsFeature(bFeatures, afeat));
      checked++;
    }
    assert checked > 0;
  }