public static Change create(
      ICompilationUnit cu,
      NLSSubstitution[] subs,
      String substitutionPattern,
      IPackageFragment accessorPackage,
      String accessorClassName,
      boolean isEclipseNLS)
      throws CoreException {

    NLSSourceModifier sourceModification = new NLSSourceModifier(substitutionPattern, isEclipseNLS);

    String message =
        Messages.format(
            NLSMessages.NLSSourceModifier_change_description, BasicElementLabels.getFileName(cu));

    TextChange change = new CompilationUnitChange(message, cu);
    MultiTextEdit multiTextEdit = new MultiTextEdit();
    change.setEdit(multiTextEdit);

    accessorClassName =
        sourceModification.createImportForAccessor(
            multiTextEdit, accessorClassName, accessorPackage, cu);

    for (int i = 0; i < subs.length; i++) {
      NLSSubstitution substitution = subs[i];
      int newState = substitution.getState();
      if (substitution.hasStateChanged()) {
        if (newState == NLSSubstitution.EXTERNALIZED) {
          if (substitution.getInitialState() == NLSSubstitution.INTERNALIZED) {
            sourceModification.addNLS(substitution, change, accessorClassName);
          } else if (substitution.getInitialState() == NLSSubstitution.IGNORED) {
            sourceModification.addAccessor(substitution, change, accessorClassName);
          }
        } else if (newState == NLSSubstitution.INTERNALIZED) {
          if (substitution.getInitialState() == NLSSubstitution.IGNORED) {
            sourceModification.deleteTag(substitution, change);
            if (substitution.isValueRename()) {
              sourceModification.replaceValue(substitution, change);
            }
          } else if (substitution.getInitialState() == NLSSubstitution.EXTERNALIZED) {
            sourceModification.deleteAccessor(substitution, change, cu);
            if (!isEclipseNLS) sourceModification.deleteTag(substitution, change);
          }
        } else if (newState == NLSSubstitution.IGNORED) {
          if (substitution.getInitialState() == NLSSubstitution.INTERNALIZED) {
            sourceModification.addNLS(substitution, change, accessorClassName);
            if (substitution.isValueRename()) {
              sourceModification.replaceValue(substitution, change);
            }
          } else {
            if (substitution.getInitialState() == NLSSubstitution.EXTERNALIZED) {
              sourceModification.deleteAccessor(substitution, change, cu);
            }
          }
        }
      } else {
        if (newState == NLSSubstitution.EXTERNALIZED) {
          if (substitution.isKeyRename()) {
            sourceModification.replaceKey(substitution, change);
          }
          if (substitution.isAccessorRename()) {
            sourceModification.replaceAccessor(substitution, change);
          }
        } else {
          if (substitution.isValueRename()) {
            sourceModification.replaceValue(substitution, change);
          }
        }
      }
    }

    return change;
  }