@Override
  public void write(LineWriter textWriter) {
    textWriter.writeLine(2); // type
    super.write(textWriter);
    textWriter.writeLine(2); // version

    textWriter.writeLine(artistIds.size());
    for (Integer id : artistIds.keySet()) textWriter.writeLine(id);
    textWriter.writeLine(labelIds.size());
    for (Integer id : labelIds.keySet()) textWriter.writeLine(id);
    textWriter.writeLine(releaseIds.size());
    for (Integer id : releaseIds.keySet()) textWriter.writeLine(id);
    textWriter.writeLine(songIds.size());
    for (Integer id : songIds.keySet()) textWriter.writeLine(id);
    textWriter.writeLine(excludeArtistIds.size());
    for (Integer id : excludeArtistIds.keySet()) textWriter.writeLine(id);
    textWriter.writeLine(excludeLabelIds.size());
    for (Integer id : excludeLabelIds.keySet()) textWriter.writeLine(id);
    textWriter.writeLine(excludeReleaseIds.size());
    for (Integer id : excludeReleaseIds.keySet()) textWriter.writeLine(id);
    textWriter.writeLine(excludeSongIds.size());
    for (Integer id : excludeSongIds.keySet()) textWriter.writeLine(id);
    if (artistSearchParameters != null) {
      textWriter.writeLine(artistSearchParameters.length);
      for (ArtistSearchParameters params : artistSearchParameters) params.write(textWriter);
    } else {
      textWriter.writeLine(0);
    }
    if (labelSearchParameters != null) {
      textWriter.writeLine(labelSearchParameters.length);
      for (LabelSearchParameters params : labelSearchParameters) params.write(textWriter);
    } else {
      textWriter.writeLine(0);
    }
    if (releaseSearchParameters != null) {
      textWriter.writeLine(releaseSearchParameters.length);
      for (ReleaseSearchParameters params : releaseSearchParameters) params.write(textWriter);
    } else {
      textWriter.writeLine(0);
    }
    if (songSearchParameters != null) {
      textWriter.writeLine(songSearchParameters.length);
      for (SongSearchParameters params : songSearchParameters) params.write(textWriter);
    } else {
      textWriter.writeLine(0);
    }
  }
 @Override
 public boolean matches(SearchRecord searchRecord) {
   if (searchRecord instanceof ArtistRecord) {
     if (excludeArtistIds.containsKey(searchRecord.getUniqueId())) return false;
     if (artistIds.containsKey(searchRecord.getUniqueId())) return true;
     if (artistSearchParameters != null)
       for (ArtistSearchParameters params : artistSearchParameters)
         if (params.matches(searchRecord) > 0.0f) return true;
     return false;
   } else if (searchRecord instanceof LabelRecord) {
     if (excludeLabelIds.containsKey(searchRecord.getUniqueId())) return false;
     if (labelIds.containsKey(searchRecord.getUniqueId())) return true;
     if (labelSearchParameters != null)
       for (LabelSearchParameters params : labelSearchParameters)
         if (params.matches(searchRecord) > 0.0f) return true;
     return false;
   } else if (searchRecord instanceof ReleaseRecord) {
     if (excludeReleaseIds.containsKey(searchRecord.getUniqueId())) return false;
     if (releaseIds.containsKey(searchRecord.getUniqueId())) return true;
     if (releaseSearchParameters != null)
       for (ReleaseSearchParameters params : releaseSearchParameters)
         if (params.matches(searchRecord) > 0.0f) return true;
     boolean include = false;
     ReleaseRecord releaseRecord = (ReleaseRecord) searchRecord;
     if (releaseRecord.getArtistIds() != null) {
       for (int artistId : releaseRecord.getArtistIds()) {
         if (excludeArtistIds.containsKey(artistId)) return false;
         if (artistIds.containsKey(artistId)) include = true;
       }
     }
     if (releaseRecord.getLabelIds() != null) {
       for (int labelId : releaseRecord.getLabelIds()) {
         if (excludeLabelIds.containsKey(labelId)) return false;
         if (labelIds.containsKey(labelId)) include = true;
       }
     }
     return include;
   } else if (searchRecord instanceof SongRecord) {
     if (excludeSongIds.containsKey(searchRecord.getUniqueId())) return false;
     if (songIds.containsKey(searchRecord.getUniqueId())) return true;
     if (songSearchParameters != null)
       for (SongSearchParameters params : songSearchParameters)
         if (params.matches(searchRecord) > 0.0f) return true;
     boolean include = false;
     SongRecord songRecord = (SongRecord) searchRecord;
     if (songRecord.getArtistIds() != null) {
       for (int artistId : songRecord.getArtistIds()) {
         if (excludeArtistIds.containsKey(artistId)) return false;
         if (artistIds.containsKey(artistId)) include = true;
       }
     }
     if (songRecord.getLabelIds() != null) {
       for (int labelId : songRecord.getLabelIds()) {
         if (excludeLabelIds.containsKey(labelId)) return false;
         if (labelIds.containsKey(labelId)) include = true;
       }
     }
     if (songRecord.getReleaseIds() != null) {
       for (int releaseId : songRecord.getReleaseIds()) {
         if (excludeReleaseIds.containsKey(releaseId)) return false;
         if (releaseIds.containsKey(releaseId)) include = true;
       }
     }
     return include;
   }
   return false;
 }