public void testNbmWithExternal() throws Exception {
    String moduleCNB = "org.netbeans.modules.mymodule";
    String moduleReleaseVersion = "1";
    String moduleImplVersion = "2";
    String moduleSpecVersion = "1.0";

    prepareNBM(moduleCNB, moduleReleaseVersion, moduleImplVersion, moduleSpecVersion, false, null);

    writeCatalog();
    UpdateUnitProviderFactory.getDefault().refreshProviders(null, true);
    OperationContainer<InstallSupport> installContainer = OperationContainer.createForInstall();
    UpdateUnit moduleUnit = getUpdateUnit(moduleCNB);
    assertNull("cannot be installed", moduleUnit.getInstalled());
    UpdateElement moduleElement = getAvailableUpdate(moduleUnit, 0);
    assertEquals(moduleElement.getSpecificationVersion(), moduleSpecVersion);
    OperationInfo<InstallSupport> independentInfo = installContainer.add(moduleElement);
    assertNotNull(independentInfo);
    doInstall(installContainer);

    File module = new File(new File(getWorkDir(), "modules"), "org-netbeans-modules-mymodule.jar");
    assertTrue("module file exists", module.exists());
    assertTrue("module was not installed from NBM external", moduleUnit.getInstalled() != null);
    File ext =
        new File(new File(getWorkDir(), "modules"), "org-netbeans-modules-mymodule.jar.external");
    assertFalse("Ext file is not written", ext.exists());
    File utf =
        new File(new File(getWorkDir(), "update_tracking"), "org-netbeans-modules-mymodule.xml");
    assertTrue("Update tracking exists", utf.exists());
    String content;
    {
      byte[] arr = new byte[(int) utf.length()];
      FileInputStream is = new FileInputStream(utf);
      is.read(arr);
      is.close();
      content = new String(arr);
    }
    if (!content.contains("\"modules/org-netbeans-modules-mymodule.jar\"")) {
      fail("Wrong content:\n" + content);
    }
    if (content.contains("\"modules/org-netbeans-modules-mymodule.jar.external\"")) {
      fail("Wrong content:\n" + content);
    }
    if (!content.contains("crc=\"" + UpdateTracking.getFileCRC(module) + "\"")) {
      fail("Wrong content:\n" + content);
    }
  }
 @SuppressWarnings("unchecked")
 public int getDownloadSize() {
   int res = 0;
   assert container != null || containerCustom != null
       : "OperationContainer found when asking for download size.";
   Set<OperationInfo> infos = new HashSet<OperationInfo>();
   infos.addAll(container.listAll());
   infos.addAll(containerCustom.listAll());
   Set<UpdateElement> elements = new HashSet<UpdateElement>();
   for (OperationInfo info : infos) {
     elements.add(info.getUpdateElement());
     elements.addAll(info.getRequiredElements());
   }
   for (UpdateElement el : elements) {
     res += el.getDownloadSize();
   }
   return res;
 }
  private void doInstall(OperationContainer<InstallSupport> installContainer)
      throws OperationException {
    InstallSupport support = installContainer.getSupport();
    assertNotNull(support);

    InstallSupport.Validator v = support.doDownload(null, false);
    assertNotNull(v);
    InstallSupport.Installer i = support.doValidate(v, null);
    assertNotNull(i);
    Restarter r = null;
    try {
      r = support.doInstall(i, null);
    } catch (OperationException ex) {
      if (OperationException.ERROR_TYPE.INSTALL == ex.getErrorType()) {
        // can ingore
        // module system cannot load the module either
      } else {
        fail(ex.toString());
      }
    }
    assertNull("Installing new element require restarting though it should not", r);
  }