Sync bndlib code

git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1381708 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/bundleplugin/src/main/java/aQute/bnd/osgi/Analyzer.java b/bundleplugin/src/main/java/aQute/bnd/osgi/Analyzer.java
index 135f96c..860fe08 100755
--- a/bundleplugin/src/main/java/aQute/bnd/osgi/Analyzer.java
+++ b/bundleplugin/src/main/java/aQute/bnd/osgi/Analyzer.java
@@ -698,6 +698,10 @@
 		return apiUses;
 	}
 
+	public Packages getClasspathExports() {
+		return classpathExports;
+	}
+
 	/**
 	 * Get the version for this bnd
 	 * 
@@ -2035,6 +2039,8 @@
 				typeName = "extends";
 			else if (typeName.equalsIgnoreCase("importing"))
 				typeName = "imports";
+			else if (typeName.equalsIgnoreCase("annotation"))
+				typeName = "annotated";
 			else if (typeName.equalsIgnoreCase("implementing"))
 				typeName = "implements";
 
diff --git a/bundleplugin/src/main/java/aQute/bnd/osgi/Annotation.java b/bundleplugin/src/main/java/aQute/bnd/osgi/Annotation.java
index 0383962..aca0a11 100644
--- a/bundleplugin/src/main/java/aQute/bnd/osgi/Annotation.java
+++ b/bundleplugin/src/main/java/aQute/bnd/osgi/Annotation.java
@@ -62,8 +62,15 @@
 
 	public <T extends java.lang.annotation.Annotation> T getAnnotation() throws Exception {
 		String cname = name.getFQN();
-		Class<T> c = (Class<T>) getClass().getClassLoader().loadClass(cname);
-		return getAnnotation(c);
+		try {
+			Class<T> c = (Class<T>) getClass().getClassLoader().loadClass(cname);
+			return getAnnotation(c);
+		}
+		catch (ClassNotFoundException e) {
+		}
+		catch (NoClassDefFoundError e) {
+		}
+		return null;
 	}
 
 	public <T extends java.lang.annotation.Annotation> T getAnnotation(Class<T> c) throws Exception {
diff --git a/bundleplugin/src/main/java/aQute/bnd/osgi/Builder.java b/bundleplugin/src/main/java/aQute/bnd/osgi/Builder.java
index 2ee603a..b5ed9be 100755
--- a/bundleplugin/src/main/java/aQute/bnd/osgi/Builder.java
+++ b/bundleplugin/src/main/java/aQute/bnd/osgi/Builder.java
@@ -9,7 +9,6 @@
 
 import aQute.bnd.component.*;
 import aQute.bnd.differ.*;
-import aQute.bnd.differ.Baseline.Info;
 import aQute.bnd.header.*;
 import aQute.bnd.make.*;
 import aQute.bnd.make.component.*;
@@ -18,7 +17,6 @@
 import aQute.bnd.osgi.Descriptors.PackageRef;
 import aQute.bnd.osgi.Descriptors.TypeRef;
 import aQute.bnd.service.*;
-import aQute.bnd.service.RepositoryPlugin.Strategy;
 import aQute.bnd.service.diff.*;
 import aQute.lib.collections.*;
 import aQute.libg.generics.*;
@@ -309,8 +307,10 @@
 				}
 			}
 		}
-		if (jar.getDirectories().size() == 0)
+		if (jar.getDirectories().size() == 0) {
+			trace("extra dirs %s", jar.getDirectories());
 			return null;
+		}
 		return jar;
 	}
 
@@ -860,6 +860,7 @@
 
 		if (!destination.contains("${@}")) {
 			cr = new CombinedResource();
+			cr.lastModified = lastModified;
 		}
 		trace("last modified requires %s", lastModified);
 
@@ -869,9 +870,10 @@
 				String path = getReplacer().process(destination);
 				String command = getReplacer().process(cmd);
 				File file = getFile(item);
-
-				Resource r = new CommandResource(command, this, Math.max(lastModified,
-						file.exists() ? file.lastModified() : 0L));
+				if ( file.exists())
+					lastModified = Math.max(lastModified, file.lastModified());
+				
+				Resource r = new CommandResource(command, this, lastModified, getBase());
 
 				if (preprocess)
 					r = new PreprocessResource(this, r);
@@ -890,6 +892,8 @@
 		// to update the modified time.
 		if (cr != null)
 			jar.putResource(destination, cr);
+		
+		updateModified(lastModified, "Include-Resource: cmd");
 	}
 
 	private String doResourceDirectory(Jar jar, Map<String,String> extra, boolean preprocess, File sourceFile,
@@ -945,6 +949,10 @@
 				files.put(p, file);
 			}
 		}
+		if (fs.length == 0) {
+			File empty = new File(dir, Constants.EMPTY_HEADER);
+			files.put(appendPath(path, empty.getName()), empty);
+		}
 	}
 
 	private void noSuchFile(Jar jar, @SuppressWarnings("unused") String clause, Map<String,String> extra, String source, String destinationPath)
@@ -1065,6 +1073,8 @@
 				if (isTrue(extra.get(LIB_DIRECTIVE))) {
 					setProperty(BUNDLE_CLASSPATH, append(getProperty(BUNDLE_CLASSPATH), path));
 				}
+			} else if (from.getName().equals(Constants.EMPTY_HEADER)) {
+				jar.putResource(path, new EmbeddedResource(new byte[0], 0));
 			} else {
 				error("Input file does not exist: " + from);
 			}
@@ -1159,7 +1169,7 @@
 		Parameters subsMap = parseHeader(sub);
 		for (Iterator<String> i = subsMap.keySet().iterator(); i.hasNext();) {
 			File file = getFile(i.next());
-			if (file.isFile()) {
+			if (file.isFile() && !file.getName().startsWith(".")) {
 				builders.add(getSubBuilder(file));
 				i.remove();
 			}
@@ -1500,84 +1510,18 @@
 			show(c, indent, warning);
 	}
 
-	/**
-	 * Base line against a previous version
-	 * 
-	 * @throws Exception
-	 */
-
-	private void doBaseline(Jar dot) throws Exception {
-		Parameters diffs = parseHeader(getProperty("-baseline"));
-		if (diffs.isEmpty())
-			return;
-
-		System.err.printf("baseline %s%n", diffs);
-
-		Jar other = getBaselineJar();
-		if (other == null) {
-			return;
-		}
-		Baseline baseline = new Baseline(this, differ);
-		Set<Info> infos = baseline.baseline(dot, other, null);
-		for (Info info : infos) {
-			if (info.mismatch) {
-				error("%s %-50s %-10s %-10s %-10s %-10s %-10s\n", info.mismatch ? '*' : ' ', info.packageName,
-						info.packageDiff.getDelta(), info.newerVersion, info.olderVersion, info.suggestedVersion,
-						info.suggestedIfProviders == null ? "-" : info.suggestedIfProviders);
-			}
-		}
-	}
-
+	
 	public void addSourcepath(Collection<File> sourcepath) {
 		for (File f : sourcepath) {
 			addSourcepath(f);
 		}
 	}
 
-	public Jar getBaselineJar() throws Exception {
+	/**
+	 * Base line against a previous version. Should be overridden in the ProjectBuilder where we have access to the repos
+	 * 
+	 * @throws Exception
+	 */
 
-		List<RepositoryPlugin> repos = getPlugins(RepositoryPlugin.class);
-
-		Parameters diffs = parseHeader(getProperty("-baseline"));
-		File baselineFile = null;
-		if (diffs.isEmpty()) {
-			String repoName = getProperty("-baseline-repo");
-			if (repoName == null) {
-				return null;
-			}
-			for (RepositoryPlugin repo : repos) {
-				if (repoName.equals(repo.getName())) {
-					baselineFile = repo.get(getBsn(), null, Strategy.HIGHEST, null);
-					break;
-				}
-			}
-		} else {
-
-			String bsn = null;
-			String version = null;
-			for (Entry<String,Attrs> entry : diffs.entrySet()) {
-				bsn = entry.getKey();
-				if ("@".equals(bsn)) {
-					bsn = getBsn();
-				}
-				version = entry.getValue().get(Constants.VERSION_ATTRIBUTE);
-				break;
-			}
-	
-			for (RepositoryPlugin repo : repos) {
-				if (version == null) {
-					baselineFile = repo.get(bsn, null, Strategy.HIGHEST, null);
-				} else {
-					baselineFile = repo.get(bsn, version, Strategy.EXACT, null);
-				}
-				if (baselineFile != null) {
-					break;
-				}
-			}
-		}
-		if (baselineFile == null) {
-			return new Jar(".");
-		}
-		return new Jar(baselineFile);
-	}
+	protected void doBaseline(Jar dot) throws Exception {}
 }
diff --git a/bundleplugin/src/main/java/aQute/bnd/osgi/ClassDataCollector.java b/bundleplugin/src/main/java/aQute/bnd/osgi/ClassDataCollector.java
index c2daba7..17aa62e 100644
--- a/bundleplugin/src/main/java/aQute/bnd/osgi/ClassDataCollector.java
+++ b/bundleplugin/src/main/java/aQute/bnd/osgi/ClassDataCollector.java
@@ -2,28 +2,28 @@
 
 import aQute.bnd.osgi.Descriptors.TypeRef;
 
+@SuppressWarnings("unused")
 public class ClassDataCollector {
-	public void classBegin(@SuppressWarnings("unused") int access, @SuppressWarnings("unused") TypeRef name) {}
+	public void classBegin(int access, TypeRef name) {}
 
 	public boolean classStart(int access, TypeRef className) {
 		classBegin(access, className);
 		return true;
 	}
 
-	public void extendsClass(@SuppressWarnings("unused") TypeRef zuper) throws Exception {}
+	public void extendsClass(TypeRef zuper) throws Exception {}
 
-	public void implementsInterfaces(@SuppressWarnings("unused") TypeRef[] interfaces) throws Exception {}
+	public void implementsInterfaces(TypeRef[] interfaces) throws Exception {}
 
-	public void addReference(@SuppressWarnings("unused") TypeRef ref) {}
+	public void addReference(TypeRef ref) {}
 
-	public void annotation(@SuppressWarnings("unused") Annotation annotation) {}
+	public void annotation(Annotation annotation) {}
 
-	public void parameter(@SuppressWarnings("unused") int p) {}
+	public void parameter(int p) {}
 
-	public void method(@SuppressWarnings("unused") Clazz.MethodDef defined) {}
+	public void method(Clazz.MethodDef defined) {}
 
-	public void field(@SuppressWarnings("unused") Clazz.FieldDef defined) {}
-
+	public void field(Clazz.FieldDef defined) {}
 
 	public void classEnd() throws Exception {}
 
@@ -58,27 +58,18 @@
 	 *            The access flags
 	 * @throws Exception
 	 */
-	public void innerClass(TypeRef innerClass, TypeRef outerClass, String innerName, @SuppressWarnings("unused") int innerClassAccessFlags)
+	public void innerClass(TypeRef innerClass, TypeRef outerClass, String innerName, int innerClassAccessFlags)
 			throws Exception {}
 
-	public void signature(@SuppressWarnings("unused") String signature) {}
+	public void signature(String signature) {}
 
-	public void constant(@SuppressWarnings("unused") Object object) {}
+	public void constant(Object object) {}
 
 	public void memberEnd() {}
 
-	public void version(@SuppressWarnings("unused") int minor, @SuppressWarnings("unused") int major) {
-		// TODO Auto-generated method stub
+	public void version(int minor, int major) {}
 
-	}
-
-	public void referenceMethod(@SuppressWarnings("unused")
-	int access, @SuppressWarnings("unused")
-	TypeRef className, @SuppressWarnings("unused")
-	String method, @SuppressWarnings("unused") String descriptor) {
-		// TODO Auto-generated method stub
-
-	}
+	public void referenceMethod(int access, TypeRef className, String method, String descriptor) {}
 
 	/**
 	 * A reference to a type from method or field. The modifiers indicate the
@@ -87,8 +78,6 @@
 	 * @param typeRef
 	 * @param modifiers
 	 */
-	public void referTo(TypeRef typeRef, int modifiers) {
-		
-	}
+	public void referTo(TypeRef typeRef, int modifiers) {}
 
 }
diff --git a/bundleplugin/src/main/java/aQute/bnd/osgi/Clazz.java b/bundleplugin/src/main/java/aQute/bnd/osgi/Clazz.java
index 1a325e6..efab9a3 100755
--- a/bundleplugin/src/main/java/aQute/bnd/osgi/Clazz.java
+++ b/bundleplugin/src/main/java/aQute/bnd/osgi/Clazz.java
@@ -147,7 +147,7 @@
 	}
 
 	public abstract class Def {
-		
+
 		final int		access;
 		Set<TypeRef>	annotations;
 
@@ -220,9 +220,11 @@
 		public TypeRef getOwnerType() {
 			return className;
 		}
-		
+
 		public abstract String getName();
+
 		public abstract TypeRef getType();
+
 		public abstract TypeRef[] getPrototype();
 
 		public Object getClazz() {
@@ -255,7 +257,6 @@
 		public String getName() {
 			return name;
 		}
-		
 
 		@Override
 		public TypeRef getType() {
@@ -296,6 +297,7 @@
 		public TypeRef[] getPrototype() {
 			return null;
 		}
+
 		public String getSignature() {
 			return signature;
 		}
@@ -338,7 +340,6 @@
 		public boolean getImplements() {
 			return interf;
 		}
-		
 
 		@Override
 		public String getName() {
@@ -346,11 +347,12 @@
 				return "<implements>";
 			return "<extends>";
 		}
-		
+
 		@Override
 		public TypeRef getType() {
 			return type;
 		}
+
 		@Override
 		public TypeRef[] getPrototype() {
 			return null;
@@ -859,9 +861,9 @@
 			doSignature(in, member, access_flags);
 		else if ("ConstantValue".equals(attributeName))
 			doConstantValue(in);
-        else if ("Exceptions".equals(attributeName))
-             doExceptions(in, access_flags);
-        else {
+		else if ("Exceptions".equals(attributeName))
+			doExceptions(in, access_flags);
+		else {
 			if (attribute_length > 0x7FFFFFFF) {
 				throw new IllegalArgumentException("Attribute > 2Gb");
 			}
@@ -1006,8 +1008,8 @@
 				referTo(clazz, access_flags);
 			}
 		}
-	}	
-	       
+	}
+
 	/**
 	 * <pre>
 	 * Code_attribute {
@@ -1154,7 +1156,8 @@
 		}
 	}
 
-	private void doAnnotations(DataInputStream in, ElementType member, RetentionPolicy policy, int access_flags) throws IOException {
+	private void doAnnotations(DataInputStream in, ElementType member, RetentionPolicy policy, int access_flags)
+			throws IOException {
 		int num_annotations = in.readUnsignedShort(); // # of annotations
 		for (int a = 0; a < num_annotations; a++) {
 			if (cd == null)
@@ -1166,8 +1169,8 @@
 		}
 	}
 
-	private Annotation doAnnotation(DataInputStream in, ElementType member, RetentionPolicy policy, boolean collect, int access_flags)
-			throws IOException {
+	private Annotation doAnnotation(DataInputStream in, ElementType member, RetentionPolicy policy, boolean collect,
+			int access_flags) throws IOException {
 		int type_index = in.readUnsignedShort();
 		if (annotations == null)
 			annotations = new HashSet<TypeRef>();
@@ -1201,8 +1204,8 @@
 		return null;
 	}
 
-	private Object doElementValue(DataInputStream in, ElementType member, RetentionPolicy policy, boolean collect, int access_flags)
-			throws IOException {
+	private Object doElementValue(DataInputStream in, ElementType member, RetentionPolicy policy, boolean collect,
+			int access_flags) throws IOException {
 		char tag = (char) in.readUnsignedByte();
 		switch (tag) {
 			case 'B' : // Byte
@@ -1228,8 +1231,8 @@
 				if (policy == RetentionPolicy.RUNTIME) {
 					referTo(type_name_index, 0);
 					if (api != null && (Modifier.isPublic(access_flags) || Modifier.isProtected(access_flags))) {
-						 TypeRef name = analyzer.getTypeRef((String) pool[type_name_index]);
-						 api.add(name.getPackageRef());
+						TypeRef name = analyzer.getTypeRef((String) pool[type_name_index]);
+						api.add(name.getPackageRef());
 					}
 				}
 				int const_name_index = in.readUnsignedShort();
@@ -1240,8 +1243,8 @@
 				if (policy == RetentionPolicy.RUNTIME) {
 					referTo(class_info_index, 0);
 					if (api != null && (Modifier.isPublic(access_flags) || Modifier.isProtected(access_flags))) {
-						 TypeRef name = analyzer.getTypeRef((String) pool[class_info_index]);
-						 api.add(name.getPackageRef());
+						TypeRef name = analyzer.getTypeRef((String) pool[class_info_index]);
+						api.add(name.getPackageRef());
 					}
 				}
 				return pool[class_info_index];
@@ -1729,5 +1732,4 @@
 	public Clazz.TypeDef getImplements(TypeRef type) {
 		return new TypeDef(type, true);
 	}
-
 }
diff --git a/bundleplugin/src/main/java/aQute/bnd/osgi/CommandResource.java b/bundleplugin/src/main/java/aQute/bnd/osgi/CommandResource.java
index eb66635..0e73945 100644
--- a/bundleplugin/src/main/java/aQute/bnd/osgi/CommandResource.java
+++ b/bundleplugin/src/main/java/aQute/bnd/osgi/CommandResource.java
@@ -8,11 +8,13 @@
 	final long		lastModified;
 	final Builder	domain;
 	final String	command;
+	final File wd;
 
-	public CommandResource(String command, Builder domain, long lastModified) {
+	public CommandResource(String command, Builder domain, long lastModified, File wd) {
 		this.lastModified = lastModified;
 		this.domain = domain;
 		this.command = command;
+		this.wd = wd;
 	}
 
 	@Override
@@ -22,6 +24,7 @@
 		try {
 			domain.trace("executing command %s", command);
 			Command cmd = new Command("sh");
+			cmd.setCwd(wd);
 			cmd.inherit();
 			String oldpath = cmd.var("PATH");
 
diff --git a/bundleplugin/src/main/java/aQute/bnd/osgi/Constants.java b/bundleplugin/src/main/java/aQute/bnd/osgi/Constants.java
index 34d60c6..4319538 100644
--- a/bundleplugin/src/main/java/aQute/bnd/osgi/Constants.java
+++ b/bundleplugin/src/main/java/aQute/bnd/osgi/Constants.java
@@ -69,6 +69,8 @@
 			PROVIDE_CAPABILITY, BUNDLE_ICON
 																				};
 
+	String							BASELINE									= "-baseline";
+	String							BASELINEREPO								= "-baselinerepo";
 	String							BUILDPATH									= "-buildpath";
 	String							BUILDPACKAGES								= "-buildpackages";
 	String							BUMPPOLICY									= "-bumppolicy";
@@ -90,6 +92,7 @@
 	String							MAKE										= "-make";
 	String							METATYPE									= "-metatype";
 	String							MANIFEST									= "-manifest";
+	String							PROFILE										= "-profile";
 	String							SAVEMANIFEST								= "-savemanifest";
 	String							NAMESECTION									= "-namesection";
 	String							NODEFAULTVERSION							= "-nodefaultversion";
@@ -130,6 +133,7 @@
 	String							RUNVM										= "-runvm";
 	String							RUNTRACE									= "-runtrace";
 	String							RUNFRAMEWORK								= "-runframework";
+	String							RUNFW										= "-runfw";
 	String							RUNTIMEOUT									= "-runtimeout";
 	String							SNAPSHOT									= "-snapshot";
 	String							RUNFRAMEWORK_SERVICES						= "services";
@@ -153,12 +157,12 @@
 	String							OUTPUT										= "-output";
 
 	String							options[]									= {
-			BUILDPATH, BUMPPOLICY, CONDUIT, CLASSPATH, CONSUMER_POLICY, DEPENDSON, DONOTCOPY, EXPORT_CONTENTS, FAIL_OK,
+			BASELINE, BUILDPATH, BUMPPOLICY, CONDUIT, CLASSPATH, CONSUMER_POLICY, DEPENDSON, DONOTCOPY, EXPORT_CONTENTS, FAIL_OK,
 			INCLUDE, INCLUDERESOURCE, MAKE, MANIFEST, NOEXTRAHEADERS, NOUSES, NOBUNDLES, PEDANTIC, PLUGIN, POM,
 			PROVIDER_POLICY, REMOVEHEADERS, RESOURCEONLY, SOURCES, SOURCEPATH, SOURCES, SOURCEPATH, SUB, RUNBUNDLES,
 			RUNPATH, RUNSYSTEMPACKAGES, RUNPROPERTIES, REPORTNEWER, UNDERTEST, TESTPATH, TESTPACKAGES, TESTREPORT,
-			VERBOSE, NOMANIFEST, DEPLOYREPO, RELEASEREPO, SAVEMANIFEST, RUNVM, WAB, WABLIB, RUNFRAMEWORK, RUNTRACE,
-			TESTCONTINUOUS, SNAPSHOT, NAMESECTION, DIGESTS, DSANNOTATIONS, EXPERIMENTS
+			VERBOSE, NOMANIFEST, DEPLOYREPO, RELEASEREPO, SAVEMANIFEST, RUNVM, WAB, WABLIB, RUNFRAMEWORK, RUNFW, RUNTRACE,
+			TESTCONTINUOUS, SNAPSHOT, NAMESECTION, DIGESTS, DSANNOTATIONS, EXPERIMENTS, BASELINE, BASELINEREPO, PROFILE
 																				};
 
 	// Ignore bundle specific headers. These bundles do not make
diff --git a/bundleplugin/src/main/java/aQute/bnd/osgi/Jar.java b/bundleplugin/src/main/java/aQute/bnd/osgi/Jar.java
index 93c55a1..9ee4048 100755
--- a/bundleplugin/src/main/java/aQute/bnd/osgi/Jar.java
+++ b/bundleplugin/src/main/java/aQute/bnd/osgi/Jar.java
@@ -515,6 +515,8 @@
 			return;
 		try {
 			createDirectories(directories, jout, path);
+			if (path.endsWith(Constants.EMPTY_HEADER))
+				return;
 			ZipEntry ze = new ZipEntry(path);
 			ze.setMethod(ZipEntry.DEFLATED);
 			long lastModified = resource.lastModified();
diff --git a/bundleplugin/src/main/java/aQute/bnd/osgi/Macro.java b/bundleplugin/src/main/java/aQute/bnd/osgi/Macro.java
index d706596..bfd0621 100755
--- a/bundleplugin/src/main/java/aQute/bnd/osgi/Macro.java
+++ b/bundleplugin/src/main/java/aQute/bnd/osgi/Macro.java
@@ -229,7 +229,7 @@
 			}
 			catch (InvocationTargetException e) {
 				if (e.getCause() instanceof IllegalArgumentException) {
-					domain.error("%s, for cmd: %s, arguments; %s", e.getMessage(), method, Arrays.toString(args));
+					domain.error("%s, for cmd: %s, arguments; %s", e.getCause().getMessage(), method, Arrays.toString(args));
 				} else {
 					domain.warning("Exception in replace: %s", e.getCause());
 					e.getCause().printStackTrace();
diff --git a/bundleplugin/src/main/java/aQute/bnd/osgi/Processor.java b/bundleplugin/src/main/java/aQute/bnd/osgi/Processor.java
index 5958a9d..e30ddcd 100755
--- a/bundleplugin/src/main/java/aQute/bnd/osgi/Processor.java
+++ b/bundleplugin/src/main/java/aQute/bnd/osgi/Processor.java
@@ -38,6 +38,7 @@
 	private File					base			= new File("").getAbsoluteFile();
 
 	Properties						properties;
+	String							profile;
 	private Macro					replacer;
 	private long					lastModified;
 	private File					propertiesFile;
@@ -138,7 +139,7 @@
 	}
 
 	public void progress(float progress, String format, Object... args) {
-		format = String.format("[%2d] %s", (int)progress, format);
+		format = String.format("[%2d] %s", (int) progress, format);
 		trace(format, args);
 	}
 
@@ -354,8 +355,8 @@
 					Class< ? > c = loader.loadClass(key);
 					Object plugin = c.newInstance();
 					customize(plugin, entry.getValue());
-					if ( plugin instanceof Closeable){
-						addClose((Closeable)plugin);
+					if (plugin instanceof Closeable) {
+						addClose((Closeable) plugin);
 					}
 					list.add(plugin);
 				}
@@ -470,7 +471,8 @@
 		toBeClosed.clear();
 	}
 
-	public String _basedir(@SuppressWarnings("unused") String args[]) {
+	public String _basedir(@SuppressWarnings("unused")
+	String args[]) {
 		if (base == null)
 			throw new IllegalArgumentException("No base dir set");
 
@@ -656,7 +658,8 @@
 
 	public boolean refresh() {
 		plugins = null; // We always refresh our plugins
-
+		
+		
 		if (propertiesFile == null)
 			return false;
 
@@ -670,6 +673,8 @@
 			}
 		}
 
+		profile = getProperty(PROFILE); // Used in property access
+		
 		if (changed) {
 			forceRefresh();
 			return true;
@@ -762,6 +767,7 @@
 	 * @return
 	 */
 	public String getProperty(String key, String deflt) {
+
 		String value = null;
 
 		Instruction ins = new Instruction(key);
@@ -789,6 +795,8 @@
 
 		Processor source = this;
 
+		// Use the key as is first, if found ok
+
 		if (filter != null && filter.contains(key)) {
 			value = (String) getProperties().get(key);
 		} else {
@@ -801,6 +809,26 @@
 			}
 		}
 
+		// Check if we found a value, if not, try to prefix
+		// it with a profile if found and search again. profiles
+		// are a simple name that is prefixed like [profile]. This
+		// allows different variables to be used in different profiles.
+
+		if (value == null && profile != null) {
+			String pkey = "[" + profile + "]" + key;
+			if (filter != null && filter.contains(key)) {
+				value = (String) getProperties().get(pkey);
+			} else {
+				while (source != null) {
+					value = (String) source.getProperties().get(pkey);
+					if (value != null)
+						break;
+
+					source = source.getParent();
+				}
+			}
+		}
+
 		if (value != null)
 			return getReplacer().process(value, source);
 		else if (deflt != null)
@@ -876,8 +904,8 @@
 		return printClauses(exports, false);
 	}
 
-	public static String printClauses(Map< ? , ? extends Map< ? , ? >> exports, @SuppressWarnings("unused") boolean checkMultipleVersions)
-			throws IOException {
+	public static String printClauses(Map< ? , ? extends Map< ? , ? >> exports, @SuppressWarnings("unused")
+	boolean checkMultipleVersions) throws IOException {
 		StringBuilder sb = new StringBuilder();
 		String del = "";
 		for (Entry< ? , ? extends Map< ? , ? >> entry : exports.entrySet()) {
@@ -977,7 +1005,8 @@
 		return result;
 	}
 
-	public boolean updateModified(long time, @SuppressWarnings("unused") String reason) {
+	public boolean updateModified(long time, @SuppressWarnings("unused")
+	String reason) {
 		if (time > lastModified) {
 			lastModified = time;
 			return true;