[581487] The VersionBuilder's isBundlePackage is unreliable

https://bugs.eclipse.org/bugs/show_bug.cgi?id=581487
diff --git a/features/org.eclipse.oomph.version-feature/feature.xml b/features/org.eclipse.oomph.version-feature/feature.xml
index ac50779..a8380dc 100644
--- a/features/org.eclipse.oomph.version-feature/feature.xml
+++ b/features/org.eclipse.oomph.version-feature/feature.xml
@@ -12,7 +12,7 @@
 <feature
       id="org.eclipse.oomph.version"
       label="%featureName"
-      version="1.16.0.qualifier"
+      version="1.17.0.qualifier"
       provider-name="%providerName"
       license-feature="org.eclipse.oomph.license"
       license-feature-version="0.0.0">
diff --git a/features/org.eclipse.oomph.version-feature/pom.xml b/features/org.eclipse.oomph.version-feature/pom.xml
index f466d01..2cbd989 100644
--- a/features/org.eclipse.oomph.version-feature/pom.xml
+++ b/features/org.eclipse.oomph.version-feature/pom.xml
@@ -20,6 +20,6 @@
   </parent>
   <groupId>org.eclipse.oomph.features</groupId>
   <artifactId>org.eclipse.oomph.version</artifactId>
-  <version>1.16.0-SNAPSHOT</version>
+  <version>1.17.0-SNAPSHOT</version>
   <packaging>eclipse-feature</packaging>
 </project>
diff --git a/features/org.eclipse.oomph.version.headless-feature/feature.xml b/features/org.eclipse.oomph.version.headless-feature/feature.xml
index ac46ea8..308f813 100644
--- a/features/org.eclipse.oomph.version.headless-feature/feature.xml
+++ b/features/org.eclipse.oomph.version.headless-feature/feature.xml
@@ -12,7 +12,7 @@
 <feature
       id="org.eclipse.oomph.version.headless"
       label="%featureName"
-      version="1.14.0.qualifier"
+      version="1.15.0.qualifier"
       provider-name="%providerName"
       license-feature="org.eclipse.oomph.license"
       license-feature-version="0.0.0">
diff --git a/features/org.eclipse.oomph.version.headless-feature/pom.xml b/features/org.eclipse.oomph.version.headless-feature/pom.xml
index 670d3d2..c16df62 100644
--- a/features/org.eclipse.oomph.version.headless-feature/pom.xml
+++ b/features/org.eclipse.oomph.version.headless-feature/pom.xml
@@ -20,6 +20,6 @@
   </parent>
   <groupId>org.eclipse.oomph.features</groupId>
   <artifactId>org.eclipse.oomph.version.headless</artifactId>
-  <version>1.14.0-SNAPSHOT</version>
+  <version>1.15.0-SNAPSHOT</version>
   <packaging>eclipse-feature</packaging>
 </project>
diff --git a/plugins/org.eclipse.oomph.version/META-INF/MANIFEST.MF b/plugins/org.eclipse.oomph.version/META-INF/MANIFEST.MF
index e9d5dc4..d06baa7 100644
--- a/plugins/org.eclipse.oomph.version/META-INF/MANIFEST.MF
+++ b/plugins/org.eclipse.oomph.version/META-INF/MANIFEST.MF
@@ -1,7 +1,7 @@
 Manifest-Version: 1.0
 Bundle-ManifestVersion: 2
 Bundle-SymbolicName: org.eclipse.oomph.version;singleton:=true
-Bundle-Version: 1.12.0.qualifier
+Bundle-Version: 1.13.0.qualifier
 Bundle-Name: %pluginName
 Bundle-Vendor: %providerName
 Bundle-Localization: plugin
@@ -12,9 +12,9 @@
 Require-Bundle: org.eclipse.core.runtime;bundle-version="[3.24.0,4.0.0)",
  org.eclipse.core.resources;bundle-version="[3.5.0,4.0.0)",
  org.eclipse.pde.core;bundle-version="[3.5.0,4.0.0)",
- org.eclipse.oomph.util;bundle-version="[1.18.0,2.0.0)";visibility:=reexport
-Export-Package: org.eclipse.oomph.internal.version;version="1.12.0";x-friends:="org.eclipse.oomph.version.ui",
- org.eclipse.oomph.version;version="1.12.0"
+ org.eclipse.oomph.util;bundle-version="[1.20.0,2.0.0)";visibility:=reexport
+Export-Package: org.eclipse.oomph.internal.version;version="1.13.0";x-friends:="org.eclipse.oomph.version.ui",
+ org.eclipse.oomph.version;version="1.13.0"
 Eclipse-RegisterBuddy: org.eclipse.oomph.util
 Eclipse-BuddyPolicy: dependent
 Automatic-Module-Name: org.eclipse.oomph.version
diff --git a/plugins/org.eclipse.oomph.version/pom.xml b/plugins/org.eclipse.oomph.version/pom.xml
index 0adc60b..3d4315e 100644
--- a/plugins/org.eclipse.oomph.version/pom.xml
+++ b/plugins/org.eclipse.oomph.version/pom.xml
@@ -20,7 +20,7 @@
   </parent>
   <groupId>org.eclipse.oomph</groupId>
   <artifactId>org.eclipse.oomph.version</artifactId>
-  <version>1.12.0-SNAPSHOT</version>
+  <version>1.13.0-SNAPSHOT</version>
   <packaging>eclipse-plugin</packaging>
 
   <build>
diff --git a/plugins/org.eclipse.oomph.version/src/org/eclipse/oomph/internal/version/VersionBuilder.java b/plugins/org.eclipse.oomph.version/src/org/eclipse/oomph/internal/version/VersionBuilder.java
index 448d828..992e2b8 100644
--- a/plugins/org.eclipse.oomph.version/src/org/eclipse/oomph/internal/version/VersionBuilder.java
+++ b/plugins/org.eclipse.oomph.version/src/org/eclipse/oomph/internal/version/VersionBuilder.java
@@ -1622,18 +1622,37 @@
     Markers.deleteAllMarkers(file, Markers.EXPORT_VERSION_PROBLEM);
 
     BundleDescription description = pluginModel.getBundleDescription();
-    String bundleName = description.getSymbolicName();
     Version bundleVersion = VersionUtil.normalize(description.getVersion());
 
+    Set<IPath> paths = new HashSet<>();
+    Set<String> prefixes = new HashSet<>();
+    getProject().accept(it -> {
+      if (it instanceof IFile)
+      {
+        IPath path = it.getProjectRelativePath();
+        if ("java".equals(path.getFileExtension())) //$NON-NLS-1$
+        {
+          IPath javaPackageFolder = path.removeLastSegments(1);
+          if (paths.add(javaPackageFolder))
+          {
+            prefixes.add(javaPackageFolder.toString().replace('/', '.'));
+          }
+        }
+      }
+      return true;
+    });
+
     for (ExportPackageDescription packageExport : description.getExportPackages())
     {
       String packageName = packageExport.getName();
-      if (isBundlePackage(packageName, bundleName))
+      String suffix = '.' + packageName;
+      boolean isBundlePackage = prefixes.stream().anyMatch(it -> it.endsWith(suffix));
+      if (isBundlePackage)
       {
         Version packageVersion = packageExport.getVersion();
-        if (packageVersion != null && !packageVersion.equals(Version.emptyVersion) && !packageVersion.equals(bundleVersion))
+        if (!packageVersion.equals(bundleVersion))
         {
-          addExportMarker(file, packageName, bundleVersion);
+          addExportMarker(file, packageName, packageVersion, bundleVersion);
         }
       }
     }
@@ -1802,32 +1821,6 @@
     }
   }
 
-  private boolean isBundlePackage(String packageName, String bundleName)
-  {
-    if (packageName.startsWith(bundleName))
-    {
-      return true;
-    }
-
-    int lastDot = bundleName.lastIndexOf('.');
-    if (lastDot != -1)
-    {
-      String bundleStart = bundleName.substring(0, lastDot);
-      String bundleEnd = bundleName.substring(lastDot + 1);
-      if (packageName.startsWith(bundleStart + ".internal." + bundleEnd)) //$NON-NLS-1$
-      {
-        return true;
-      }
-
-      if (packageName.startsWith(bundleStart + ".spi." + bundleEnd)) //$NON-NLS-1$
-      {
-        return true;
-      }
-    }
-
-    return false;
-  }
-
   private void addRequireMarker(IFile file, String name, String message, boolean missing, VersionRange versionRange)
   {
     try
@@ -1909,19 +1902,23 @@
     }
   }
 
-  private void addExportMarker(IFile file, String name, Version bundleVersion)
+  private void addExportMarker(IFile file, String name, Version packageVersion, Version bundleVersion)
   {
     String versionString = bundleVersion.toString();
 
     try
     {
       String message = NLS.bind(Messages.VersionBuilder_PackageRequiresVersion_message, name, versionString);
-      String regex = name.replace(".", "\\.") + ";version=\"([0123456789\\.]*)\""; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+      boolean exists = !packageVersion.equals(Version.emptyVersion);
+      @SuppressWarnings("nls")
+      String regex = !exists ? //
+          "(?:\nExport-Package: |\n )" + name.replace(".", "\\.") + "()[;,\r\n]" : //
+          name.replace(".", "\\.") + ";version=\"([0123456789\\.]*)\"";
 
       IMarker marker = Markers.addMarker(file, message, IMarker.SEVERITY_ERROR, regex);
       marker.setAttribute(Markers.PROBLEM_TYPE, Markers.EXPORT_VERSION_PROBLEM);
       marker.setAttribute(Markers.QUICK_FIX_PATTERN, regex);
-      marker.setAttribute(Markers.QUICK_FIX_REPLACEMENT, versionString);
+      marker.setAttribute(Markers.QUICK_FIX_REPLACEMENT, exists ? versionString : ";version=\"" + bundleVersion + "\""); //$NON-NLS-1$ //$NON-NLS-2$
       marker.setAttribute(Markers.QUICK_FIX_CONFIGURE_OPTION, IVersionBuilderArguments.IGNORE_EXPORT_VERSIONS_ARGUMENT);
     }
     catch (Exception ex)