diff --git a/org.eclipse.ajdt.core/src/org/eclipse/ajdt/core/AspectJCorePreferences.java b/org.eclipse.ajdt.core/src/org/eclipse/ajdt/core/AspectJCorePreferences.java
index 3d5730a..992502f 100755
--- a/org.eclipse.ajdt.core/src/org/eclipse/ajdt/core/AspectJCorePreferences.java
+++ b/org.eclipse.ajdt.core/src/org/eclipse/ajdt/core/AspectJCorePreferences.java
@@ -43,38 +43,36 @@
  * names have been kept for compatibility.
  */
 public class AspectJCorePreferences {
-			
-    public static final String OPTION_IncrementalCompilationOptimizations = "org.eclipse.ajdt.core.builder.incrementalCompilationOptimizations"; //$NON-NLS-1$
 
-    
+	public static final String OPTION_IncrementalCompilationOptimizations = "org.eclipse.ajdt.core.builder.incrementalCompilationOptimizations"; //$NON-NLS-1$
+
 	public static final String ASPECTPATH_ATTRIBUTE_NAME = "org.eclipse.ajdt.aspectpath"; //$NON-NLS-1$
 	public static final String INPATH_ATTRIBUTE_NAME = "org.eclipse.ajdt.inpath"; //$NON-NLS-1$
-	
-	// see ajdt.ui's plugin.xml and the org.eclipse.jdt.ui.classpathAttributeConfiguration extension point
+
+	// see ajdt.ui's plugin.xml and the
+	// org.eclipse.jdt.ui.classpathAttributeConfiguration extension point
 	public static final String INPATH_RESTRICTION_ATTRIBUTE_NAME = "org.eclipse.ajdt.inpath.restriction"; //$NON-NLS-1$
 	public static final String ASPECTPATH_RESTRICTION_ATTRIBUTE_NAME = "org.eclipse.ajdt.aspectpath.restriction"; //$NON-NLS-1$
 
+	/**
+	 * The value may be filled in with the container that contains this
+	 * classpath entry So when checking to see if a classpath entry has this
+	 * attribute, use {@link #isOnAspectpath(IClasspathEntry)}
+	 */
+	public static final IClasspathAttribute ASPECTPATH_ATTRIBUTE = JavaCore
+			.newClasspathAttribute(ASPECTPATH_ATTRIBUTE_NAME, ASPECTPATH_ATTRIBUTE_NAME); // $NON-NLS-1$
 
 	/**
-	 *  The value may be filled in with the container that contains this classpath entry
-	 *  So when checking to see if a classpath entry has this attribute, use {@link #isOnAspectpath(IClasspathEntry)} 
+	 * The value may be filled in with the container that contains this
+	 * classpath entry So when checking to see if a classpath entry has this
+	 * attribute, use {@link #isOnInpath(IClasspathEntry)}
 	 */
-	public static final IClasspathAttribute ASPECTPATH_ATTRIBUTE = JavaCore.newClasspathAttribute(
-			ASPECTPATH_ATTRIBUTE_NAME, ASPECTPATH_ATTRIBUTE_NAME); //$NON-NLS-1$
+	public static final IClasspathAttribute INPATH_ATTRIBUTE = JavaCore.newClasspathAttribute(INPATH_ATTRIBUTE_NAME,
+			INPATH_ATTRIBUTE_NAME); // $NON-NLS-1$
 
-	/**
-	 *  The value may be filled in with the container that contains this classpath entry
-	 *  So when checking to see if a classpath entry has this attribute, use {@link #isOnInpath(IClasspathEntry)} 
-	 */
-	public static final IClasspathAttribute INPATH_ATTRIBUTE = JavaCore.newClasspathAttribute(
-			INPATH_ATTRIBUTE_NAME, INPATH_ATTRIBUTE_NAME); //$NON-NLS-1$
+	public static final String OUT_JAR = "org.eclipse.ajdt.ui.outJar"; //$NON-NLS-1$
 
-	
-	
-	
-    public static final String OUT_JAR = "org.eclipse.ajdt.ui.outJar"; //$NON-NLS-1$
-
-    public static final String INPATH_OUT_FOLDER = "org.eclipse.ajdt.ui.inpathOutFolder"; //$NON-NLS-1$
+	public static final String INPATH_OUT_FOLDER = "org.eclipse.ajdt.ui.inpathOutFolder"; //$NON-NLS-1$
 
 	public static final String ASPECTPATH = "org.eclipse.ajdt.ui.aspectPath"; //$NON-NLS-1$
 
@@ -89,141 +87,133 @@
 	public static final String INPATH_ENT_KINDS = "org.eclipse.ajdt.ui.inPath.entryKind"; //$NON-NLS-1$
 
 	public static String getProjectOutJar(IProject project) {
-        IScopeContext projectScope = new ProjectScope(project);
-        IEclipsePreferences projectNode = projectScope
-                .getNode(AspectJPlugin.UI_PLUGIN_ID);
-        return projectNode.get(OUT_JAR, ""); //$NON-NLS-1$
-    }
+		IScopeContext projectScope = new ProjectScope(project);
+		IEclipsePreferences projectNode = projectScope.getNode(AspectJPlugin.UI_PLUGIN_ID);
+		return projectNode.get(OUT_JAR, ""); //$NON-NLS-1$
+	}
 
-    public static String getProjectInpathOutFolder(IProject project) {
-        IScopeContext projectScope = new ProjectScope(project);
-        IEclipsePreferences projectNode = projectScope
-                .getNode(AspectJPlugin.UI_PLUGIN_ID);
-        return projectNode.get(INPATH_OUT_FOLDER, null);
-    }
+	public static String getProjectInpathOutFolder(IProject project) {
+		IScopeContext projectScope = new ProjectScope(project);
+		IEclipsePreferences projectNode = projectScope.getNode(AspectJPlugin.UI_PLUGIN_ID);
+		return projectNode.get(INPATH_OUT_FOLDER, null);
+	}
 
-    public static void setProjectOutJar(IProject project, String value) {
-        IScopeContext projectScope = new ProjectScope(project);
-        IEclipsePreferences projectNode = projectScope
-                .getNode(AspectJPlugin.UI_PLUGIN_ID);
-        projectNode.put(OUT_JAR, value);
-        if (value.length() == 0) {
-            projectNode.remove(OUT_JAR);
-        }
-        try {
-            projectNode.flush();
-        } catch (BackingStoreException e) {
-        }
-    }
+	public static void setProjectOutJar(IProject project, String value) {
+		IScopeContext projectScope = new ProjectScope(project);
+		IEclipsePreferences projectNode = projectScope.getNode(AspectJPlugin.UI_PLUGIN_ID);
+		projectNode.put(OUT_JAR, value);
+		if (value.length() == 0) {
+			projectNode.remove(OUT_JAR);
+		}
+		try {
+			projectNode.flush();
+		} catch (BackingStoreException e) {
+		}
+	}
 
-    public static void setProjectInpathOutFolder(IProject project, String value) {
-        IScopeContext projectScope = new ProjectScope(project);
-        IEclipsePreferences projectNode = projectScope
-                .getNode(AspectJPlugin.UI_PLUGIN_ID);
-        if (value == null || value.length() == 0) {
-            projectNode.remove(INPATH_OUT_FOLDER);
-        } else {
-            projectNode.put(INPATH_OUT_FOLDER, value);
-        }
-        try {
-            projectNode.flush();
-        } catch (BackingStoreException e) {
-        }
-    }
+	public static void setProjectInpathOutFolder(IProject project, String value) {
+		IScopeContext projectScope = new ProjectScope(project);
+		IEclipsePreferences projectNode = projectScope.getNode(AspectJPlugin.UI_PLUGIN_ID);
+		if (value == null || value.length() == 0) {
+			projectNode.remove(INPATH_OUT_FOLDER);
+		} else {
+			projectNode.put(INPATH_OUT_FOLDER, value);
+		}
+		try {
+			projectNode.flush();
+		} catch (BackingStoreException e) {
+		}
+	}
 
-    public static void setProjectAspectPath(IProject project, String path,
-            String cKinds, String eKinds) {
-        setProjectPath(project, path, cKinds, eKinds, ASPECTPATH_ATTRIBUTE);
-    }
-    public static String[] getRawProjectAspectPath(IProject project) {
-        return internalGetProjectPath(project, ASPECTPATH_ATTRIBUTE, false);
-    }
-    
-    public static String[] getResolvedProjectAspectPath(IProject project) {
-        return internalGetProjectPath(project, ASPECTPATH_ATTRIBUTE, true);
-    }
-    
+	public static void setProjectAspectPath(IProject project, String path, String cKinds, String eKinds) {
+		setProjectPath(project, path, cKinds, eKinds, ASPECTPATH_ATTRIBUTE);
+	}
+
+	public static String[] getRawProjectAspectPath(IProject project) {
+		return internalGetProjectPath(project, ASPECTPATH_ATTRIBUTE, false);
+	}
+
+	public static String[] getResolvedProjectAspectPath(IProject project) {
+		return internalGetProjectPath(project, ASPECTPATH_ATTRIBUTE, true);
+	}
 
 	public static void addToAspectPath(IProject project, IClasspathEntry entry) {
 		IJavaProject jp = JavaCore.create(project);
-		addAttribute(jp,entry,AspectJCorePreferences.ASPECTPATH_ATTRIBUTE);
+		addAttribute(jp, entry, AspectJCorePreferences.ASPECTPATH_ATTRIBUTE);
 	}
 
 	public static void removeFromAspectPath(IProject project, IClasspathEntry entry) {
 		IJavaProject jp = JavaCore.create(project);
-		removeAttribute(jp,entry,AspectJCorePreferences.ASPECTPATH_ATTRIBUTE);
+		removeAttribute(jp, entry, AspectJCorePreferences.ASPECTPATH_ATTRIBUTE);
 	}
-	
-   public static void addToAspectPath(IProject project, String jarPath, int eKind) {
-       addAttribute(project, jarPath, eKind, ASPECTPATH_ATTRIBUTE);
-   }
 
+	public static void addToAspectPath(IProject project, String jarPath, int eKind) {
+		addAttribute(project, jarPath, eKind, ASPECTPATH_ATTRIBUTE);
+	}
 
 	public static boolean isOnAspectpath(IClasspathEntry entry) {
 		IClasspathAttribute[] attributes = entry.getExtraAttributes();
 		for (int j = 0; j < attributes.length; j++) {
 			if (isAspectPathAttribute(attributes[j])) {
-				return true;								
+				return true;
 			}
 		}
 		return false;
 	}
-	
+
 	public static boolean isAspectPathAttribute(IClasspathAttribute attribute) {
 		return attribute.getName().equals(AspectJCorePreferences.ASPECTPATH_ATTRIBUTE.getName());
 	}
 
-    /**
-     * determines if an element is on the aspect path taking into account
-     * the restrictions of the classpath container entry
-     */
-    public static boolean isOnAspectpathWithRestrictions(IClasspathEntry entry, String item) {
-        if (!isOnAspectpath(entry)) {
-            return false;
-        }
-        
-        Set<String> restrictions = findContainerRestrictions(entry, true);
-        if (restrictions == null) {
-            // no restrictions, assume the jar entry is on the path
-            return true;
-        } else {
-            for (String restriction : restrictions) {
-                if (item.indexOf(restriction) != -1) {
-                    return true;
-                }
-            }
-            return false;
-        }
-    }
-    
-    /**
-     * determines if an element is on the aspect path taking into account
-     * the restrictions of the classpath container entry
-     */
-    public static boolean isOnInpathWithRestrictions(IClasspathEntry entry, String item) {
-        if (!isOnInpath(entry)) {
-            return false;
-        }
-        
-        Set<String> restrictions = findContainerRestrictions(entry, false);
-        if (restrictions == null || restrictions.isEmpty()) {
-            // no restrictions, assume the jar entry is on the path
-            return true;
-        } else {
-            for (String restriction : restrictions) {
-                if (item.indexOf(restriction) != -1) {
-                    return true;
-                }
-            }
-            return false;
-        }
-    }
-    
-	
-	
-    /**
-     * Checks to see if an entry is already on the aspect path
-     */
+	/**
+	 * determines if an element is on the aspect path taking into account the
+	 * restrictions of the classpath container entry
+	 */
+	public static boolean isOnAspectpathWithRestrictions(IClasspathEntry entry, String item) {
+		if (!isOnAspectpath(entry)) {
+			return false;
+		}
+
+		Set<String> restrictions = findContainerRestrictions(entry, true);
+		if (restrictions == null) {
+			// no restrictions, assume the jar entry is on the path
+			return true;
+		} else {
+			for (String restriction : restrictions) {
+				if (item.indexOf(restriction) != -1) {
+					return true;
+				}
+			}
+			return false;
+		}
+	}
+
+	/**
+	 * determines if an element is on the aspect path taking into account the
+	 * restrictions of the classpath container entry
+	 */
+	public static boolean isOnInpathWithRestrictions(IClasspathEntry entry, String item) {
+		if (!isOnInpath(entry)) {
+			return false;
+		}
+
+		Set<String> restrictions = findContainerRestrictions(entry, false);
+		if (restrictions == null || restrictions.isEmpty()) {
+			// no restrictions, assume the jar entry is on the path
+			return true;
+		} else {
+			for (String restriction : restrictions) {
+				if (item.indexOf(restriction) != -1) {
+					return true;
+				}
+			}
+			return false;
+		}
+	}
+
+	/**
+	 * Checks to see if an entry is already on the aspect path
+	 */
 	public static boolean isOnAspectpath(IProject project, String path) {
 		IJavaProject jp = JavaCore.create(project);
 		try {
@@ -235,13 +225,12 @@
 						|| (cp[i].getEntryKind() == IClasspathEntry.CPE_PROJECT)) {
 					IClasspathEntry resolvedClasspathEntry = JavaCore.getResolvedClasspathEntry(cp[i]);
 					if (resolvedClasspathEntry != null) {
-                        String entry = resolvedClasspathEntry
-    							.getPath().toPortableString();
-    					if (entry.equals(path)) {
-    						if (isOnAspectpath(cp[i])) {
-    							return true;
-    						}
-    					}
+						String entry = resolvedClasspathEntry.getPath().toPortableString();
+						if (entry.equals(path)) {
+							if (isOnAspectpath(cp[i])) {
+								return true;
+							}
+						}
 					}
 				}
 			}
@@ -251,215 +240,219 @@
 	}
 
 	public static String[] getRawProjectInpath(IProject project) {
-        return internalGetProjectPath(project, INPATH_ATTRIBUTE, false);
-    }
+		return internalGetProjectPath(project, INPATH_ATTRIBUTE, false);
+	}
 
-    public static String[] getResolvedProjectInpath(IProject project) {
-        return internalGetProjectPath(project, INPATH_ATTRIBUTE, true);
-    }
+	public static String[] getResolvedProjectInpath(IProject project) {
+		return internalGetProjectPath(project, INPATH_ATTRIBUTE, true);
+	}
 
-    public static List<IClasspathEntry> resolveDependentProjectClasspath(IClasspathEntry projEntry, IProject requiredProj) {
-        // add all output locations and exported classpath entities
-        // AspectJ compiler doesn't understand the concept of a java project
-        List<IClasspathEntry> actualEntries = new ArrayList<IClasspathEntry>();
-        
+	public static List<IClasspathEntry> resolveDependentProjectClasspath(IClasspathEntry projEntry,
+			IProject requiredProj) {
+		// add all output locations and exported classpath entities
+		// AspectJ compiler doesn't understand the concept of a java project
+		List<IClasspathEntry> actualEntries = new ArrayList<IClasspathEntry>();
 
-        try {
-            JavaProject requiredJavaProj = (JavaProject) JavaCore.create(requiredProj);
-            // bug 288395 Do not use the default mechanism for resolving classpath here
-            // this will look into jar files at the Classpath header in the jar's manifest
-            // and include jar files that are potentially missing, but have no effect on
-            // the build.
-            Object resolvedClasspath = requiredJavaProj.resolveClasspath(requiredJavaProj.getRawClasspath(), true, false);
-            IClasspathEntry[] requiredEntries = extractRequiredEntries(resolvedClasspath);
-            for (int i = 0; i < requiredEntries.length; i++) {
-                IClasspathEntry requiredEntry = requiredEntries[i];
-                if (requiredEntry.getEntryKind() == IClasspathEntry.CPE_SOURCE) {
+		try {
+			JavaProject requiredJavaProj = (JavaProject) JavaCore.create(requiredProj);
+			// bug 288395 Do not use the default mechanism for resolving
+			// classpath here
+			// this will look into jar files at the Classpath header in the
+			// jar's manifest
+			// and include jar files that are potentially missing, but have no
+			// effect on
+			// the build.
+			Object resolvedClasspath = requiredJavaProj.resolveClasspath(requiredJavaProj.getRawClasspath(), true,
+					false);
+			IClasspathEntry[] requiredEntries = extractRequiredEntries(resolvedClasspath);
+			for (int i = 0; i < requiredEntries.length; i++) {
+				IClasspathEntry requiredEntry = requiredEntries[i];
+				if (requiredEntry.getEntryKind() == IClasspathEntry.CPE_SOURCE) {
 
-                    // always add source entries even if not explicitly exported
-                    // don't add the source folder itself, but instead add the outfolder
-                    IPath outputLocation = requiredEntry.getOutputLocation();
-                    if (outputLocation != null) {
-            	        IAccessRule[] rules = projEntry.getAccessRules();
-                	    IClasspathAttribute[] attributes = projEntry.getExtraAttributes();
+					// always add source entries even if not explicitly exported
+					// don't add the source folder itself, but instead add the
+					// outfolder
+					IPath outputLocation = requiredEntry.getOutputLocation();
+					if (outputLocation != null) {
+						IAccessRule[] rules = projEntry.getAccessRules();
+						IClasspathAttribute[] attributes = projEntry.getExtraAttributes();
 
-                	    // only add the out folder if it already exists
-                	    if (requiredProj.getFolder(outputLocation.removeFirstSegments(1)).exists()) {
-                            IClasspathEntry outFolder = JavaCore.newLibraryEntry(outputLocation,
-                                    requiredEntry.getPath(),
-                                    requiredProj.getFullPath(), rules, attributes, projEntry.isExported());
-                            actualEntries.add(outFolder);
-                	    }
-                    }
-                } else if (requiredEntry.isExported()) {
-                    // must recur through this entry and add entries that it contains
-                    actualEntries.addAll(resolveClasspath(requiredEntry, requiredProj));
-                    
-                }
-            } // for (int i = 0; i < requiredEntries.length; i++)
-            
-            IPath outputLocation = requiredJavaProj.getOutputLocation();
-            // Output location may not exist.  Do not put output location of required project
-            // on path unless it exists
-            boolean exists = false;
-            // bug 244330 check to see if the project folder is also the output folder
-            if (outputLocation.segmentCount() == 1) {
-            	exists = true;
-            } else {
-            	if (requiredProj.getWorkspace().getRoot().getFolder(outputLocation).exists()) {
-            		exists = true;
-            	}
-            }
-            
-            if (exists) {
-                IClasspathEntry outFolder = JavaCore.newLibraryEntry(outputLocation,
-                                                                     null,
-                                                                     requiredProj.getFullPath());					                
-                actualEntries.add(outFolder);
-            }
-        } catch (JavaModelException e) {
-        }
-        return actualEntries;
-    }
+						// only add the out folder if it already exists
+						if (requiredProj.getFolder(outputLocation.removeFirstSegments(1)).exists()) {
+							IClasspathEntry outFolder = JavaCore.newLibraryEntry(outputLocation,
+									requiredEntry.getPath(), requiredProj.getFullPath(), rules, attributes,
+									projEntry.isExported());
+							actualEntries.add(outFolder);
+						}
+					}
+				} else if (requiredEntry.isExported()) {
+					// must recur through this entry and add entries that it
+					// contains
+					actualEntries.addAll(resolveClasspath(requiredEntry, requiredProj));
 
-    
-    /**
-     * resolvedClasspath is a package protected static class inside JavaProject
-     * must use reflection to access it 
-     */
-    @SuppressWarnings({ "unchecked" })
-    private static IClasspathEntry[] extractRequiredEntries(
-            Object resolvedClasspath) {
-        
-        try {
-            Class resolvedClasspathClass = Class.forName("org.eclipse.jdt.internal.core.JavaProject$ResolvedClasspath");
-            return (IClasspathEntry[]) ReflectionUtils.getPrivateField(resolvedClasspathClass, "resolvedClasspath", resolvedClasspath);
-        } catch (Exception e) {
-            return new IClasspathEntry[0];
-        }
-    }
+				}
+			} // for (int i = 0; i < requiredEntries.length; i++)
 
-    public static List<IClasspathEntry> resolveClasspathContainer(IClasspathEntry classpathContainerEntry, IProject thisProject) 
-            throws JavaModelException {
-        IJavaProject thisJavaProject = JavaCore.create(thisProject);
-        IClasspathContainer container = 
-            JavaCore.getClasspathContainer(classpathContainerEntry.getPath(), thisJavaProject);
-        if (container != null) {
-            List<IClasspathEntry> actualEntries = new ArrayList<IClasspathEntry>();
-            IClasspathEntry[] containerEntries = container.getClasspathEntries();
-            for (int i = 0; i < containerEntries.length; i++) {
-                // projects must be resolved specially since the AspectJ doesn't understand the 
-                // concept of project
-                switch (containerEntries[i].getEntryKind()) {
-                    case IClasspathEntry.CPE_PROJECT:
-                        IProject requiredProj = thisProject.getWorkspace().getRoot().getProject(
-                                containerEntries[i].getPath().makeRelative().toPortableString());
-                        if (! requiredProj.getName().equals(thisProject.getName())   
-                                && requiredProj.exists()) {
-                            actualEntries.addAll(resolveDependentProjectClasspath(containerEntries[i], requiredProj));
-                        }
-                        break;
+			IPath outputLocation = requiredJavaProj.getOutputLocation();
+			// Output location may not exist. Do not put output location of
+			// required project
+			// on path unless it exists
+			boolean exists = false;
+			// bug 244330 check to see if the project folder is also the output
+			// folder
+			if (outputLocation.segmentCount() == 1) {
+				exists = true;
+			} else {
+				if (requiredProj.getWorkspace().getRoot().getFolder(outputLocation).exists()) {
+					exists = true;
+				}
+			}
 
-                    case IClasspathEntry.CPE_VARIABLE:
-                        IClasspathEntry resolvedClasspathEntry = JavaCore.getResolvedClasspathEntry(
-                                containerEntries[i]);
-                        if (resolvedClasspathEntry != null) {
-                            actualEntries.add(
-                                    resolvedClasspathEntry);
-                        }
-                        break;
-                        
-                    case IClasspathEntry.CPE_CONTAINER:
-                        // not sure if we can have this, but try anyway
-                        actualEntries.addAll(resolveClasspathContainer(containerEntries[i], thisProject));
-                        break;
-                    case IClasspathEntry.CPE_LIBRARY:
-                        actualEntries.add(containerEntries[i]);
-                        break;
-                    default:
-                        // do nothing
-                }
-            }
-            return actualEntries;
-        } else {
-            return Collections.emptyList();
-        }
-    }
-    
-    /**
-     * Resolves a single classpath entry
-     * @param entry the classpath entry to resolve
-     * @param thisProject the java project that has this entry
-     * @return the resolved list of classpath entries
-     * @throws JavaModelException 
-     */
-    public static List<IClasspathEntry> resolveClasspath(IClasspathEntry entry, IProject thisProject) throws JavaModelException {
-        switch(entry.getEntryKind()) {
-            case IClasspathEntry.CPE_CONTAINER:
-                return resolveClasspathContainer(entry, thisProject);
-                
-            case IClasspathEntry.CPE_LIBRARY:
-                return Collections.singletonList(entry);
-                
-            case IClasspathEntry.CPE_PROJECT:
-                IProject containedProj = thisProject.getWorkspace().getRoot().getProject(
-                        entry.getPath().makeRelative().toPortableString());
-                if (! containedProj.getName().equals(thisProject.getName())   
-                        && containedProj.exists()) {
-                    return resolveDependentProjectClasspath(entry, containedProj);
-                } else {
-                    return Collections.emptyList();
-                }
-                    
-            case IClasspathEntry.CPE_VARIABLE:
-                IClasspathEntry resolvedClasspathEntry = JavaCore.getResolvedClasspathEntry(entry);
-                if (resolvedClasspathEntry != null) {
-                    return Collections.singletonList(resolvedClasspathEntry);
-                } else {
-                    return Collections.emptyList();
-                }
-            default:
-                return Collections.emptyList();
-        }
-    }
+			if (exists) {
+				IClasspathEntry outFolder = JavaCore.newLibraryEntry(outputLocation, null, requiredProj.getFullPath());
+				actualEntries.add(outFolder);
+			}
+		} catch (JavaModelException e) {
+		}
+		return actualEntries;
+	}
 
-	public static void setProjectInPath(IProject project, String path,
-			String cKinds, String eKinds) {
-        setProjectPath(project, path, cKinds, eKinds, INPATH_ATTRIBUTE);
+	/**
+	 * resolvedClasspath is a package protected static class inside JavaProject
+	 * must use reflection to access it
+	 */
+	@SuppressWarnings({ "unchecked" })
+	private static IClasspathEntry[] extractRequiredEntries(Object resolvedClasspath) {
+
+		try {
+			Class resolvedClasspathClass = Class.forName("org.eclipse.jdt.internal.core.JavaProject$ResolvedClasspath");
+			return (IClasspathEntry[]) ReflectionUtils.getPrivateField(resolvedClasspathClass, "resolvedClasspath",
+					resolvedClasspath);
+		} catch (Exception e) {
+			return new IClasspathEntry[0];
+		}
+	}
+
+	public static List<IClasspathEntry> resolveClasspathContainer(IClasspathEntry classpathContainerEntry,
+			IProject thisProject) throws JavaModelException {
+		IJavaProject thisJavaProject = JavaCore.create(thisProject);
+		IClasspathContainer container = JavaCore.getClasspathContainer(classpathContainerEntry.getPath(),
+				thisJavaProject);
+		if (container != null) {
+			List<IClasspathEntry> actualEntries = new ArrayList<IClasspathEntry>();
+			IClasspathEntry[] containerEntries = container.getClasspathEntries();
+			for (int i = 0; i < containerEntries.length; i++) {
+				// projects must be resolved specially since the AspectJ doesn't
+				// understand the
+				// concept of project
+				switch (containerEntries[i].getEntryKind()) {
+				case IClasspathEntry.CPE_PROJECT:
+					IProject requiredProj = thisProject.getWorkspace().getRoot()
+							.getProject(containerEntries[i].getPath().makeRelative().toPortableString());
+					if (!requiredProj.getName().equals(thisProject.getName()) && requiredProj.exists()) {
+						actualEntries.addAll(resolveDependentProjectClasspath(containerEntries[i], requiredProj));
+					}
+					break;
+
+				case IClasspathEntry.CPE_VARIABLE:
+					IClasspathEntry resolvedClasspathEntry = JavaCore.getResolvedClasspathEntry(containerEntries[i]);
+					if (resolvedClasspathEntry != null) {
+						actualEntries.add(resolvedClasspathEntry);
+					}
+					break;
+
+				case IClasspathEntry.CPE_CONTAINER:
+					// not sure if we can have this, but try anyway
+					actualEntries.addAll(resolveClasspathContainer(containerEntries[i], thisProject));
+					break;
+				case IClasspathEntry.CPE_LIBRARY:
+					actualEntries.add(containerEntries[i]);
+					break;
+				default:
+					// do nothing
+				}
+			}
+			return actualEntries;
+		} else {
+			return Collections.emptyList();
+		}
+	}
+
+	/**
+	 * Resolves a single classpath entry
+	 * 
+	 * @param entry
+	 *            the classpath entry to resolve
+	 * @param thisProject
+	 *            the java project that has this entry
+	 * @return the resolved list of classpath entries
+	 * @throws JavaModelException
+	 */
+	public static List<IClasspathEntry> resolveClasspath(IClasspathEntry entry, IProject thisProject)
+			throws JavaModelException {
+		switch (entry.getEntryKind()) {
+		case IClasspathEntry.CPE_CONTAINER:
+			return resolveClasspathContainer(entry, thisProject);
+
+		case IClasspathEntry.CPE_LIBRARY:
+			return Collections.singletonList(entry);
+
+		case IClasspathEntry.CPE_PROJECT:
+			IProject containedProj = thisProject.getWorkspace().getRoot()
+					.getProject(entry.getPath().makeRelative().toPortableString());
+			if (!containedProj.getName().equals(thisProject.getName()) && containedProj.exists()) {
+				return resolveDependentProjectClasspath(entry, containedProj);
+			} else {
+				return Collections.emptyList();
+			}
+
+		case IClasspathEntry.CPE_VARIABLE:
+			IClasspathEntry resolvedClasspathEntry = JavaCore.getResolvedClasspathEntry(entry);
+			if (resolvedClasspathEntry != null) {
+				return Collections.singletonList(resolvedClasspathEntry);
+			} else {
+				return Collections.emptyList();
+			}
+		default:
+			return Collections.emptyList();
+		}
+	}
+
+	public static void setProjectInPath(IProject project, String path, String cKinds, String eKinds) {
+		setProjectPath(project, path, cKinds, eKinds, INPATH_ATTRIBUTE);
 	}
 
 	public static void addToInPath(IProject project, IClasspathEntry entry) {
 		IJavaProject jp = JavaCore.create(project);
-		addAttribute(jp,entry,AspectJCorePreferences.INPATH_ATTRIBUTE);
-	}
-	
-	public static void removeFromInPath(IProject project, IClasspathEntry entry) {
-		IJavaProject jp = JavaCore.create(project);
-		removeAttribute(jp,entry,AspectJCorePreferences.INPATH_ATTRIBUTE);
-	}
-	
-	public static void addToInPath(IProject project, String jarPath, int eKind) {
-	    addAttribute(project, jarPath, eKind, INPATH_ATTRIBUTE);
+		addAttribute(jp, entry, AspectJCorePreferences.INPATH_ATTRIBUTE);
 	}
 
-	
-    public static boolean isOnInpath(IClasspathEntry entry) {
+	public static void removeFromInPath(IProject project, IClasspathEntry entry) {
+		IJavaProject jp = JavaCore.create(project);
+		removeAttribute(jp, entry, AspectJCorePreferences.INPATH_ATTRIBUTE);
+	}
+
+	public static void addToInPath(IProject project, String jarPath, int eKind) {
+		addAttribute(project, jarPath, eKind, INPATH_ATTRIBUTE);
+	}
+
+	public static boolean isOnInpath(IClasspathEntry entry) {
 		IClasspathAttribute[] attributes = entry.getExtraAttributes();
 		for (int j = 0; j < attributes.length; j++) {
 			if (isInPathAttribute(attributes[j])) {
-				return true;								
+				return true;
 			}
 		}
 		return false;
 	}
-    
-    public static boolean isOnPath(IClasspathEntry entry, boolean aspectpath) {
-        return aspectpath ? isOnAspectpath(entry) : isOnInpath(entry);
-    }
+
+	public static boolean isOnPath(IClasspathEntry entry, boolean aspectpath) {
+		return aspectpath ? isOnAspectpath(entry) : isOnInpath(entry);
+	}
 
 	/**
-     * Checks to see if an entry is already on the Inpath
-     */
+	 * Checks to see if an entry is already on the Inpath
+	 */
 	public static boolean isOnInpath(IProject project, String jarPath) {
 		IJavaProject jp = JavaCore.create(project);
 		try {
@@ -467,16 +460,16 @@
 			for (int i = 0; i < cp.length; i++) {
 				if ((cp[i].getEntryKind() == IClasspathEntry.CPE_LIBRARY)
 						|| (cp[i].getEntryKind() == IClasspathEntry.CPE_VARIABLE)
-				        || (cp[i].getEntryKind() == IClasspathEntry.CPE_CONTAINER)
-				        || (cp[i].getEntryKind() == IClasspathEntry.CPE_PROJECT)) {
+						|| (cp[i].getEntryKind() == IClasspathEntry.CPE_CONTAINER)
+						|| (cp[i].getEntryKind() == IClasspathEntry.CPE_PROJECT)) {
 					IClasspathEntry resolvedClasspathEntry = JavaCore.getResolvedClasspathEntry(cp[i]);
 					if (resolvedClasspathEntry != null) {
-					    String entry = resolvedClasspathEntry.getPath().toPortableString();
-    					if (entry.equals(jarPath)) {
-    						if (isOnInpath(cp[i])) {
-    							return true;
-    						}
-    					}
+						String entry = resolvedClasspathEntry.getPath().toPortableString();
+						if (entry.equals(jarPath)) {
+							if (isOnInpath(cp[i])) {
+								return true;
+							}
+						}
 					}
 				}
 			}
@@ -484,467 +477,460 @@
 		}
 		return false;
 	}
-	
 
 	public static boolean isInPathAttribute(IClasspathAttribute attribute) {
 		return attribute.getName().equals(AspectJCorePreferences.INPATH_ATTRIBUTE.getName());
 	}
 
+	public static void setIncrementalCompilationOptimizationsEnabled(boolean value) {
+		IEclipsePreferences store = AspectJPlugin.getDefault().getPreferences();
+		store.putBoolean(OPTION_IncrementalCompilationOptimizations, value);
+	}
 
-    public static void setIncrementalCompilationOptimizationsEnabled(boolean value) {
-        IEclipsePreferences store = AspectJPlugin.getDefault()
-                .getPreferences();
-        store.putBoolean(OPTION_IncrementalCompilationOptimizations, value);
-    }
-    
-    /**
-     * Searches the raw classpath for entries whose paths contain
-     * the strings in putOnPath.
-     * 
-     * Then ensures that these classpath entries are on the aspect path
-     */
-    public static void augmentAspectPath(IProject project, String[] putOnAspectPath) {
-        if (putOnAspectPath.length == 0) {
-            // nothing to do!
-            return;
-        }
-        IJavaProject jp = JavaCore.create(project);
-        List<IClasspathEntry> toPutOnAspectPath = new ArrayList<IClasspathEntry>();
-        try {
-            IClasspathEntry[] cp = jp.getRawClasspath();
-            for (int i = 0; i < cp.length; i++) {
-                String path = cp[i].getPath().toPortableString();
-                for (int j = 0; j < putOnAspectPath.length; j++) {
-                    if (path.indexOf(putOnAspectPath[j]) != -1) {
-                        toPutOnAspectPath.add(cp[i]);
-                    }
-                }
-            }
-            
-            for (IClasspathEntry entry : toPutOnAspectPath) {
-                if (! isOnAspectpath(entry)) {
-                    addToAspectPath(project, entry);
-                }
-            }
-        } catch (JavaModelException e) {
-        }
-    }
+	/**
+	 * Searches the raw classpath for entries whose paths contain the strings in
+	 * putOnPath.
+	 * 
+	 * Then ensures that these classpath entries are on the aspect path
+	 */
+	public static void augmentAspectPath(IProject project, String[] putOnAspectPath) {
+		if (putOnAspectPath.length == 0) {
+			// nothing to do!
+			return;
+		}
+		IJavaProject jp = JavaCore.create(project);
+		List<IClasspathEntry> toPutOnAspectPath = new ArrayList<IClasspathEntry>();
+		try {
+			IClasspathEntry[] cp = jp.getRawClasspath();
+			for (int i = 0; i < cp.length; i++) {
+				String path = cp[i].getPath().toPortableString();
+				for (int j = 0; j < putOnAspectPath.length; j++) {
+					if (path.indexOf(putOnAspectPath[j]) != -1) {
+						toPutOnAspectPath.add(cp[i]);
+					}
+				}
+			}
 
-    /**
-     * Checks to see if the compiler option for incremental build optimizations
-     * is on or off
-     * 
-     * On by default
-     * @return
-     */
-    public static boolean isIncrementalCompilationOptimizationsEnabled() {
-        IEclipsePreferences store = AspectJPlugin.getDefault()
-                .getPreferences();
-        return store.getBoolean(OPTION_IncrementalCompilationOptimizations, true);
-    }
+			for (IClasspathEntry entry : toPutOnAspectPath) {
+				if (!isOnAspectpath(entry)) {
+					addToAspectPath(project, entry);
+				}
+			}
+		} catch (JavaModelException e) {
+		}
+	}
 
-    private static void setProjectPath(IProject project, String path,
-            String cKinds, String eKinds, IClasspathAttribute attribute) {
-    	IJavaProject javaProject = JavaCore.create(project);		
-    	removeAttribute(javaProject, attribute);
-    	
-    	StringTokenizer pathTok = new StringTokenizer(path, File.pathSeparator);
-    	StringTokenizer eKindsTok = new StringTokenizer(eKinds, File.pathSeparator);
-    	int index = 1;
-    	while (pathTok.hasMoreTokens() && eKindsTok.hasMoreTokens()) {
-    		String entry = pathTok.nextToken();
-    		int eKind = Integer.parseInt(eKindsTok.nextToken());
-    		if (ASPECTPATH_ATTRIBUTE.equals(attribute)) {
-    		    addToAspectPath(project,entry, eKind);
-    		} else if (INPATH_ATTRIBUTE.equals(attribute)) {
-    		    addToInPath(project,entry, eKind);
-    		}
-    		index++;
-    	}
-    }
+	/**
+	 * Checks to see if the compiler option for incremental build optimizations
+	 * is on or off
+	 * 
+	 * On by default
+	 * 
+	 * @return
+	 */
+	public static boolean isIncrementalCompilationOptimizationsEnabled() {
+		IEclipsePreferences store = AspectJPlugin.getDefault().getPreferences();
+		return store.getBoolean(OPTION_IncrementalCompilationOptimizations, true);
+	}
 
-    
-    private static boolean shouldCheckOldStylePath(IProject project, String pathKind) {
-        IScopeContext projectScope = new ProjectScope(project);
-        IEclipsePreferences projectNode = projectScope
-                .getNode(AspectJPlugin.UI_PLUGIN_ID);
-        return projectNode.get(pathKind, "").length() == 0 && projectNode.get(pathKind + "1", "").length() > 0;
-    }
+	private static void setProjectPath(IProject project, String path, String cKinds, String eKinds,
+			IClasspathAttribute attribute) {
+		IJavaProject javaProject = JavaCore.create(project);
+		removeAttribute(javaProject, attribute);
 
-    private static void markOldStylePathAsRead(IProject project, String pathKind) {
-        IScopeContext projectScope = new ProjectScope(project);
-        IEclipsePreferences projectNode = projectScope
-                .getNode(AspectJPlugin.UI_PLUGIN_ID);
-        projectNode.put(pathKind, "visited");
-        try {
-            projectNode.flush();
-        } catch (BackingStoreException e) {
-        }
-    }
-    
-    private static String[] getOldProjectPath(IProject project, boolean aspectPath) {
-        String pathName;
-        String pathConKinds;
-        String pathEntKinds;
-        if (aspectPath) {
-            pathName = ASPECTPATH;
-            pathConKinds = ASPECTPATH_CON_KINDS;
-            pathEntKinds = ASPECTPATH_ENT_KINDS;
-        } else {
-            pathName = INPATH;
-            pathConKinds = INPATH_CON_KINDS;
-            pathEntKinds = INPATH_ENT_KINDS;
-        }
-        
-    	IScopeContext projectScope = new ProjectScope(project);
-    	IEclipsePreferences projectNode = projectScope
-    			.getNode(AspectJPlugin.UI_PLUGIN_ID);
-    	String pathString = ""; //$NON-NLS-1$
-    	int index = 1;
-    	String value = projectNode.get(pathName + index, ""); //$NON-NLS-1$
-    	if (value.length() == 0) {
-    		return null;
-    	}
-    	while (value.length() > 0) {
-    		pathString += value;
-    		pathString += File.pathSeparator;
-    		index++;
-    		value = projectNode.get(pathName + index, ""); //$NON-NLS-1$
-    	}
-    
-    	String contentString = ""; //$NON-NLS-1$
-    	index = 1;
-    	value = projectNode.get(pathConKinds + index, ""); //$NON-NLS-1$
-    	while (value.length() > 0) {
-    		contentString += toContentKind(value.toUpperCase());
-    		contentString += File.pathSeparator;
-    		index++;
-    		value = projectNode.get(pathConKinds + index, ""); //$NON-NLS-1$
-    	}
-    
-    	String entryString = ""; //$NON-NLS-1$
-    	index = 1;
-    	value = projectNode.get(pathEntKinds + index, ""); //$NON-NLS-1$
-    	while (value.length() > 0) {
-    		entryString += toEntryKind(value.toUpperCase());
-    		entryString += File.pathSeparator;
-    		index++;
-    		value = projectNode.get(pathEntKinds + index, ""); //$NON-NLS-1$
-    	}
-    	return new String[] { pathString, contentString, entryString };
-    }
+		StringTokenizer pathTok = new StringTokenizer(path, File.pathSeparator);
+		StringTokenizer eKindsTok = new StringTokenizer(eKinds, File.pathSeparator);
+		int index = 1;
+		while (pathTok.hasMoreTokens() && eKindsTok.hasMoreTokens()) {
+			String entry = pathTok.nextToken();
+			int eKind = Integer.parseInt(eKindsTok.nextToken());
+			if (ASPECTPATH_ATTRIBUTE.equals(attribute)) {
+				addToAspectPath(project, entry, eKind);
+			} else if (INPATH_ATTRIBUTE.equals(attribute)) {
+				addToInPath(project, entry, eKind);
+			}
+			index++;
+		}
+	}
 
-    /**
-     * Firstly, add library to the Java build path if it's not there already,
-     * then mark the entry as being on the aspect path
-     * @param project
-     * @param path
-     */
-    private static void addAttribute(IProject project, String jarPath, int eKind, IClasspathAttribute attribute) {
-    	IJavaProject jp = JavaCore.create(project);
-    	
-    	
-    	try {
-            IClasspathEntry[] cp = jp.getRawClasspath();
-            int cpIndex = getIndexInBuildPathEntry(cp, jarPath);
-            if (cpIndex >= 0) { // already on classpath
-                // add attribute to classpath entry
-                // if it doesn't already exist
-                IClasspathEntry pathAdd = cp[cpIndex];
-                // only add attribute if this element is not already on the path
-                if (isAspectPathAttribute(attribute) ? 
-                        !isOnAspectpath(pathAdd) :
-                        !isOnInpath(pathAdd)) {  
-                    IClasspathAttribute[] attributes = pathAdd.getExtraAttributes();
-                    IClasspathAttribute[] newattrib = new IClasspathAttribute[attributes.length + 1];
-                    System.arraycopy(attributes, 0, newattrib, 0, attributes.length);
-                    newattrib[attributes.length] = attribute;
-                    switch(pathAdd.getEntryKind()) {
-                        case IClasspathEntry.CPE_LIBRARY:
-                            pathAdd = JavaCore.newLibraryEntry(pathAdd.getPath(),
-                                    pathAdd.getSourceAttachmentPath(), 
-                                    pathAdd.getSourceAttachmentRootPath(),
-                                    pathAdd.getAccessRules(), newattrib, 
-                                    pathAdd.isExported());
-                            break;
-                            
-                        case IClasspathEntry.CPE_VARIABLE:
-                            pathAdd = JavaCore.newVariableEntry(pathAdd.getPath(),
-                                    pathAdd.getSourceAttachmentPath(), 
-                                    pathAdd.getSourceAttachmentRootPath(),
-                                    pathAdd.getAccessRules(), newattrib, 
-                                    pathAdd.isExported());
-                            break;
-    
-                        case IClasspathEntry.CPE_CONTAINER:
-                            pathAdd = JavaCore.newContainerEntry(pathAdd.getPath(),
-                                    pathAdd.getAccessRules(), newattrib, 
-                                    pathAdd.isExported());
-                            break;
-                            
-                        case IClasspathEntry.CPE_PROJECT:
-                            pathAdd = JavaCore.newProjectEntry(pathAdd.getPath(), 
-                                    pathAdd.getAccessRules(), 
-                                    true, newattrib, pathAdd.isExported());
-                            break;
-                    }
-                    
-                    cp[cpIndex] = pathAdd;
-                    jp.setRawClasspath(cp, null);
-                }
-    		} else {
-    			addEntryToJavaBuildPath(jp, attribute, jarPath, eKind);
-    		}
-    	} catch (JavaModelException e) {
-    	}
-    }
+	private static boolean shouldCheckOldStylePath(IProject project, String pathKind) {
+		IScopeContext projectScope = new ProjectScope(project);
+		IEclipsePreferences projectNode = projectScope.getNode(AspectJPlugin.UI_PLUGIN_ID);
+		return projectNode.get(pathKind, "").length() == 0 && projectNode.get(pathKind + "1", "").length() > 0;
+	}
 
-    private static String[] internalGetProjectPath(IProject project, IClasspathAttribute attribute, boolean useResolvedPath) {
-        if (isAspectPathAttribute(attribute)) {
-            if (shouldCheckOldStylePath(project, ASPECTPATH)) {
-        		String[] old = getOldProjectPath(project, true);
-        		if (old != null) {
-        			AJLog.log("Migrating aspect path settings for project "+project.getName()); //$NON-NLS-1$
-        			setProjectAspectPath(project,old[0],old[1],old[2]);
-        		}
-        		markOldStylePathAsRead(project, ASPECTPATH);
-            }
-        } else { // INPATH_ATTRIBUTE
-            if (shouldCheckOldStylePath(project, INPATH)) {
-                String[] old = getOldProjectPath(project, false);
-                if (old != null) {
-                    AJLog.log("Migrating aspect path settings for project "+project.getName()); //$NON-NLS-1$
-                    setProjectInPath(project,old[0],old[1],old[2]);
-                }
-                markOldStylePathAsRead(project, INPATH);
-            }
-        }
-    	String pathString = ""; //$NON-NLS-1$
-    	String contentString = ""; //$NON-NLS-1$
-    	String entryString = ""; //$NON-NLS-1$
-    
-    	IJavaProject javaProject = JavaCore.create(project);
-    	try {
-            IClasspathEntry[] cp = javaProject.getRawClasspath();
-    		for (int i = 0; i < cp.length; i++) {
-    			IClasspathAttribute[] attributes = cp[i].getExtraAttributes();
-    			boolean attributeFound = false;
-    			for (int j = 0; j < attributes.length; j++) {
-    				if (attributes[j].getName().equals(attribute.getName())) {
-    				    attributeFound = true;
-    				    List<IClasspathEntry> actualEntries = new ArrayList<IClasspathEntry>();
-    				    
-    				    if (useResolvedPath) {
-    				        // this entry is on the path.  must resolve it
-    				        if (cp[i].getEntryKind() == IClasspathEntry.CPE_CONTAINER) {
-    				            List<IClasspathEntry>containerEntries = resolveClasspathContainer(cp[i], project);
-    				            // Bug 273770 - look for the XXXPATH_RESTRICTION_ATTRIBUTE_NAME classpath attribute
-    				            Set<String> extraPathElements = findContainerRestrictions(cp[i], isAspectPathAttribute(attribute));
-    				            if (extraPathElements != null && extraPathElements.size() > 0) {
-    				                // must filter
-    				                for (Iterator<IClasspathEntry> cpIter = containerEntries.iterator(); cpIter.hasNext(); ) {
-    				                    IClasspathEntry containerEntry = cpIter.next();
-    				                    if (!containsAsPathFragment(extraPathElements, containerEntry)) {
-    				                        cpIter.remove();
-    				                    }
-    				                }
-    				            }
-    				            actualEntries.addAll(containerEntries);
-    				        } else if (cp[i].getEntryKind() == IClasspathEntry.CPE_PROJECT) {
-    				            IProject requiredProj = project.getWorkspace().getRoot().getProject(
-    				                    cp[i].getPath().makeRelative().toPortableString());
-    				            if (! requiredProj.getName().equals(project.getName())   
-    				                    && requiredProj.exists()) {
-    					            actualEntries.addAll(resolveDependentProjectClasspath(cp[i], requiredProj));
-    				            }
-    				        } else { // resolve the classpath variable
-    				        	IClasspathEntry resolved = JavaCore.getResolvedClasspathEntry(cp[i]);
-    				        	if (resolved != null) {
-        				        	if (resolved.getEntryKind() == IClasspathEntry.CPE_PROJECT) {
-        				        		// must resolve the project
-        				        		actualEntries.addAll(resolveDependentProjectClasspath(resolved, project.getWorkspace().getRoot().getProject(resolved.getPath().toString())));
-        				        	} else {
-        				        		actualEntries.add(resolved);
-        				        	}
-    				        	}
-    				        } // cp[i].getEntryKind()
-    				    } else {
-    				        actualEntries.add(cp[i]);
-    				    } // useResolvedEntry
-    				    
-    				    for (IClasspathEntry actualEntry : actualEntries) {
-    				        // we can get null for actualEntry if the raw entry corresponds to 
-    				        // an unbound classpath variable
-    				        if (actualEntry != null) {
-    	                        pathString += actualEntry.getPath().toPortableString() + File.pathSeparator;
-    	                        contentString += actualEntry.getContentKind() + File.pathSeparator;
-    	                        entryString += actualEntry.getEntryKind() + File.pathSeparator;
-    				        }
-    				    }
-    				}  // attributes[j].equals(attribute)
-    			}  // for (int j = 0; j < attributes.length; j++)
-    			
-    			// there is a special case that we must look inside the classpath container for entries with
-    			// attributes if we are returning the resolved path and the container itself isn't already
-    			// on the path.
-    			if (!attributeFound && useResolvedPath && cp[i].getEntryKind() == IClasspathEntry.CPE_CONTAINER) {
-    			    List<IClasspathEntry> containerEntries = resolveClasspathContainer(cp[i], project);
-    			    
-    			    for (IClasspathEntry containerEntry : containerEntries) {
-    			        if (isOnPath(containerEntry, isAspectPathAttribute(attribute))) {
-    			            pathString += containerEntry.getPath().toPortableString() + File.pathSeparator;
-    			            contentString += containerEntry.getContentKind() + File.pathSeparator;
-    			            entryString += containerEntry.getEntryKind() + File.pathSeparator;
-    			        }
-    			    }  // for (Iterator cpIter = containerEntries.iterator(); cpIter.hasNext(); ) 
-    			}  // !attributeFound && useResolvedPath && cp[i].getEntryKind() == IClasspathEntry.CPE_CONTAINER
-    		}  // for (int i = 0; i < cp.length; i++)
-    	} catch (JavaModelException e) {
-    	}
-    	return new String[] { pathString, contentString, entryString };
-    }
+	private static void markOldStylePathAsRead(IProject project, String pathKind) {
+		IScopeContext projectScope = new ProjectScope(project);
+		IEclipsePreferences projectNode = projectScope.getNode(AspectJPlugin.UI_PLUGIN_ID);
+		projectNode.put(pathKind, "visited");
+		try {
+			projectNode.flush();
+		} catch (BackingStoreException e) {
+		}
+	}
 
-    public static boolean containsAsPathFragment(Set<String> extraPathElements,
-            IClasspathEntry containerEntry) {
-        if (extraPathElements.size() == 0) {
-            return false;
-        }
-        String pathStr = containerEntry.getPath().toString();
-        for (String extraPathStr : extraPathElements) {
-            if (pathStr.indexOf(extraPathStr) != -1) {
-                return true;
-            }
-        }
-        return false;
-    }
+	private static String[] getOldProjectPath(IProject project, boolean aspectPath) {
+		String pathName;
+		String pathConKinds;
+		String pathEntKinds;
+		if (aspectPath) {
+			pathName = ASPECTPATH;
+			pathConKinds = ASPECTPATH_CON_KINDS;
+			pathEntKinds = ASPECTPATH_ENT_KINDS;
+		} else {
+			pathName = INPATH;
+			pathConKinds = INPATH_CON_KINDS;
+			pathEntKinds = INPATH_ENT_KINDS;
+		}
 
-    private static Set<String> findContainerRestrictions(IClasspathEntry containerEntry,
-            boolean isAspectPathAttribute) {
-        if (containerEntry.getEntryKind() != IClasspathEntry.CPE_CONTAINER) {
-            return Collections.emptySet();
-        }
-        Set<String> restrictionPaths = new HashSet<String>();
-        String restrictions = getRestriction(containerEntry, 
-                isAspectPathAttribute ? ASPECTPATH_RESTRICTION_ATTRIBUTE_NAME : INPATH_RESTRICTION_ATTRIBUTE_NAME);
-        if (restrictions != null) {
-            String[] restrictionsArr = restrictions.split(",");
-            for (int j = 0; j < restrictionsArr.length; j++) {
-                restrictionPaths.add(restrictionsArr[j].trim());
-            }
-            return restrictionPaths;
-        } else {
-            return null;
-        }
-    }
+		IScopeContext projectScope = new ProjectScope(project);
+		IEclipsePreferences projectNode = projectScope.getNode(AspectJPlugin.UI_PLUGIN_ID);
+		String pathString = ""; //$NON-NLS-1$
+		int index = 1;
+		String value = projectNode.get(pathName + index, ""); //$NON-NLS-1$
+		if (value.length() == 0) {
+			return null;
+		}
+		while (value.length() > 0) {
+			pathString += value;
+			pathString += File.pathSeparator;
+			index++;
+			value = projectNode.get(pathName + index, ""); //$NON-NLS-1$
+		}
 
-    private static void addAttribute(IJavaProject jp, IClasspathEntry entry, IClasspathAttribute attr) {
-    	try {
-    		IClasspathEntry[] cp = jp.getRawClasspath();
-    		for (int i = 0; i < cp.length; i++) {
-    			if (cp[i].equals(entry)) {
-    				IClasspathAttribute[] attributes = cp[i].getExtraAttributes();
-    				IClasspathAttribute[] newattrib = new IClasspathAttribute[attributes.length + 1];
-    				System.arraycopy(attributes, 0, newattrib, 0, attributes.length);
-    				newattrib[attributes.length] = attr;
-    				switch (cp[i].getEntryKind()) {
-                        case IClasspathEntry.CPE_LIBRARY:
-                            cp[i] = JavaCore.newLibraryEntry(cp[i].getPath(),
-                                    cp[i].getSourceAttachmentPath(), 
-                                    cp[i].getSourceAttachmentRootPath(),
-                                    cp[i].getAccessRules(), newattrib, 
-                                    cp[i].isExported());
-                            break;
-    
-                        case IClasspathEntry.CPE_VARIABLE:
-                            cp[i] = JavaCore.newVariableEntry(cp[i].getPath(),
-                                    cp[i].getSourceAttachmentPath(), 
-                                    cp[i].getSourceAttachmentRootPath(),
-                                    cp[i].getAccessRules(), newattrib, 
-                                    cp[i].isExported());
-                            break;
-    
-                        case IClasspathEntry.CPE_CONTAINER:
-                            cp[i] = JavaCore.newContainerEntry(cp[i].getPath(),
-                                    cp[i].getAccessRules(), newattrib, 
-                                    cp[i].isExported());
-                            break;
-    
-                        case IClasspathEntry.CPE_PROJECT:
-                            cp[i] = JavaCore.newProjectEntry(cp[i].getPath(), 
-                                    cp[i].getAccessRules(), true, newattrib,
-                                    cp[i].isExported());
-                            break;
-    
-                    }
-    			}
-    		}
-    		jp.setRawClasspath(cp, null);
-    	} catch (JavaModelException e) {
-    	}
-    }
+		String contentString = ""; //$NON-NLS-1$
+		index = 1;
+		value = projectNode.get(pathConKinds + index, ""); //$NON-NLS-1$
+		while (value.length() > 0) {
+			contentString += toContentKind(value.toUpperCase());
+			contentString += File.pathSeparator;
+			index++;
+			value = projectNode.get(pathConKinds + index, ""); //$NON-NLS-1$
+		}
 
-    public static void removeAttribute(IJavaProject jp, IClasspathEntry entry, IClasspathAttribute attr) {
-    	try {
-    		IClasspathEntry[] cp = jp.getRawClasspath();
-    		for (int i = 0; i < cp.length; i++) {
-    			if (cp[i].equals(entry)) {
-    				IClasspathAttribute[] attributes = cp[i].getExtraAttributes();
-    				IClasspathAttribute[] newattrib = new IClasspathAttribute[attributes.length - 1];
-    				int count = 0;
-    				for (int j = 0; j < attributes.length; j++) {
-    					if (!attributes[j].getName().equals(attr.getName())) {
-    						newattrib[count++] = attributes[j];
-    					}
-    				}
-                    switch(cp[i].getEntryKind()) {
-                        case IClasspathEntry.CPE_LIBRARY:
-                            cp[i] = JavaCore.newLibraryEntry(cp[i].getPath(),
-                                    cp[i].getSourceAttachmentPath(), cp[i]
-                                            .getSourceAttachmentRootPath(),
-                                    cp[i].getAccessRules(), newattrib, cp[i]
-                                            .isExported());
-                            break;
-                            
-                        case IClasspathEntry.CPE_VARIABLE:
-                            cp[i] = JavaCore.newVariableEntry(cp[i].getPath(),
-                                    cp[i].getSourceAttachmentPath(), cp[i]
-                                            .getSourceAttachmentRootPath(),
-                                    cp[i].getAccessRules(), newattrib, cp[i]
-                                            .isExported());                     
-                            break;
-    
-                        case IClasspathEntry.CPE_CONTAINER:
-                            cp[i] = JavaCore.newContainerEntry(cp[i].getPath(),
-                                    cp[i].getAccessRules(), newattrib, cp[i]
-                                            .isExported());                     
-                            break;
-                            
-                        case IClasspathEntry.CPE_PROJECT:
-                            cp[i] = JavaCore.newProjectEntry(cp[i].getPath(), 
-                                    cp[i].getAccessRules(), 
-                                    true, newattrib, cp[i].isExported());
-                            break;
-                    }
-    			}
-    		}
-    		jp.setRawClasspath(cp, null);
-    	} catch (JavaModelException e) {
-    	}
-    }
+		String entryString = ""; //$NON-NLS-1$
+		index = 1;
+		value = projectNode.get(pathEntKinds + index, ""); //$NON-NLS-1$
+		while (value.length() > 0) {
+			entryString += toEntryKind(value.toUpperCase());
+			entryString += File.pathSeparator;
+			index++;
+			value = projectNode.get(pathEntKinds + index, ""); //$NON-NLS-1$
+		}
+		return new String[] { pathString, contentString, entryString };
+	}
 
-    /**
+	/**
+	 * Firstly, add library to the Java build path if it's not there already,
+	 * then mark the entry as being on the aspect path
+	 * 
+	 * @param project
+	 * @param path
+	 */
+	private static void addAttribute(IProject project, String jarPath, int eKind, IClasspathAttribute attribute) {
+		IJavaProject jp = JavaCore.create(project);
+
+		try {
+			IClasspathEntry[] cp = jp.getRawClasspath();
+			int cpIndex = getIndexInBuildPathEntry(cp, jarPath);
+			if (cpIndex >= 0) { // already on classpath
+				// add attribute to classpath entry
+				// if it doesn't already exist
+				IClasspathEntry pathAdd = cp[cpIndex];
+				// only add attribute if this element is not already on the path
+				if (isAspectPathAttribute(attribute) ? !isOnAspectpath(pathAdd) : !isOnInpath(pathAdd)) {
+					IClasspathAttribute[] attributes = pathAdd.getExtraAttributes();
+					IClasspathAttribute[] newattrib = new IClasspathAttribute[attributes.length + 1];
+					System.arraycopy(attributes, 0, newattrib, 0, attributes.length);
+					newattrib[attributes.length] = attribute;
+					switch (pathAdd.getEntryKind()) {
+					case IClasspathEntry.CPE_LIBRARY:
+						pathAdd = JavaCore.newLibraryEntry(pathAdd.getPath(), pathAdd.getSourceAttachmentPath(),
+								pathAdd.getSourceAttachmentRootPath(), pathAdd.getAccessRules(), newattrib,
+								pathAdd.isExported());
+						break;
+
+					case IClasspathEntry.CPE_VARIABLE:
+						pathAdd = JavaCore.newVariableEntry(pathAdd.getPath(), pathAdd.getSourceAttachmentPath(),
+								pathAdd.getSourceAttachmentRootPath(), pathAdd.getAccessRules(), newattrib,
+								pathAdd.isExported());
+						break;
+
+					case IClasspathEntry.CPE_CONTAINER:
+						pathAdd = JavaCore.newContainerEntry(pathAdd.getPath(), pathAdd.getAccessRules(), newattrib,
+								pathAdd.isExported());
+						break;
+
+					case IClasspathEntry.CPE_PROJECT:
+						pathAdd = JavaCore.newProjectEntry(pathAdd.getPath(), pathAdd.getAccessRules(), true, newattrib,
+								pathAdd.isExported());
+						break;
+					}
+
+					cp[cpIndex] = pathAdd;
+					jp.setRawClasspath(cp, null);
+				}
+			} else {
+				addEntryToJavaBuildPath(jp, attribute, jarPath, eKind);
+			}
+		} catch (JavaModelException e) {
+		}
+	}
+
+	private static String[] internalGetProjectPath(IProject project, IClasspathAttribute attribute,
+			boolean useResolvedPath) {
+		if (isAspectPathAttribute(attribute)) {
+			if (shouldCheckOldStylePath(project, ASPECTPATH)) {
+				String[] old = getOldProjectPath(project, true);
+				if (old != null) {
+					AJLog.log("Migrating aspect path settings for project " + project.getName()); //$NON-NLS-1$
+					setProjectAspectPath(project, old[0], old[1], old[2]);
+				}
+				markOldStylePathAsRead(project, ASPECTPATH);
+			}
+		} else { // INPATH_ATTRIBUTE
+			if (shouldCheckOldStylePath(project, INPATH)) {
+				String[] old = getOldProjectPath(project, false);
+				if (old != null) {
+					AJLog.log("Migrating aspect path settings for project " + project.getName()); //$NON-NLS-1$
+					setProjectInPath(project, old[0], old[1], old[2]);
+				}
+				markOldStylePathAsRead(project, INPATH);
+			}
+		}
+		String pathString = ""; //$NON-NLS-1$
+		String contentString = ""; //$NON-NLS-1$
+		String entryString = ""; //$NON-NLS-1$
+
+		IJavaProject javaProject = JavaCore.create(project);
+		try {
+			IClasspathEntry[] cp = javaProject.getRawClasspath();
+			AJLog.log("internalGetProjectPath: iterating over classpath entries, size #"+(cp==null?0:cp.length));
+			for (int i = 0; i < cp.length; i++) {
+				IClasspathAttribute[] attributes = cp[i].getExtraAttributes();
+				AJLog.log("internalGetProjectPath: attributes on "+cp[i].getPath()+" are "+toString(attributes));
+				boolean attributeFound = false;
+				for (int j = 0; j < attributes.length; j++) {
+					if (attributes[j].getName().equals(attribute.getName())) {
+						attributeFound = true;
+						List<IClasspathEntry> actualEntries = new ArrayList<IClasspathEntry>();
+
+						if (useResolvedPath) {
+							// this entry is on the path. must resolve it
+							if (cp[i].getEntryKind() == IClasspathEntry.CPE_CONTAINER) {
+								List<IClasspathEntry> containerEntries = resolveClasspathContainer(cp[i], project);
+								// Bug 273770 - look for the
+								// XXXPATH_RESTRICTION_ATTRIBUTE_NAME classpath
+								// attribute
+								Set<String> extraPathElements = findContainerRestrictions(cp[i],
+										isAspectPathAttribute(attribute));
+								if (extraPathElements != null && extraPathElements.size() > 0) {
+									// must filter
+									for (Iterator<IClasspathEntry> cpIter = containerEntries.iterator(); cpIter
+											.hasNext();) {
+										IClasspathEntry containerEntry = cpIter.next();
+										if (!containsAsPathFragment(extraPathElements, containerEntry)) {
+											cpIter.remove();
+										}
+									}
+								}
+								actualEntries.addAll(containerEntries);
+							} else if (cp[i].getEntryKind() == IClasspathEntry.CPE_PROJECT) {
+								IProject requiredProj = project.getWorkspace().getRoot()
+										.getProject(cp[i].getPath().makeRelative().toPortableString());
+								if (!requiredProj.getName().equals(project.getName()) && requiredProj.exists()) {
+									actualEntries.addAll(resolveDependentProjectClasspath(cp[i], requiredProj));
+								}
+							} else { // resolve the classpath variable
+								IClasspathEntry resolved = JavaCore.getResolvedClasspathEntry(cp[i]);
+								if (resolved != null) {
+									if (resolved.getEntryKind() == IClasspathEntry.CPE_PROJECT) {
+										// must resolve the project
+										actualEntries.addAll(resolveDependentProjectClasspath(resolved, project
+												.getWorkspace().getRoot().getProject(resolved.getPath().toString())));
+									} else {
+										actualEntries.add(resolved);
+									}
+								}
+							} // cp[i].getEntryKind()
+						} else {
+							actualEntries.add(cp[i]);
+						} // useResolvedEntry
+
+						for (IClasspathEntry actualEntry : actualEntries) {
+							// we can get null for actualEntry if the raw entry
+							// corresponds to
+							// an unbound classpath variable
+							if (actualEntry != null) {
+								pathString += actualEntry.getPath().toPortableString() + File.pathSeparator;
+								contentString += actualEntry.getContentKind() + File.pathSeparator;
+								entryString += actualEntry.getEntryKind() + File.pathSeparator;
+							}
+						}
+					} // attributes[j].equals(attribute)
+				} // for (int j = 0; j < attributes.length; j++)
+
+				// there is a special case that we must look inside the
+				// classpath container for entries with
+				// attributes if we are returning the resolved path and the
+				// container itself isn't already
+				// on the path.
+				if (!attributeFound && useResolvedPath && cp[i].getEntryKind() == IClasspathEntry.CPE_CONTAINER) {
+					List<IClasspathEntry> containerEntries = resolveClasspathContainer(cp[i], project);
+
+					for (IClasspathEntry containerEntry : containerEntries) {
+						if (isOnPath(containerEntry, isAspectPathAttribute(attribute))) {
+							pathString += containerEntry.getPath().toPortableString() + File.pathSeparator;
+							contentString += containerEntry.getContentKind() + File.pathSeparator;
+							entryString += containerEntry.getEntryKind() + File.pathSeparator;
+						}
+					} // for (Iterator cpIter = containerEntries.iterator();
+						// cpIter.hasNext(); )
+				} // !attributeFound && useResolvedPath && cp[i].getEntryKind()
+					// == IClasspathEntry.CPE_CONTAINER
+			} // for (int i = 0; i < cp.length; i++)
+		} catch (JavaModelException e) {
+		}
+		return new String[] { pathString, contentString, entryString };
+	}
+
+	private static String toString(IClasspathAttribute[] attributes) {
+		StringBuilder s = new StringBuilder();
+		if (attributes != null) {
+			for (IClasspathAttribute ca: attributes) {
+				s.append(ca.getName()+"="+ca.getValue()+" ");
+			}
+		}
+		return s.toString().trim();
+	}
+
+	public static boolean containsAsPathFragment(Set<String> extraPathElements, IClasspathEntry containerEntry) {
+		if (extraPathElements.size() == 0) {
+			return false;
+		}
+		String pathStr = containerEntry.getPath().toString();
+		for (String extraPathStr : extraPathElements) {
+			if (pathStr.indexOf(extraPathStr) != -1) {
+				return true;
+			}
+		}
+		return false;
+	}
+
+	private static Set<String> findContainerRestrictions(IClasspathEntry containerEntry,
+			boolean isAspectPathAttribute) {
+		if (containerEntry.getEntryKind() != IClasspathEntry.CPE_CONTAINER) {
+			return Collections.emptySet();
+		}
+		Set<String> restrictionPaths = new HashSet<String>();
+		String restrictions = getRestriction(containerEntry,
+				isAspectPathAttribute ? ASPECTPATH_RESTRICTION_ATTRIBUTE_NAME : INPATH_RESTRICTION_ATTRIBUTE_NAME);
+		if (restrictions != null) {
+			String[] restrictionsArr = restrictions.split(",");
+			for (int j = 0; j < restrictionsArr.length; j++) {
+				restrictionPaths.add(restrictionsArr[j].trim());
+			}
+			return restrictionPaths;
+		} else {
+			return null;
+		}
+	}
+
+	private static void addAttribute(IJavaProject jp, IClasspathEntry entry, IClasspathAttribute attr) {
+		try {
+			IClasspathEntry[] cp = jp.getRawClasspath();
+			for (int i = 0; i < cp.length; i++) {
+				if (cp[i].equals(entry)) {
+					IClasspathAttribute[] attributes = cp[i].getExtraAttributes();
+					IClasspathAttribute[] newattrib = new IClasspathAttribute[attributes.length + 1];
+					System.arraycopy(attributes, 0, newattrib, 0, attributes.length);
+					newattrib[attributes.length] = attr;
+					switch (cp[i].getEntryKind()) {
+					case IClasspathEntry.CPE_LIBRARY:
+						cp[i] = JavaCore.newLibraryEntry(cp[i].getPath(), cp[i].getSourceAttachmentPath(),
+								cp[i].getSourceAttachmentRootPath(), cp[i].getAccessRules(), newattrib,
+								cp[i].isExported());
+						break;
+
+					case IClasspathEntry.CPE_VARIABLE:
+						cp[i] = JavaCore.newVariableEntry(cp[i].getPath(), cp[i].getSourceAttachmentPath(),
+								cp[i].getSourceAttachmentRootPath(), cp[i].getAccessRules(), newattrib,
+								cp[i].isExported());
+						break;
+
+					case IClasspathEntry.CPE_CONTAINER:
+						cp[i] = JavaCore.newContainerEntry(cp[i].getPath(), cp[i].getAccessRules(), newattrib,
+								cp[i].isExported());
+						break;
+
+					case IClasspathEntry.CPE_PROJECT:
+						cp[i] = JavaCore.newProjectEntry(cp[i].getPath(), cp[i].getAccessRules(), true, newattrib,
+								cp[i].isExported());
+						break;
+
+					}
+				}
+			}
+			jp.setRawClasspath(cp, null);
+		} catch (JavaModelException e) {
+		}
+	}
+
+	public static void removeAttribute(IJavaProject jp, IClasspathEntry entry, IClasspathAttribute attr) {
+		try {
+			IClasspathEntry[] cp = jp.getRawClasspath();
+			for (int i = 0; i < cp.length; i++) {
+				if (cp[i].equals(entry)) {
+					IClasspathAttribute[] attributes = cp[i].getExtraAttributes();
+					IClasspathAttribute[] newattrib = new IClasspathAttribute[attributes.length - 1];
+					int count = 0;
+					for (int j = 0; j < attributes.length; j++) {
+						if (!attributes[j].getName().equals(attr.getName())) {
+							newattrib[count++] = attributes[j];
+						}
+					}
+					switch (cp[i].getEntryKind()) {
+					case IClasspathEntry.CPE_LIBRARY:
+						cp[i] = JavaCore.newLibraryEntry(cp[i].getPath(), cp[i].getSourceAttachmentPath(),
+								cp[i].getSourceAttachmentRootPath(), cp[i].getAccessRules(), newattrib,
+								cp[i].isExported());
+						break;
+
+					case IClasspathEntry.CPE_VARIABLE:
+						cp[i] = JavaCore.newVariableEntry(cp[i].getPath(), cp[i].getSourceAttachmentPath(),
+								cp[i].getSourceAttachmentRootPath(), cp[i].getAccessRules(), newattrib,
+								cp[i].isExported());
+						break;
+
+					case IClasspathEntry.CPE_CONTAINER:
+						cp[i] = JavaCore.newContainerEntry(cp[i].getPath(), cp[i].getAccessRules(), newattrib,
+								cp[i].isExported());
+						break;
+
+					case IClasspathEntry.CPE_PROJECT:
+						cp[i] = JavaCore.newProjectEntry(cp[i].getPath(), cp[i].getAccessRules(), true, newattrib,
+								cp[i].isExported());
+						break;
+					}
+				}
+			}
+			jp.setRawClasspath(cp, null);
+		} catch (JavaModelException e) {
+		}
+	}
+
+	/**
 	 * Remove all occurrences of an attribute
+	 * 
 	 * @param javaProject
 	 * @param attribute
 	 */
-	private static void removeAttribute(IJavaProject javaProject,
-			IClasspathAttribute attribute) {
+	private static void removeAttribute(IJavaProject javaProject, IClasspathAttribute attribute) {
 		try {
 			IClasspathEntry[] cp = javaProject.getRawClasspath();
 			boolean changed = false;
 			for (int i = 0; i < cp.length; i++) {
-				IClasspathAttribute[] attributes = cp[i]
-						.getExtraAttributes();
+				IClasspathAttribute[] attributes = cp[i].getExtraAttributes();
 				boolean found = false;
 				for (int j = 0; !found && (j < attributes.length); j++) {
 					if (attributes[j].getName().equals(attribute.getName())) {
@@ -952,44 +938,37 @@
 					}
 				}
 				if (found) {
-				    changed = true;
+					changed = true;
 					IClasspathAttribute[] newattrib = new IClasspathAttribute[attributes.length - 1];
 					int count = 0;
 					for (int j = 0; j < attributes.length; j++) {
-						if (!attributes[j].getName()
-								.equals(attribute.getName())) {
+						if (!attributes[j].getName().equals(attribute.getName())) {
 							newattrib[count++] = attributes[j];
 						}
 					}
-                    switch(cp[i].getEntryKind()) {
-                        case IClasspathEntry.CPE_LIBRARY:
-                            cp[i] = JavaCore.newLibraryEntry(cp[i].getPath(),
-                                    cp[i].getSourceAttachmentPath(), 
-                                    cp[i].getSourceAttachmentRootPath(),
-                                    cp[i].getAccessRules(), newattrib, 
-                                    cp[i].isExported());
-                            break;
-                            
-                        case IClasspathEntry.CPE_VARIABLE:
-                            cp[i] = JavaCore.newVariableEntry(cp[i].getPath(),
-                                    cp[i].getSourceAttachmentPath(), 
-                                    cp[i].getSourceAttachmentRootPath(),
-                                    cp[i].getAccessRules(), newattrib, 
-                                    cp[i].isExported());
-                            break;
+					switch (cp[i].getEntryKind()) {
+					case IClasspathEntry.CPE_LIBRARY:
+						cp[i] = JavaCore.newLibraryEntry(cp[i].getPath(), cp[i].getSourceAttachmentPath(),
+								cp[i].getSourceAttachmentRootPath(), cp[i].getAccessRules(), newattrib,
+								cp[i].isExported());
+						break;
 
-                        case IClasspathEntry.CPE_CONTAINER:
-                            cp[i] = JavaCore.newContainerEntry(cp[i].getPath(),
-                                    cp[i].getAccessRules(), newattrib, 
-                                    cp[i].isExported());
-                            break;
-                            
-                        case IClasspathEntry.CPE_PROJECT:
-                            cp[i] = JavaCore.newProjectEntry(cp[i].getPath(), 
-                                    cp[i].getAccessRules(), 
-                                    true, newattrib, cp[i].isExported());
-                            break;
-                    }
+					case IClasspathEntry.CPE_VARIABLE:
+						cp[i] = JavaCore.newVariableEntry(cp[i].getPath(), cp[i].getSourceAttachmentPath(),
+								cp[i].getSourceAttachmentRootPath(), cp[i].getAccessRules(), newattrib,
+								cp[i].isExported());
+						break;
+
+					case IClasspathEntry.CPE_CONTAINER:
+						cp[i] = JavaCore.newContainerEntry(cp[i].getPath(), cp[i].getAccessRules(), newattrib,
+								cp[i].isExported());
+						break;
+
+					case IClasspathEntry.CPE_PROJECT:
+						cp[i] = JavaCore.newProjectEntry(cp[i].getPath(), cp[i].getAccessRules(), true, newattrib,
+								cp[i].isExported());
+						break;
+					}
 				}
 			}
 			if (changed) {
@@ -998,38 +977,34 @@
 		} catch (JavaModelException e) {
 		}
 	}
-	
-	
+
 	private static int getIndexInBuildPathEntry(IClasspathEntry[] cp, String jarPath) {
-        for (int i = 0; i < cp.length; i++) {
-            String entry = cp[i].getPath().toPortableString();
-            if (entry.equals(jarPath)) {
-                return i;
-            }
-        }
-        return -1;
+		for (int i = 0; i < cp.length; i++) {
+			String entry = cp[i].getPath().toPortableString();
+			if (entry.equals(jarPath)) {
+				return i;
+			}
+		}
+		return -1;
 	}
-	
-	
-	private static void addEntryToJavaBuildPath(IJavaProject jp,
-			IClasspathAttribute attribute, String path, int eKind) {
+
+	private static void addEntryToJavaBuildPath(IJavaProject jp, IClasspathAttribute attribute, String path,
+			int eKind) {
 		IClasspathAttribute[] attributes = new IClasspathAttribute[] { attribute };
 		try {
 			IClasspathEntry[] originalCP = jp.getRawClasspath();
 			IClasspathEntry[] newCP = new IClasspathEntry[originalCP.length + 1];
 			IClasspathEntry cp = null;
 			if (eKind == IClasspathEntry.CPE_LIBRARY) {
-				cp = JavaCore.newLibraryEntry(
-						new Path(path), null, null, new IAccessRule[0], attributes, false);
+				cp = JavaCore.newLibraryEntry(new Path(path), null, null, new IAccessRule[0], attributes, false);
 			} else if (eKind == IClasspathEntry.CPE_VARIABLE) {
-				cp = JavaCore.newVariableEntry(
-						new Path(path), null, null, new IAccessRule[0], attributes, false);
+				cp = JavaCore.newVariableEntry(new Path(path), null, null, new IAccessRule[0], attributes, false);
 			} else if (eKind == IClasspathEntry.CPE_CONTAINER) {
-			    cp = JavaCore.newContainerEntry(new Path(path), null, attributes, false);
+				cp = JavaCore.newContainerEntry(new Path(path), null, attributes, false);
 			} else if (eKind == IClasspathEntry.CPE_PROJECT) {
-			    cp = JavaCore.newProjectEntry(new Path(path), null, true, attributes, false);
+				cp = JavaCore.newProjectEntry(new Path(path), null, true, attributes, false);
 			}
-			
+
 			// Update the raw classpath with the new entry.
 			if (cp != null) {
 				System.arraycopy(originalCP, 0, newCP, 0, originalCP.length);
@@ -1067,137 +1042,131 @@
 		return new Integer(entry).toString();
 	}
 
-    public static String getRestriction(IClasspathEntry pathEntry, String attributeName) {
-        IClasspathAttribute[] attributes = pathEntry.getExtraAttributes();
-        for (int i = 0; i < attributes.length; i++) {
-            IClasspathAttribute attribute = attributes[i];
-            if (attribute.getName().equals(attributeName)) {
-                String extraStr = attribute.getValue();
-                if (extraStr != null) {
-                    return extraStr;
-                }
-            }
-        }
+	public static String getRestriction(IClasspathEntry pathEntry, String attributeName) {
+		IClasspathAttribute[] attributes = pathEntry.getExtraAttributes();
+		for (int i = 0; i < attributes.length; i++) {
+			IClasspathAttribute attribute = attributes[i];
+			if (attribute.getName().equals(attributeName)) {
+				String extraStr = attribute.getValue();
+				if (extraStr != null) {
+					return extraStr;
+				}
+			}
+		}
 
-        return null;
-    }
-    
-    /**
-     * adds the classpath attribute to the entry with the default value if it doesn't already exist
-     * else does nothing
-     */
-    public static IClasspathEntry ensureHasAttribute(IClasspathEntry curr, String attributeName, String defaultVal) {
-        int index = indexOfAttribute(curr.getExtraAttributes(), attributeName);
-        if (index < 0) {
-            IClasspathAttribute[] attrs = curr.getExtraAttributes();
-            // must create a new entry with more extra attributes
-            IClasspathAttribute newAttr = JavaCore.newClasspathAttribute(attributeName, defaultVal);
-            IClasspathAttribute[] newAttrs;
-            if (attrs == null || attrs.length == 0) {
-                newAttrs = new IClasspathAttribute[] { newAttr };
-            } else {
-                newAttrs = new IClasspathAttribute[attrs.length+1];
-                System.arraycopy(attrs, 0, newAttrs, 0, attrs.length);
-                newAttrs[attrs.length] = newAttr;
-            }
-            return copyContainerEntry(curr, newAttrs);
-        } else {
-            return curr;
-        }
-    }
-    
-    /**
-     * adds the classpath attribute to the entry with the default value if it doesn't already exist
-     * else does nothing
-     */
-    public static IClasspathEntry ensureHasNoAttribute(IClasspathEntry curr, String attributeName) {
-        int index = indexOfAttribute(curr.getExtraAttributes(), attributeName);
-        if (index < 0) {
-            return curr;
-        } else {
-            IClasspathAttribute[] attrs = curr.getExtraAttributes();
-            // must create a new entry with more extra attributes
-            IClasspathAttribute[] newAttrs = new IClasspathAttribute[attrs.length-1];
-            for (int i = 0, j = 0; i < newAttrs.length; i++) {
-                if (i != index) {
-                    newAttrs[j] = attrs[i];
-                    j++;
-                }
-            }
-            return copyContainerEntry(curr, newAttrs);
-        }
-    }
-    
+		return null;
+	}
 
+	/**
+	 * adds the classpath attribute to the entry with the default value if it
+	 * doesn't already exist else does nothing
+	 */
+	public static IClasspathEntry ensureHasAttribute(IClasspathEntry curr, String attributeName, String defaultVal) {
+		int index = indexOfAttribute(curr.getExtraAttributes(), attributeName);
+		if (index < 0) {
+			IClasspathAttribute[] attrs = curr.getExtraAttributes();
+			// must create a new entry with more extra attributes
+			IClasspathAttribute newAttr = JavaCore.newClasspathAttribute(attributeName, defaultVal);
+			IClasspathAttribute[] newAttrs;
+			if (attrs == null || attrs.length == 0) {
+				newAttrs = new IClasspathAttribute[] { newAttr };
+			} else {
+				newAttrs = new IClasspathAttribute[attrs.length + 1];
+				System.arraycopy(attrs, 0, newAttrs, 0, attrs.length);
+				newAttrs[attrs.length] = newAttr;
+			}
+			return copyContainerEntry(curr, newAttrs);
+		} else {
+			return curr;
+		}
+	}
 
-    public static IClasspathEntry copyContainerEntry(IClasspathEntry containerEntry, 
-            IClasspathAttribute[] extraAttrs) {
-        return JavaCore.newContainerEntry(containerEntry.getPath(), 
-                containerEntry.getAccessRules(), extraAttrs, containerEntry.isExported());
-    }
-    
-    private static int indexOfAttribute(IClasspathAttribute[] attrs,
-            String attrName) {
-        for (int i = 0; i < attrs.length; i++) {
-            if (attrs[i].getName().equals(attrName)) {
-                return i;
-            }
-        }
-        return -1;
-    }
+	/**
+	 * adds the classpath attribute to the entry with the default value if it
+	 * doesn't already exist else does nothing
+	 */
+	public static IClasspathEntry ensureHasNoAttribute(IClasspathEntry curr, String attributeName) {
+		int index = indexOfAttribute(curr.getExtraAttributes(), attributeName);
+		if (index < 0) {
+			return curr;
+		} else {
+			IClasspathAttribute[] attrs = curr.getExtraAttributes();
+			// must create a new entry with more extra attributes
+			IClasspathAttribute[] newAttrs = new IClasspathAttribute[attrs.length - 1];
+			for (int i = 0, j = 0; i < newAttrs.length; i++) {
+				if (i != index) {
+					newAttrs[j] = attrs[i];
+					j++;
+				}
+			}
+			return copyContainerEntry(curr, newAttrs);
+		}
+	}
 
+	public static IClasspathEntry copyContainerEntry(IClasspathEntry containerEntry, IClasspathAttribute[] extraAttrs) {
+		return JavaCore.newContainerEntry(containerEntry.getPath(), containerEntry.getAccessRules(), extraAttrs,
+				containerEntry.isExported());
+	}
 
-    
-    /**
-     * Adds the classpath restriction to the given classpath entry.
-     * Returns the new classpath entry
-     */
-    public static IClasspathEntry updatePathRestrictions(IClasspathEntry entry,
-            String restrictionStr, String restrictionKind) {
-        IClasspathAttribute[] attrs = entry.getExtraAttributes();
-        int index = indexOfAttribute(attrs, restrictionKind);
-        IClasspathAttribute newAttr = JavaCore.newClasspathAttribute(restrictionKind, restrictionStr);
-        if (index >= 0) {
-            // just replace
-            attrs[index] = newAttr;
-        } else {
-            // must create a new entry with more extra attributes
-            IClasspathAttribute[] newAttrs;
-            if (attrs == null || attrs.length == 0) {
-                newAttrs = new IClasspathAttribute[] { newAttr };
-            } else {
-                newAttrs = new IClasspathAttribute[attrs.length+1];
-                System.arraycopy(attrs, 0, newAttrs, 0, attrs.length);
-                newAttrs[attrs.length] = newAttr;
-            }
-            entry = copyContainerEntry(entry, newAttrs);
-        }
-        return entry;
-    }
+	private static int indexOfAttribute(IClasspathAttribute[] attrs, String attrName) {
+		for (int i = 0; i < attrs.length; i++) {
+			if (attrs[i].getName().equals(attrName)) {
+				return i;
+			}
+		}
+		return -1;
+	}
 
-    /**
-     * If this classpath entry's path already exists on the classpath, then it is replaced
-     * else it is added
-     */
-    public static void updateClasspathEntry(IProject project, IClasspathEntry newEntry) {
-        IJavaProject jProject = JavaCore.create(project);
-        try {
-            IClasspathEntry[] entries = jProject.getRawClasspath();
-            for (int i = 0; i < entries.length; i++) {
-                IClasspathEntry entry = entries[i];
-                if (newEntry.getPath().equals(entry.getPath())) {
-                    entries[i] = newEntry;
-                    jProject.setRawClasspath(entries, null);
-                    return;
-                }
-            }
-            
-            // entry not found on classpath...add it
-            IClasspathEntry[] newEntries = new IClasspathEntry[entries.length + 1];
-            System.arraycopy(entries, 0, newEntries, 0, entries.length);
-            newEntries[entries.length] = newEntry;
-            jProject.setRawClasspath(newEntries, null);
-        } catch (JavaModelException e) {
-        }
-    }
+	/**
+	 * Adds the classpath restriction to the given classpath entry. Returns the
+	 * new classpath entry
+	 */
+	public static IClasspathEntry updatePathRestrictions(IClasspathEntry entry, String restrictionStr,
+			String restrictionKind) {
+		IClasspathAttribute[] attrs = entry.getExtraAttributes();
+		int index = indexOfAttribute(attrs, restrictionKind);
+		IClasspathAttribute newAttr = JavaCore.newClasspathAttribute(restrictionKind, restrictionStr);
+		if (index >= 0) {
+			// just replace
+			attrs[index] = newAttr;
+		} else {
+			// must create a new entry with more extra attributes
+			IClasspathAttribute[] newAttrs;
+			if (attrs == null || attrs.length == 0) {
+				newAttrs = new IClasspathAttribute[] { newAttr };
+			} else {
+				newAttrs = new IClasspathAttribute[attrs.length + 1];
+				System.arraycopy(attrs, 0, newAttrs, 0, attrs.length);
+				newAttrs[attrs.length] = newAttr;
+			}
+			entry = copyContainerEntry(entry, newAttrs);
+		}
+		return entry;
+	}
+
+	/**
+	 * If this classpath entry's path already exists on the classpath, then it
+	 * is replaced else it is added
+	 */
+	public static void updateClasspathEntry(IProject project, IClasspathEntry newEntry) {
+		IJavaProject jProject = JavaCore.create(project);
+		try {
+			IClasspathEntry[] entries = jProject.getRawClasspath();
+			for (int i = 0; i < entries.length; i++) {
+				IClasspathEntry entry = entries[i];
+				if (newEntry.getPath().equals(entry.getPath())) {
+					entries[i] = newEntry;
+					jProject.setRawClasspath(entries, null);
+					return;
+				}
+			}
+
+			// entry not found on classpath...add it
+			IClasspathEntry[] newEntries = new IClasspathEntry[entries.length + 1];
+			System.arraycopy(entries, 0, newEntries, 0, entries.length);
+			newEntries[entries.length] = newEntry;
+			jProject.setRawClasspath(newEntries, null);
+		} catch (JavaModelException e) {
+		}
+	}
 }
