I have hit a problem that I think is a bug in UsesAnalyser.

In encountering a particular bundle constraint violation UsesAnalyser recurses endlessly through the method addUsedImportedPackages(...) analysing the same packages again and again. This seems to me to be an error in the code - that is, protection against repeating analysis of the same packages is implemented in one block but not another.

I BELIEVE the code should be modified as follows BUT would be glad of confirmation:

private void addUsedImportedPackages(State state, Map<String, Set<SourcedPackage>> packages, ExportPackageDescription exportPackage, ExportPackageDescription topDependency, Set<String> knownPackages) {
String[] packageNames = (String[]) exportPackage.getDirective(Constants.USES_DIRECTIV E);
if (packageNames!=null) {
BundleDescription bundle = exportPackage.getExporter();

ExportPackageDescription[] allExports = bundle.getExportPackages();
ImportPackageSpecification[] allImports = bundle.getImportPackages();
ExportPackageDescription[] allResolvedImports = bundle.getResolvedImports();

for (String packageName : packageNames) {
ExportPackageDescription localExport = findExportPackageDescriptionInArray(allExports, packageName);
if (null!=localExport) {
addSourcedPackageToMapSet(packages, packageName, new UsedBySourcedPackage(topDependency, localExport));
}

ExportPackageDescription localResolvedImport = findExportPackageDescriptionInArray(allResolvedImp orts, packageName);
if (null!=localResolvedImport) {
if (!knownPackages.contains(packageName)) {
knownPackages.add(packageName);
addSourcedPackageToMapSet(packages, packageName, new UsedBySourcedPackage(topDependency, localResolvedImport));
addUsedImportedPackages(state, packages, localResolvedImport, topDependency, knownPackages);
}
} else {
ImportPackageSpecification anImport = findImportPackageSpecificationInArray(allImports, packageName);
if (anImport!=null) {
ExportPackageDescription[] matchingExports = getCandidateExports(state, anImport);
for (ExportPackageDescription matchingExport : matchingExports) {
// FIRST ADDITION
if (!knownPackages.contains(packageName)) {

knownPackages.add(packageName);
addSourcedPackageToMapSet(packages, packageName, new UsedBySourcedPackage(topDependency, matchingExport));
addUsedImportedPackages(state, packages, matchingExport, topDependency, knownPackages);
// SECOND ADDITION
}

}
}
}
}
}
}