Index: maven-core/src/main/java/org/apache/maven/plugin/DefaultPluginManager.java
===================================================================
--- maven-core/src/main/java/org/apache/maven/plugin/DefaultPluginManager.java	(revision 636021)
+++ maven-core/src/main/java/org/apache/maven/plugin/DefaultPluginManager.java	(working copy)
@@ -20,6 +20,19 @@
  * under the License.
  */
 
+import java.io.File;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
 import org.apache.maven.MavenArtifactFilterManager;
 import org.apache.maven.artifact.Artifact;
 import org.apache.maven.artifact.factory.ArtifactFactory;
@@ -48,6 +61,7 @@
 import org.apache.maven.plugin.descriptor.Parameter;
 import org.apache.maven.plugin.descriptor.PluginDescriptor;
 import org.apache.maven.plugin.descriptor.PluginDescriptorBuilder;
+import org.apache.maven.plugin.identifier.PluginCoordinate;
 import org.apache.maven.plugin.logging.Log;
 import org.apache.maven.plugin.version.PluginVersionManager;
 import org.apache.maven.plugin.version.PluginVersionNotFoundException;
@@ -83,19 +97,6 @@
 import org.codehaus.plexus.util.StringUtils;
 import org.codehaus.plexus.util.xml.Xpp3Dom;
 
-import java.io.File;
-import java.net.URL;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.LinkedHashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
 public class DefaultPluginManager
     extends AbstractLogEnabled
     implements PluginManager, Initializable, Contextualizable
@@ -203,7 +204,9 @@
 
             artifactResolver.resolve( pluginArtifact, project.getPluginArtifactRepositories(), localRepository );
 
-            PlexusContainer pluginContainer = container.getChildContainer( plugin.getKey() );
+            PluginCoordinate pc = new PluginCoordinate( pluginArtifact.getGroupId(), pluginArtifact.getArtifactId(), pluginArtifact.getVersion() );
+                        
+            PlexusContainer pluginContainer = container.getChildContainer( pc.toString() );
 
             File pluginFile = pluginArtifact.getFile();
 
@@ -293,7 +296,8 @@
 
         try
         {
-            child = container.createChildContainer( plugin.getKey(),
+            PluginCoordinate pc = new PluginCoordinate(plugin);
+            child = container.createChildContainer( pc.toString(),
                                                     Collections.singletonList( pluginArtifact.getFile() ),
                                                     Collections.EMPTY_MAP,
                                                     Collections.singletonList( pluginCollector ) );
@@ -580,7 +584,9 @@
     {
         String pluginKey = pluginDescriptor.getPluginLookupKey();
 
-        PlexusContainer pluginContainer = container.getChildContainer( pluginKey );
+        PluginCoordinate pc = new PluginCoordinate(pluginDescriptor.getGroupId(), pluginDescriptor.getArtifactId(), pluginDescriptor.getVersion());
+                
+        PlexusContainer pluginContainer = container.getChildContainer( pc.toString() );
 
         if ( pluginContainer == null )
         {
Index: maven-core/src/main/java/org/apache/maven/plugin/identifier/PluginCoordinate.java
===================================================================
--- maven-core/src/main/java/org/apache/maven/plugin/identifier/PluginCoordinate.java	(revision 0)
+++ maven-core/src/main/java/org/apache/maven/plugin/identifier/PluginCoordinate.java	(revision 0)
@@ -0,0 +1,93 @@
+package org.apache.maven.plugin.identifier;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.artifact.versioning.ArtifactVersion;
+import org.apache.maven.artifact.versioning.DefaultArtifactVersion;
+import org.apache.maven.model.Plugin;
+
+/**
+ * The co-ordinate of a plugin - the identifier, and the version
+ * that is in use.
+ */
+public class PluginCoordinate
+{
+  PluginIdentifier identifier;
+  ArtifactVersion version;
+  
+  public PluginCoordinate(Plugin plugin)
+  {
+    this.identifier = new PluginIdentifier(plugin.getGroupId(), plugin.getArtifactId());
+    if( plugin.getVersion() != null )
+    {
+      this.version = new DefaultArtifactVersion(plugin.getVersion());
+    }
+  }
+  
+  public PluginCoordinate(String groupId, String artifactId, String version)
+  {
+    this.identifier = new PluginIdentifier(groupId, artifactId);
+    if( version != null )
+    {
+      this.version = new DefaultArtifactVersion( version );
+    }
+  }
+
+  public PluginIdentifier getIdentifier()
+  {
+    return identifier;
+  }
+
+  public ArtifactVersion getVersion()
+  {
+    return version;
+  }
+  
+  public String toString()
+  {
+    String value = this.identifier.toString();
+    if( this.version != null )
+    {
+      value += ":" + version.toString();
+    }
+    return value;
+  }
+  
+  /**
+   * @see java.lang.Object#hashCode()
+   */
+  public int hashCode()
+  {
+      return toString().hashCode();
+  }
+  
+  public boolean equals( Object other )
+  {
+      if ( other instanceof PluginCoordinate )
+      {
+        PluginCoordinate otherCoord = (PluginCoordinate) other;
+
+        return this.toString().equals( otherCoord.toString() );
+      }
+
+      return false;
+  }
+  
+}
Index: maven-core/src/main/java/org/apache/maven/plugin/identifier/PluginIdentifier.java
===================================================================
--- maven-core/src/main/java/org/apache/maven/plugin/identifier/PluginIdentifier.java	(revision 0)
+++ maven-core/src/main/java/org/apache/maven/plugin/identifier/PluginIdentifier.java	(revision 0)
@@ -0,0 +1,71 @@
+package org.apache.maven.plugin.identifier;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * An identifier of a plugin - the group and artifact.
+ */
+public class PluginIdentifier
+{
+  String artifactId;
+  String groupId;
+  
+  public PluginIdentifier(String groupId, String artifactId)
+  {
+    this.artifactId = artifactId;
+    this.groupId    = groupId;
+  }
+
+  public String getArtifactId()
+  {
+    return artifactId;
+  }
+
+  public String getGroupId()
+  {
+    return groupId;
+  }
+  
+  public String toString()
+  {
+      return this.artifactId + ":" + this.groupId;
+  } 
+  
+  /**
+   * @see java.lang.Object#hashCode()
+   */
+  public int hashCode()
+  {
+      return artifactId.hashCode() + groupId.hashCode();
+  }
+  
+  public boolean equals( Object other )
+  {
+      if ( other instanceof PluginIdentifier )
+      {
+        PluginIdentifier otherId = (PluginIdentifier) other;
+
+        return this.artifactId.equals( otherId.artifactId ) &&
+               this.groupId.equals( otherId.groupId );
+      }
+
+      return false;
+  }
+}
Index: maven-core/src/main/java/org/apache/maven/plugin/MavenPluginCollector.java
===================================================================
--- maven-core/src/main/java/org/apache/maven/plugin/MavenPluginCollector.java	(revision 636021)
+++ maven-core/src/main/java/org/apache/maven/plugin/MavenPluginCollector.java	(working copy)
@@ -21,6 +21,8 @@
 
 import org.apache.maven.model.Plugin;
 import org.apache.maven.plugin.descriptor.PluginDescriptor;
+import org.apache.maven.plugin.identifier.PluginCoordinate;
+import org.apache.maven.plugin.identifier.PluginIdentifier;
 import org.codehaus.plexus.component.discovery.ComponentDiscoveryEvent;
 import org.codehaus.plexus.component.discovery.ComponentDiscoveryListener;
 import org.codehaus.plexus.component.repository.ComponentSetDescriptor;
@@ -32,15 +34,25 @@
 import java.util.Map;
 import java.util.Set;
 
+/**
+* This class contains references to the plugins that have been loaded,
+* indexed in a way so that they can be looked up.
+* 
+* It listens for new plugins being loaded, and adds them into the index
+* as this happens.
+* 
+*/
 public class MavenPluginCollector
     extends AbstractLogEnabled
     implements ComponentDiscoveryListener
 {
-
+    // Set {PluginCoordinate}
     private Set pluginsInProcess = new HashSet();
 
+    // Map {PluginIdentifier -> Map {PluginCoordinate -> PluginDescriptor}}
     private Map pluginDescriptors = new HashMap();
 
+    // Map {String -> PluginDescriptor}
     private Map pluginIdsByPrefix = new HashMap();
 
     // ----------------------------------------------------------------------
@@ -54,14 +66,15 @@
         {
             PluginDescriptor pluginDescriptor = (PluginDescriptor) componentSetDescriptor;
             
-            // TODO: see comment in getPluginDescriptor
-            String key = Plugin.constructKey( pluginDescriptor.getGroupId(), pluginDescriptor.getArtifactId() );
+                        
+             PluginCoordinate coordinate = new PluginCoordinate( pluginDescriptor.getGroupId(), pluginDescriptor.getArtifactId(), pluginDescriptor.getVersion() );
             
-            if ( !pluginsInProcess.contains( key ) )
+            if ( !pluginsInProcess.contains( coordinate ) )
             {
-                pluginsInProcess.add( key );
+                pluginsInProcess.add( coordinate );
 
-                pluginDescriptors.put( key, pluginDescriptor );
+                Map pluginMap = getDescriptors(coordinate.getIdentifier());
+                pluginMap.put( coordinate, pluginDescriptor );
 
                 // TODO: throw an (not runtime) exception if there is a prefix overlap - means doing so elsewhere
                 // we also need to deal with multiple versions somehow - currently, first wins
@@ -78,24 +91,55 @@
         // TODO: include version, but can't do this in the plugin manager as it is not resolved to the right version
         // at that point. Instead, move the duplication check to the artifact container, or store it locally based on
         // the unresolved version?
-        return (PluginDescriptor) pluginDescriptors.get( plugin.getKey() );
+        //return (PluginDescriptor) pluginDescriptors.get( plugin.getKey() );
+              
+        // NM: It seems like the version is always present. Maybe some API is needed,
+        // to differentiate between 'has any plugin of this type loaded' and 'has this
+        // *specific* plugin been installed.
+              
+        PluginCoordinate coordinate = new PluginCoordinate(plugin);
+                
+        Map pluginMap = getDescriptors(coordinate.getIdentifier());
+        return (PluginDescriptor)pluginMap.get(coordinate);
     }
 
     public boolean isPluginInstalled( Plugin plugin )
     {
         // TODO: see comment in getPluginDescriptor
-        return pluginDescriptors.containsKey( plugin.getKey() );
+        //return pluginDescriptors.containsKey( plugin.getKey() );
+            
+        PluginCoordinate coordinate = new PluginCoordinate(plugin);
+                
+        Map pluginMap = getDescriptors(coordinate.getIdentifier());
+        return pluginMap.containsKey(coordinate);
     }
 
+    private Map getDescriptors(PluginIdentifier pluginIdentifier)
+    {
+         Map map = (Map)pluginDescriptors.get(pluginIdentifier);
+         if( map == null )
+         {
+            map = new HashMap();
+            pluginDescriptors.put(pluginIdentifier, map);
+         }
+          return map;
+    }
+    
     public PluginDescriptor getPluginDescriptorForPrefix( String prefix )
     {
+        getLogger().debug( "getPluginDescriptorForPrefix " + prefix );
         return (PluginDescriptor) pluginIdsByPrefix.get( prefix );
     }
 
     public void flushPluginDescriptor( Plugin plugin )
     {
-        pluginsInProcess.remove( plugin.getKey() );
-        pluginDescriptors.remove( plugin.getKey() );
+
+        getLogger().debug( "flushPluginDescriptor " + plugin.getKey() + " @ " + plugin.getVersion() );
+        PluginCoordinate coordinate = new PluginCoordinate(plugin);
+                
+        pluginsInProcess.remove( coordinate );
+        Map pluginMap = getDescriptors(coordinate.getIdentifier());
+        pluginMap.remove( coordinate );
         
         for ( Iterator it = pluginIdsByPrefix.entrySet().iterator(); it.hasNext(); )
         {

