public boolean isOutdated(final boolean tests, final ProjectWrapper history) {
      if (history == null) {
        return true;
      }

      final ModuleWrapper past = history.getModule(myName);

      if (past == null) {
        return true;
      }

      final boolean outputChanged = !safeEquals(past.getOutputPath(), getOutputPath());
      final boolean testOutputChanged =
          tests && !safeEquals(past.getTestOutputPath(), getTestOutputPath());
      final boolean sourceChanged = !past.getSourceFiles().equals(getSourceFiles());
      final boolean testSourceChanged =
          tests && !past.getTestSourceFiles().equals(getTestSourceFiles());
      final boolean sourceOutdated =
          mySource.isOutdated() || !mySource.getOutdatedFiles(past.mySource).isEmpty();
      final boolean testSourceOutdated =
          tests && (myTest.isOutdated() || !myTest.getOutdatedFiles(past.myTest).isEmpty());
      final boolean unsafeDependencyChange =
          (new Object() {
            public boolean run(
                final List<ClasspathItemWrapper> today,
                final List<ClasspathItemWrapper> yesterday) {
              final Iterator<ClasspathItemWrapper> t = today.iterator();
              final Iterator<ClasspathItemWrapper> y = yesterday.iterator();

              while (true) {
                if (!y.hasNext()) return false;

                if (!t.hasNext()) return true;

                if (!safeEquals(t.next(), y.next())) return true;
              }
            }
          }.run(dependsOn(tests), past.dependsOn(tests)));

      return sourceOutdated
          || testSourceOutdated
          || sourceChanged
          || testSourceChanged
          || outputChanged
          || testOutputChanged
          || unsafeDependencyChange;
    }