docs: public synchronized String installAddOns(List<String> addons) {
          StringBuilder errorMessages = new StringBuilder();
          AddOnCollection aoc = getLatestVersionInfo();
          if (aoc == null) {
              String error = Constant.messages.getString("cfu.cmdline.nocfu");
              errorMessages.append(error);
              CommandLine.error(error);
          } else {
              for (String aoName : addons) {
                  AddOn ao = aoc.getAddOn(aoName);
                  if (ao == null) {
                      String error = Constant.messages.getString("cfu.cmdline.noaddon", aoName);
                      errorMessages.append(error);
                      errorMessages.append("\n");
                      CommandLine.error(error);
                      continue;
                  }
                  AddOnDependencyChecker addOnDependencyChecker = new AddOnDependencyChecker(getLocalVersionInfo(), aoc);
                  AddOnDependencyChecker.AddOnChangesResult result;
                  // Check to see if its already installed
                  AddOn iao = getLocalVersionInfo().getAddOn(aoName);
                  if (iao != null) {
                      if (!ao.isUpdateTo(iao)) {
                          CommandLine.info(Constant.messages.getString("cfu.cmdline.addoninst", iao.getFile().getAbsolutePath()));
                          continue;
                      }
  
                      result = addOnDependencyChecker.calculateUpdateChanges(ao);
                  } else {
                      result = addOnDependencyChecker.calculateInstallChanges(ao);
                  }
                  
                  if (!result.getUninstalls().isEmpty()) {
                      String error = Constant.messages
                              .getString("cfu.cmdline.addoninst.uninstalls.required", result.getUninstalls());
                      errorMessages.append(error);
                      errorMessages.append("\n");
                      CommandLine.error(error);
                      continue;
                  }
  
                  Set<AddOn> allAddOns = new HashSet<>();
                  allAddOns.addAll(result.getInstalls());
                  allAddOns.addAll(result.getNewVersions());
                  for (AddOn addOn : allAddOns) {
                      CommandLine.info(Constant.messages.getString("cfu.cmdline.addonurl", addOn.getUrl()));
                  }
  
                  processAddOnChanges(null, result);
              }
              if (!waitAndInstallDownloads()) {
                  errorMessages.append(Constant.messages.getString("cfu.cmdline.addoninst.error")).append("\n");
              }
          }
          return errorMessages.toString();
      }