[420821] Use PDE model to provide OCL registry
diff --git a/examples/org.eclipse.ocl.examples.pivot/emf-gen/org/eclipse/ocl/examples/pivot/util/PivotPlugin.java b/examples/org.eclipse.ocl.examples.pivot/emf-gen/org/eclipse/ocl/examples/pivot/util/PivotPlugin.java
index ecfccad..8593577 100644
--- a/examples/org.eclipse.ocl.examples.pivot/emf-gen/org/eclipse/ocl/examples/pivot/util/PivotPlugin.java
+++ b/examples/org.eclipse.ocl.examples.pivot/emf-gen/org/eclipse/ocl/examples/pivot/util/PivotPlugin.java
@@ -60,6 +60,7 @@
 
 	public static final @NonNull String STANDARD_LIBRARY_PPID = "standard_library";
 	public static final @NonNull String COMPLETE_OCL_REGISTRY_PID = "complete_ocl_registry";
+	public static final @NonNull String COMPLETE_OCL_REGISTRY_QPID = PivotPlugin.PLUGIN_ID + "." + PivotPlugin.COMPLETE_OCL_REGISTRY_PID;
 
 	/**
 	 * Keep track of the singleton.
diff --git a/examples/org.eclipse.ocl.examples.pivot/src/org/eclipse/ocl/examples/pivot/registry/CompleteOCLRegistry.java b/examples/org.eclipse.ocl.examples.pivot/src/org/eclipse/ocl/examples/pivot/registry/CompleteOCLRegistry.java
index 18c5237..b79e583 100644
--- a/examples/org.eclipse.ocl.examples.pivot/src/org/eclipse/ocl/examples/pivot/registry/CompleteOCLRegistry.java
+++ b/examples/org.eclipse.ocl.examples.pivot/src/org/eclipse/ocl/examples/pivot/registry/CompleteOCLRegistry.java
@@ -32,7 +32,7 @@
  */
 public class CompleteOCLRegistry
 {
-	public static final @NonNull CompleteOCLRegistry INSTANCE = new CompleteOCLRegistry();
+	public static final @NonNull CompleteOCLRegistry INSTANCE = new CompleteOCLRegistry(null);
 	
 	/**
 	 * A Registration identifies a contribution to a Registry enabling the registry to be rebuilt if a registration is removed.
@@ -88,8 +88,16 @@
 		}
 	}
 
-	private @Nullable Map<Registration, Integer> registrations = null;
 	private final @NonNull Map<String, Set<URI>> nsURI2resourceURIs = new HashMap<String, Set<URI>>();
+	private @Nullable Map<Registration, Integer> registrations = null;
+
+	public CompleteOCLRegistry() {
+		this(new HashMap<Registration, Integer>());
+	}
+
+	protected CompleteOCLRegistry(@Nullable Map<Registration, Integer> registrations) {
+		this.registrations = registrations;
+	}
 
 	public synchronized void addRegistration(@NonNull Registration registration) {
 		Map<Registration, Integer> registrations2 = registrations;
diff --git a/examples/org.eclipse.ocl.examples.xtext.base.ui/src/org/eclipse/ocl/examples/xtext/base/ui/utilities/PDEUtils.java b/examples/org.eclipse.ocl.examples.xtext.base.ui/src/org/eclipse/ocl/examples/xtext/base/ui/utilities/PDEUtils.java
new file mode 100644
index 0000000..dadaf0d
--- /dev/null
+++ b/examples/org.eclipse.ocl.examples.xtext.base.ui/src/org/eclipse/ocl/examples/xtext/base/ui/utilities/PDEUtils.java
@@ -0,0 +1,110 @@
+/**
+ * <copyright>
+ *
+ * Copyright (c) 2014 Obeo and others.
+ * All rights reserved.   This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *   E.D.Willink (Obeo) - Initial API and implementation
+ * </copyright>
+ */
+package org.eclipse.ocl.examples.xtext.base.ui.utilities;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.jdt.annotation.Nullable;
+import org.eclipse.ocl.examples.pivot.registry.CompleteOCLRegistry;
+import org.eclipse.ocl.examples.pivot.util.PivotPlugin;
+import org.eclipse.osgi.service.resolver.BundleDescription;
+import org.eclipse.pde.core.plugin.IPluginAttribute;
+import org.eclipse.pde.core.plugin.IPluginElement;
+import org.eclipse.pde.core.plugin.IPluginExtension;
+import org.eclipse.pde.core.plugin.IPluginModelBase;
+import org.eclipse.pde.core.plugin.IPluginObject;
+import org.eclipse.pde.core.plugin.PluginRegistry;
+
+/**
+ * PDEUtils provides functionality exploiting PDE usage of the trget extension points..
+ */
+public class PDEUtils
+{
+	/**
+	 * Create a new Complete OCL Registry from the workspace and plugin extension point registrations.
+	 */
+	public static @NonNull CompleteOCLRegistry createCompleteOCLRegistry() {
+		CompleteOCLRegistry registry = new CompleteOCLRegistry();
+		IPluginModelBase[] activeModels = PluginRegistry.getActiveModels(false);
+		for (IPluginModelBase activeModel : activeModels) {
+			if (activeModel != null) {
+				for (IPluginExtension pluginExtension : activeModel.getExtensions().getExtensions()) {
+					String point = pluginExtension.getPoint();
+					if (PivotPlugin.COMPLETE_OCL_REGISTRY_QPID.equals(point)) {
+						URI location = getLocation(activeModel);
+						readCompleteOCLRegistryExtensionPoints(registry, location, pluginExtension);
+					}
+				}
+			}
+		}
+		return registry;
+	}
+
+	private static @NonNull URI getLocation(@NonNull IPluginModelBase activeModel) {
+		IResource underlyingResource = activeModel.getUnderlyingResource();
+		if (underlyingResource != null) {
+			String projectPath = underlyingResource.getProject().getFullPath().toString() + "/";
+			@SuppressWarnings("null")@NonNull URI projectURI = URI.createPlatformResourceURI(projectPath, true);
+			return projectURI;
+		}
+		else {
+			BundleDescription bundleDescription = activeModel.getBundleDescription();
+			String bundlePath = bundleDescription.getSymbolicName() + "/";
+			@SuppressWarnings("null")@NonNull URI bundleURI = URI.createPlatformPluginURI(bundlePath, true);
+			return bundleURI;
+		}
+	}
+
+	private static void readCompleteOCLRegistryExtensionPoints(@NonNull CompleteOCLRegistry registry,
+			@NonNull URI location, @NonNull IPluginExtension pluginExtension) {
+		for (IPluginObject child1 : pluginExtension.getChildren()) {
+			if (child1 instanceof IPluginElement) {
+				CompleteOCLRegistry.Registration registration = readCompleteOCLRegistryExtensionPoint(location, (IPluginElement) child1);
+				if (registration != null) {
+					registry.addRegistration(registration);
+				}
+			}
+		}
+	}
+
+	private static @Nullable CompleteOCLRegistry.Registration readCompleteOCLRegistryExtensionPoint(
+			@NonNull URI location, @NonNull IPluginElement documentElement) {
+		IPluginAttribute resourceAttribute = documentElement.getAttribute("resource");
+		if (resourceAttribute == null) {
+			return null;
+		}
+		List<String> nsURIs = new ArrayList<String>();
+		for (IPluginObject child2 : documentElement.getChildren()) {
+			if (child2 instanceof IPluginElement) {
+				IPluginElement forElement = (IPluginElement) child2;
+				IPluginAttribute uriAttribute = forElement.getAttribute("uri");
+				if (uriAttribute == null) {
+					return null;
+				}
+				String uriString = uriAttribute.getValue();
+				if (uriString == null) {
+					return null;
+				}
+				nsURIs.add(uriString);
+			}
+		}
+		URI resourceURI = URI.createURI(resourceAttribute.getValue());
+		@SuppressWarnings("null")@NonNull URI resolvedResourceURI = resourceURI.resolve(location);
+		return new CompleteOCLRegistry.Registration(resolvedResourceURI, nsURIs);
+	}
+}
diff --git a/examples/org.eclipse.ocl.examples.xtext.completeocl.ui/src/org/eclipse/ocl/examples/xtext/completeocl/ui/commands/LoadCompleteOCLResourceHandler.java b/examples/org.eclipse.ocl.examples.xtext.completeocl.ui/src/org/eclipse/ocl/examples/xtext/completeocl/ui/commands/LoadCompleteOCLResourceHandler.java
index 8061bc4..d8fa09d 100644
--- a/examples/org.eclipse.ocl.examples.xtext.completeocl.ui/src/org/eclipse/ocl/examples/xtext/completeocl/ui/commands/LoadCompleteOCLResourceHandler.java
+++ b/examples/org.eclipse.ocl.examples.xtext.completeocl.ui/src/org/eclipse/ocl/examples/xtext/completeocl/ui/commands/LoadCompleteOCLResourceHandler.java
@@ -63,6 +63,7 @@
 import org.eclipse.ocl.examples.pivot.utilities.BaseResource;
 import org.eclipse.ocl.examples.pivot.utilities.PivotUtil;
 import org.eclipse.ocl.examples.pivot.validation.PivotEObjectValidator;
+import org.eclipse.ocl.examples.xtext.base.ui.utilities.PDEUtils;
 import org.eclipse.ocl.examples.xtext.completeocl.CompleteOCLStandaloneSetup;
 import org.eclipse.ocl.examples.xtext.completeocl.ui.CompleteOCLUiModule;
 import org.eclipse.ocl.examples.xtext.completeocl.ui.messages.CompleteOCLUIMessages;
@@ -187,9 +188,11 @@
 			Composite buttonComposite = (Composite)createDialogArea.getChildren()[0];
 
 			Button browseRegisteredOCLFiles = new Button(buttonComposite, SWT.PUSH);
-			browseRegisteredOCLFiles.setText(CompleteOCLUIMessages.LoadCompleteOCLResource_browseOCLFiles);
+			browseRegisteredOCLFiles.setText(CompleteOCLUIMessages.LoadCompleteOCLResource_BrowseRegisteredOCLFiles);
 			prepareBrowseRegisteredOCLFiles(browseRegisteredOCLFiles);
-			registeredURIsForResourceSet = CompleteOCLRegistry.INSTANCE.getResourceURIs(resourceSet);
+//			registeredURIsForResourceSet = CompleteOCLRegistry.INSTANCE.getResourceURIs(resourceSet);
+			CompleteOCLRegistry registry = PDEUtils.createCompleteOCLRegistry();
+			registeredURIsForResourceSet = registry.getResourceURIs(resourceSet);
 			if (registeredURIsForResourceSet.isEmpty()) {
 				browseRegisteredOCLFiles.setEnabled(false);
 			} else {
@@ -250,6 +253,7 @@
 				setMessage(CompleteOCLUIMessages.LoadCompleteOCLResource_SelectRegisteredOCLFileURI);
 				setFilter("*");
 				setTitle(CompleteOCLUIMessages.LoadCompleteOCLResource_OCLFileSelection_label);
+				setSize(100, 20);
 			}
 			
 			@Override
diff --git a/examples/org.eclipse.ocl.examples.xtext.completeocl.ui/src/org/eclipse/ocl/examples/xtext/completeocl/ui/messages/CompleteOCLUIMessages.java b/examples/org.eclipse.ocl.examples.xtext.completeocl.ui/src/org/eclipse/ocl/examples/xtext/completeocl/ui/messages/CompleteOCLUIMessages.java
index c16d6ffe..4ac2b5d 100644
--- a/examples/org.eclipse.ocl.examples.xtext.completeocl.ui/src/org/eclipse/ocl/examples/xtext/completeocl/ui/messages/CompleteOCLUIMessages.java
+++ b/examples/org.eclipse.ocl.examples.xtext.completeocl.ui/src/org/eclipse/ocl/examples/xtext/completeocl/ui/messages/CompleteOCLUIMessages.java
@@ -33,7 +33,7 @@
 	public static String NewWizardPage_pageSummary;
 	public static String NewWizardPage_pageTitle;
 	
-	public static String LoadCompleteOCLResource_browseOCLFiles;
+	public static String LoadCompleteOCLResource_BrowseRegisteredOCLFiles;
 	public static String LoadCompleteOCLResource_SelectRegisteredOCLFileURI;
 	public static String LoadCompleteOCLResource_OCLFileSelection_label;
 }
\ No newline at end of file
diff --git a/examples/org.eclipse.ocl.examples.xtext.completeocl.ui/src/org/eclipse/ocl/examples/xtext/completeocl/ui/messages/CompleteOCLUIMessages.properties b/examples/org.eclipse.ocl.examples.xtext.completeocl.ui/src/org/eclipse/ocl/examples/xtext/completeocl/ui/messages/CompleteOCLUIMessages.properties
index a0484de..6b3e2d5 100644
--- a/examples/org.eclipse.ocl.examples.xtext.completeocl.ui/src/org/eclipse/ocl/examples/xtext/completeocl/ui/messages/CompleteOCLUIMessages.properties
+++ b/examples/org.eclipse.ocl.examples.xtext.completeocl.ui/src/org/eclipse/ocl/examples/xtext/completeocl/ui/messages/CompleteOCLUIMessages.properties
@@ -15,6 +15,6 @@
 NewWizardPage_pageSummary=Complete OCL File
 NewWizardPage_pageTitle=New Complete OCL File
 
-LoadCompleteOCLResource_browseOCLFiles=Browse &Registered OCL Files...
+LoadCompleteOCLResource_BrowseRegisteredOCLFiles=Browse &Registered OCL Files...
 LoadCompleteOCLResource_SelectRegisteredOCLFileURI = &Select a registered OCL File URI: 
 LoadCompleteOCLResource_OCLFileSelection_label = OCL File Selection
diff --git a/tests/org.eclipse.ocl.examples.xtext.tests/src/org/eclipse/ocl/examples/test/xtext/AllXtextTests.java b/tests/org.eclipse.ocl.examples.xtext.tests/src/org/eclipse/ocl/examples/test/xtext/AllXtextTests.java
index 98bd7d3..7df1869 100644
--- a/tests/org.eclipse.ocl.examples.xtext.tests/src/org/eclipse/ocl/examples/test/xtext/AllXtextTests.java
+++ b/tests/org.eclipse.ocl.examples.xtext.tests/src/org/eclipse/ocl/examples/test/xtext/AllXtextTests.java
@@ -96,6 +96,7 @@
 		}
 		result.addTestSuite(PrettyPrinterTest.class);
 		result.addTestSuite(ProjectMapTest.class);
+		result.addTestSuite(RegistryTests.class);
 		result.addTestSuite(SerializeTests.class);
 		result.addTestSuite(RoundTripTests.class);
 		result.addTestSuite(StereotypesTest.class);
diff --git a/tests/org.eclipse.ocl.examples.xtext.tests/src/org/eclipse/ocl/examples/test/xtext/RegistryTests.java b/tests/org.eclipse.ocl.examples.xtext.tests/src/org/eclipse/ocl/examples/test/xtext/RegistryTests.java
index 64c48c3..20d403b 100644
--- a/tests/org.eclipse.ocl.examples.xtext.tests/src/org/eclipse/ocl/examples/test/xtext/RegistryTests.java
+++ b/tests/org.eclipse.ocl.examples.xtext.tests/src/org/eclipse/ocl/examples/test/xtext/RegistryTests.java
@@ -89,6 +89,9 @@
 		assertEquals(setOf, registry.getResourceURIs(listOf_a1_a2));
 	}
 	
+	/**
+	 * Confirm that registrations are counted so after adding twice, it remains till removed twice.
+	 */
 	public void testCompleteOCLRegistry_Rebuild_Counted() {
 		@SuppressWarnings("null")@NonNull URI uriA = URI.createURI("A");
 		@SuppressWarnings("null")@NonNull Set<URI> setOf = Sets.newHashSet();