class FileComparator {

  public Set<ConstructChange> identifyChanges() {
    if (this.changes == null) {
      this.changes = new TreeSet<ConstructChange>();

      // Loop constructs of defective file (if any)
      // Add to changes if construct has been modified (!equals) or does not exist any longer
      if (this.defAnalyzer != null) {
        try {
          for (ConstructId key : this.defAnalyzer.getConstructs().keySet()) {
            if (this.fixAnalyzer != null && this.fixAnalyzer.containsConstruct(key)) {
              if (!this.defAnalyzer.getConstruct(key).equals(this.fixAnalyzer.getConstruct(key))) {
                // Modification (MOD)
                final ConstructChange c =
                    new ConstructChange(
                        this.repo,
                        this.repoPath,
                        this.defAnalyzer.getConstruct(key),
                        this.fixAnalyzer.getConstruct(key),
                        this.revision,
                        this.timeStamp);

                // Always add the construct change, no matter the signature change (if any)
                // if(c.hasSignatureChange())
                this.changes.add(c);
              }
            } else {
              this.changes.add(
                  new ConstructChange(
                      this.repo,
                      this.repoPath,
                      this.defAnalyzer.getConstruct(key),
                      null,
                      this.revision,
                      this.timeStamp));
            }
          }
        } catch (FileAnalysisException e) {
          FileComparator.log.error(
              "Error while comparing defective and fixed version: " + e.getMessage(), e);
        }
      }
      // Loop constructs of fixed file (if any)
      // Add to changes if construct has been modified (!equals) or does not exist any longer
      if (this.fixAnalyzer != null) {
        try {
          for (ConstructId key : this.fixAnalyzer.getConstructs().keySet()) {
            if (this.defAnalyzer != null && this.defAnalyzer.containsConstruct(key)) {
              if (!this.fixAnalyzer.getConstruct(key).equals(this.defAnalyzer.getConstruct(key))) {
                // Modification (MOD)
                final ConstructChange chg =
                    new ConstructChange(
                        this.repo,
                        this.repoPath,
                        this.defAnalyzer.getConstruct(key),
                        this.fixAnalyzer.getConstruct(key),
                        this.revision,
                        this.timeStamp);

                // Always add the construct change if not existing yet, no matter the signature
                // change (if any)
                if (!this.changes.contains(chg)) // && chg.hasSignatureChange())
                this.changes.add(chg);
              }
            } else {
              this.changes.add(
                  new ConstructChange(
                      this.repo,
                      this.repoPath,
                      null,
                      this.fixAnalyzer.getConstruct(key),
                      this.revision,
                      this.timeStamp));
            }
          }
        } catch (FileAnalysisException e) {
          FileComparator.log.error(
              "Error while comparing defective and fixed version: " + e.getMessage(), e);
        }
      }
    }
    return changes;
  }

  public  FileComparator(FileChange _c, String _rev, String _time_stamp);
  public  FileComparator(
      File _def, File _fix, String _rev, String _repo, String _repo_path, String _time_stamp);

}