You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@karaf.apache.org by gn...@apache.org on 2017/04/07 15:15:12 UTC

karaf git commit: [KARAF-5074] Upgrade to Felix Utils 1.10, FileInstall 3.6 and use the new TypedProperties

Repository: karaf
Updated Branches:
  refs/heads/master 8ac48708b -> 3cd6866bf


[KARAF-5074] Upgrade to Felix Utils 1.10, FileInstall 3.6 and use the new TypedProperties 

Project: http://git-wip-us.apache.org/repos/asf/karaf/repo
Commit: http://git-wip-us.apache.org/repos/asf/karaf/commit/3cd6866b
Tree: http://git-wip-us.apache.org/repos/asf/karaf/tree/3cd6866b
Diff: http://git-wip-us.apache.org/repos/asf/karaf/diff/3cd6866b

Branch: refs/heads/master
Commit: 3cd6866bf9eb8d19b186441390d1e6d8719e652a
Parents: 8ac4870
Author: Guillaume Nodet <gn...@apache.org>
Authored: Wed Apr 5 17:53:15 2017 +0200
Committer: Guillaume Nodet <gn...@apache.org>
Committed: Fri Apr 7 17:14:49 2017 +0200

----------------------------------------------------------------------
 .../config/command/ConfigCommandSupport.java    |   2 +-
 .../command/ConfigPropertyCommandSupport.java   |   9 +-
 .../karaf/config/command/PropSetCommand.java    |   2 +-
 .../config/core/impl/ConfigRepositoryImpl.java  |  19 +-
 .../service/FeatureConfigInstaller.java         |  24 ++-
 pom.xml                                         |   4 +-
 .../karaf/profile/PlaceholderResolver.java      |   4 +-
 .../java/org/apache/karaf/profile/Profile.java  |   4 +-
 .../apache/karaf/profile/ProfileBuilder.java    |   8 +-
 .../apache/karaf/profile/assembly/Builder.java  |   8 +-
 .../karaf/profile/command/ProfileDisplay.java   |  16 +-
 .../karaf/profile/command/ProfileEdit.java      |  26 +--
 .../profile/impl/PlaceholderResolvers.java      |  22 +--
 .../karaf/profile/impl/ProfileBuilderImpl.java  |  35 ++--
 .../apache/karaf/profile/impl/ProfileImpl.java  |  32 ++--
 .../org/apache/karaf/profile/impl/Profiles.java | 185 ++++---------------
 .../org/apache/karaf/profile/impl/Utils.java    |  35 ++--
 17 files changed, 157 insertions(+), 278 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/karaf/blob/3cd6866b/config/src/main/java/org/apache/karaf/config/command/ConfigCommandSupport.java
----------------------------------------------------------------------
diff --git a/config/src/main/java/org/apache/karaf/config/command/ConfigCommandSupport.java b/config/src/main/java/org/apache/karaf/config/command/ConfigCommandSupport.java
index 3a0aaf1..031f85d 100644
--- a/config/src/main/java/org/apache/karaf/config/command/ConfigCommandSupport.java
+++ b/config/src/main/java/org/apache/karaf/config/command/ConfigCommandSupport.java
@@ -51,7 +51,7 @@ public abstract class ConfigCommandSupport implements Action {
     protected abstract Object doExecute() throws Exception;
 
     @SuppressWarnings("rawtypes")
-    protected Dictionary getEditedProps() throws Exception {
+    protected Dictionary<String, Object> getEditedProps() throws Exception {
         return (Dictionary) this.session.get(PROPERTY_CONFIG_PROPS);
     }
 

http://git-wip-us.apache.org/repos/asf/karaf/blob/3cd6866b/config/src/main/java/org/apache/karaf/config/command/ConfigPropertyCommandSupport.java
----------------------------------------------------------------------
diff --git a/config/src/main/java/org/apache/karaf/config/command/ConfigPropertyCommandSupport.java b/config/src/main/java/org/apache/karaf/config/command/ConfigPropertyCommandSupport.java
index 114e7e5..466d462 100644
--- a/config/src/main/java/org/apache/karaf/config/command/ConfigPropertyCommandSupport.java
+++ b/config/src/main/java/org/apache/karaf/config/command/ConfigPropertyCommandSupport.java
@@ -17,6 +17,7 @@
 package org.apache.karaf.config.command;
 
 import java.util.Dictionary;
+import java.util.Hashtable;
 import java.util.Properties;
 
 import org.apache.karaf.config.command.completers.ConfigurationCompleter;
@@ -36,12 +37,12 @@ public abstract class ConfigPropertyCommandSupport extends ConfigCommandSupport
      "rawtypes", "unchecked"
     })
     protected Object doExecute() throws Exception {
-        Dictionary props = getEditedProps();
+        Dictionary<String, Object> props = getEditedProps();
         if (props == null && pid == null) {
             System.err.println("No configuration is being edited--run the edit command first");
         } else {
             if (props == null) {
-                props = new Properties();
+                props = new Hashtable<>();
             }
             propertyAction(props);
             if(requiresUpdate(pid)) {
@@ -82,8 +83,8 @@ public abstract class ConfigPropertyCommandSupport extends ConfigCommandSupport
      */
     @SuppressWarnings("rawtypes")
     @Override
-    protected Dictionary getEditedProps() throws Exception {
-        Dictionary props = this.configRepository.getConfigProperties(pid);
+    protected Dictionary<String, Object> getEditedProps() throws Exception {
+        Dictionary<String, Object> props = this.configRepository.getConfigProperties(pid);
         return (props != null) ? props : super.getEditedProps();
     }
 }

http://git-wip-us.apache.org/repos/asf/karaf/blob/3cd6866b/config/src/main/java/org/apache/karaf/config/command/PropSetCommand.java
----------------------------------------------------------------------
diff --git a/config/src/main/java/org/apache/karaf/config/command/PropSetCommand.java b/config/src/main/java/org/apache/karaf/config/command/PropSetCommand.java
index 8337f6a..b4c3f85 100644
--- a/config/src/main/java/org/apache/karaf/config/command/PropSetCommand.java
+++ b/config/src/main/java/org/apache/karaf/config/command/PropSetCommand.java
@@ -33,7 +33,7 @@ public class PropSetCommand extends ConfigPropertyCommandSupport {
     String prop;
 
     @Argument(index = 1, name = "value", description = "The value of the property", required = true, multiValued = false)
-    String value;
+    Object value;
 
     @SuppressWarnings({"unchecked", "rawtypes"})
     @Override

http://git-wip-us.apache.org/repos/asf/karaf/blob/3cd6866b/config/src/main/java/org/apache/karaf/config/core/impl/ConfigRepositoryImpl.java
----------------------------------------------------------------------
diff --git a/config/src/main/java/org/apache/karaf/config/core/impl/ConfigRepositoryImpl.java b/config/src/main/java/org/apache/karaf/config/core/impl/ConfigRepositoryImpl.java
index 3ef4b9b..ac4e1e2 100644
--- a/config/src/main/java/org/apache/karaf/config/core/impl/ConfigRepositoryImpl.java
+++ b/config/src/main/java/org/apache/karaf/config/core/impl/ConfigRepositoryImpl.java
@@ -60,15 +60,18 @@ public class ConfigRepositoryImpl implements ConfigRepository {
      * @see org.apache.karaf.shell.config.impl.ConfigRepository#update(java.lang.String, java.util.Dictionary, boolean)
      */
     @Override
-    public void update(String pid, Dictionary<String, Object> props) throws IOException {
+    public void update(String pid, Dictionary<String, Object> properties) throws IOException {
         LOGGER.trace("Update configuration {}", pid);
         Configuration cfg = configAdmin.getConfiguration(pid, null);
-        cfg.update(props);
-        try {
-            updateStorage(pid, props);
-        } catch (Exception e) {
-            LOGGER.warn("Can't update cfg file", e);
+        if (storage != null) {
+            // Check, whether a file location is already provided.
+            if (properties.get(FILEINSTALL_FILE_NAME) == null) {
+                String cfgFileName = pid + ".cfg";
+                File cfgFile = new File(storage, cfgFileName);
+                properties.put(FILEINSTALL_FILE_NAME, cfgFile.getCanonicalFile().toURI().toString());
+            }
         }
+        cfg.update(properties);
     }
 
     /* (non-Javadoc)
@@ -123,7 +126,7 @@ public class ConfigRepositoryImpl implements ConfigRepository {
                         cfgFile = getCfgFileFromProperties(oldProps);
                         if (cfgFile == null) {
                             throw new IOException("The configuration value '" + oldProps.get(FILEINSTALL_FILE_NAME)
-                                    + "' for ' + FILEINSTALL_FILE_NAME + ' does not represent a valid file location.");
+                                    + "' for '" + FILEINSTALL_FILE_NAME + "' does not represent a valid file location.");
                         }
                     } catch (URISyntaxException | MalformedURLException e) {
                         throw new IOException(e);
@@ -209,7 +212,7 @@ public class ConfigRepositoryImpl implements ConfigRepository {
             }
             config.update(properties);
             String pid = config.getPid();
-            updateStorage(pid, properties);
+//            updateStorage(pid, properties);
             return pid;
         } catch (IOException e) {
             throw new UncheckedIOException(e);

http://git-wip-us.apache.org/repos/asf/karaf/blob/3cd6866b/features/core/src/main/java/org/apache/karaf/features/internal/service/FeatureConfigInstaller.java
----------------------------------------------------------------------
diff --git a/features/core/src/main/java/org/apache/karaf/features/internal/service/FeatureConfigInstaller.java b/features/core/src/main/java/org/apache/karaf/features/internal/service/FeatureConfigInstaller.java
index 29b5eb7..ad96b63 100644
--- a/features/core/src/main/java/org/apache/karaf/features/internal/service/FeatureConfigInstaller.java
+++ b/features/core/src/main/java/org/apache/karaf/features/internal/service/FeatureConfigInstaller.java
@@ -29,6 +29,7 @@ import java.util.*;
 
 import org.apache.felix.utils.properties.InterpolationHelper;
 import org.apache.felix.utils.properties.InterpolationHelper.SubstitutionCallback;
+import org.apache.felix.utils.properties.TypedProperties;
 import org.apache.karaf.features.ConfigFileInfo;
 import org.apache.karaf.features.ConfigInfo;
 import org.apache.karaf.features.Feature;
@@ -100,12 +101,14 @@ public class FeatureConfigInstaller {
 
     public void installFeatureConfigs(Feature feature) throws IOException, InvalidSyntaxException {
     	for (ConfigInfo config : feature.getConfigurations()) {
-            org.apache.felix.utils.properties.Properties props = new org.apache.felix.utils.properties.Properties();
-            props.load(new StringReader(config.getValue()));
+            TypedProperties props = new TypedProperties();
+            // trim lines
+            String val = config.getValue().replaceAll("\n\\s+", "\n");
+            props.load(new StringReader(val));
 			String[] pid = parsePid(config.getName());
 			Configuration cfg = findExistingConfiguration(configAdmin, pid[0], pid[1]);
 			if (cfg == null) {
-				Dictionary<String, String> cfgProps = convertToDict(props);
+				Dictionary<String, Object> cfgProps = convertToDict(props);
 				cfg = createConfiguration(configAdmin, pid[0], pid[1]);
 				String key = createConfigurationKey(pid[0], pid[1]);
 				cfgProps.put(CONFIG_KEY, key);
@@ -120,7 +123,7 @@ public class FeatureConfigInstaller {
 				Dictionary<String,Object> properties = cfg.getProperties();
                 for (String key : props.keySet()) {
                     if (properties.get(key) == null) {
-                        properties.put(key, props.getProperty(key));
+                        properties.put(key, props.get(key));
                         update = true;
                     }
                 }
@@ -139,9 +142,9 @@ public class FeatureConfigInstaller {
         }
     }
 
-	private Dictionary<String, String> convertToDict(Map<String, String> props) {
-		Dictionary<String, String> cfgProps = new Hashtable<String, String>();
-        for (Map.Entry<String, String> e : props.entrySet()) {
+	private Dictionary<String, Object> convertToDict(Map<String, Object> props) {
+		Dictionary<String, Object> cfgProps = new Hashtable<>();
+        for (Map.Entry<String, Object> e : props.entrySet()) {
             cfgProps.put(e.getKey(), e.getValue());
         }
 		return cfgProps;
@@ -240,7 +243,7 @@ public class FeatureConfigInstaller {
         }
     }
 
-    protected void updateStorage(String pid, String factoryPid, org.apache.felix.utils.properties.Properties props, boolean append) throws Exception {
+    protected void updateStorage(String pid, String factoryPid, TypedProperties props, boolean append) throws Exception {
         if (storage != null && configCfgStore) {
             // get the cfg file
             File cfgFile;
@@ -272,7 +275,8 @@ public class FeatureConfigInstaller {
             if (!cfgFile.exists()) {
                 props.save(cfgFile);
             } else {
-                org.apache.felix.utils.properties.Properties properties = new org.apache.felix.utils.properties.Properties(cfgFile);
+                TypedProperties properties = new TypedProperties();
+                properties.load( cfgFile );
                 for (String key : props.keySet()) {
                     if (!Constants.SERVICE_PID.equals(key)
                             && !ConfigurationAdmin.SERVICE_FACTORYPID.equals(key)
@@ -306,7 +310,7 @@ public class FeatureConfigInstaller {
                 }
                 // save the cfg file
                 storage.mkdirs();
-                properties.save();
+                properties.save( cfgFile );
             }
         }
     }

http://git-wip-us.apache.org/repos/asf/karaf/blob/3cd6866b/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 6418403..395e541 100644
--- a/pom.xml
+++ b/pom.xml
@@ -184,7 +184,7 @@
         <felix.configadmin.version>1.8.14</felix.configadmin.version>
         <felix.connect.version>0.1.0</felix.connect.version>
         <felix.coordinator.version>1.0.2</felix.coordinator.version>
-        <felix.fileinstall.version>3.5.8</felix.fileinstall.version>
+        <felix.fileinstall.version>3.6.0-SNAPSHOT</felix.fileinstall.version>
         <felix.framework.version>5.6.2</felix.framework.version>
         <felix.framework.security.version>2.6.0</felix.framework.security.version>
         <felix.gogo.runtime.version>1.0.4</felix.gogo.runtime.version>
@@ -192,7 +192,7 @@
         <felix.httplite.version>0.1.5</felix.httplite.version>
         <felix.inventory.version>1.0.4</felix.inventory.version>
         <felix.plugin.version>3.3.0</felix.plugin.version>
-        <felix.utils.version>1.9.0</felix.utils.version>
+        <felix.utils.version>1.10.0-SNAPSHOT</felix.utils.version>
         <felix.webconsole.version>4.3.0</felix.webconsole.version>
         <felix.webconsole.api.version>3.1.2</felix.webconsole.api.version>
         <felix.metatype.version>1.1.2</felix.metatype.version>

http://git-wip-us.apache.org/repos/asf/karaf/blob/3cd6866b/profile/src/main/java/org/apache/karaf/profile/PlaceholderResolver.java
----------------------------------------------------------------------
diff --git a/profile/src/main/java/org/apache/karaf/profile/PlaceholderResolver.java b/profile/src/main/java/org/apache/karaf/profile/PlaceholderResolver.java
index 740178e..89d8a0e 100644
--- a/profile/src/main/java/org/apache/karaf/profile/PlaceholderResolver.java
+++ b/profile/src/main/java/org/apache/karaf/profile/PlaceholderResolver.java
@@ -27,7 +27,7 @@ public interface PlaceholderResolver {
      *
      * @return The placeholder scheme.
      */
-    public String getScheme();
+    String getScheme();
 
     /**
      * Resolve the placeholder found inside the value, for the specific key of the pid.
@@ -38,6 +38,6 @@ public interface PlaceholderResolver {
      * @param value The value with the placeholder.
      * @return The resolved value or EMPTY_STRING.
      */
-    public String resolve(Map<String, Map<String, String>> profile, String pid, String key, String value);
+    String resolve(Map<String, Map<String, String>> profile, String pid, String key, String value);
 
 }

http://git-wip-us.apache.org/repos/asf/karaf/blob/3cd6866b/profile/src/main/java/org/apache/karaf/profile/Profile.java
----------------------------------------------------------------------
diff --git a/profile/src/main/java/org/apache/karaf/profile/Profile.java b/profile/src/main/java/org/apache/karaf/profile/Profile.java
index 30097b6..c9d4b3d 100644
--- a/profile/src/main/java/org/apache/karaf/profile/Profile.java
+++ b/profile/src/main/java/org/apache/karaf/profile/Profile.java
@@ -121,7 +121,7 @@ public interface Profile {
      *
      * @return The configurations in the profile.
      */
-    Map<String, Map<String, String>> getConfigurations();
+    Map<String, Map<String, Object>> getConfigurations();
 
     /**
      * Get the configuration properties for the given PID.
@@ -129,7 +129,7 @@ public interface Profile {
      * @param pid The configuration PID to look for.
      * @return An empty map if the there is no configuration for the given pid.
      */
-    Map<String, String> getConfiguration(String pid);
+    Map<String, Object> getConfiguration(String pid);
 
     /**
      * Indicate if this profile is an overlay or not.

http://git-wip-us.apache.org/repos/asf/karaf/blob/3cd6866b/profile/src/main/java/org/apache/karaf/profile/ProfileBuilder.java
----------------------------------------------------------------------
diff --git a/profile/src/main/java/org/apache/karaf/profile/ProfileBuilder.java b/profile/src/main/java/org/apache/karaf/profile/ProfileBuilder.java
index e00fedb..b87f9a7 100644
--- a/profile/src/main/java/org/apache/karaf/profile/ProfileBuilder.java
+++ b/profile/src/main/java/org/apache/karaf/profile/ProfileBuilder.java
@@ -57,13 +57,13 @@ public interface ProfileBuilder {
      * @param pid The configuration PID.
      * @return The copy of the configuration with the given PID.
      */
-    Map<String, String> getConfiguration(String pid);
+    Map<String, Object> getConfiguration(String pid);
     
-    ProfileBuilder addConfiguration(String pid, Map<String, String> config);
+    ProfileBuilder addConfiguration(String pid, Map<String, Object> config);
 
-    ProfileBuilder addConfiguration(String pid, String key, String value);
+    ProfileBuilder addConfiguration(String pid, String key, Object value);
 
-    ProfileBuilder setConfigurations(Map<String, Map<String, String>> configs);
+    ProfileBuilder setConfigurations(Map<String, Map<String, Object>> configs);
 
     ProfileBuilder deleteConfiguration(String pid);
 

http://git-wip-us.apache.org/repos/asf/karaf/blob/3cd6866b/profile/src/main/java/org/apache/karaf/profile/assembly/Builder.java
----------------------------------------------------------------------
diff --git a/profile/src/main/java/org/apache/karaf/profile/assembly/Builder.java b/profile/src/main/java/org/apache/karaf/profile/assembly/Builder.java
index ac7a482..1b57729 100644
--- a/profile/src/main/java/org/apache/karaf/profile/assembly/Builder.java
+++ b/profile/src/main/java/org/apache/karaf/profile/assembly/Builder.java
@@ -564,10 +564,10 @@ public class Builder {
 
         manager = new CustomDownloadManager(resolver, executor, overallEffective, translatedUrls);
 
-        Hashtable<String, String> agentProps = new Hashtable<>(overallEffective.getConfiguration(ORG_OPS4J_PAX_URL_MVN_PID));
-        final Map<String, String> properties = new HashMap<>();
-        properties.put("karaf.default.repository", "system");
-        InterpolationHelper.performSubstitution(agentProps, properties::get, false, false, true);
+//        Hashtable<String, String> agentProps = new Hashtable<>(overallEffective.getConfiguration(ORG_OPS4J_PAX_URL_MVN_PID));
+//        final Map<String, String> properties = new HashMap<>();
+//        properties.put("karaf.default.repository", "system");
+//        InterpolationHelper.performSubstitution(agentProps, properties::get, false, false, true);
 
         //
         // Write config and system properties

http://git-wip-us.apache.org/repos/asf/karaf/blob/3cd6866b/profile/src/main/java/org/apache/karaf/profile/command/ProfileDisplay.java
----------------------------------------------------------------------
diff --git a/profile/src/main/java/org/apache/karaf/profile/command/ProfileDisplay.java b/profile/src/main/java/org/apache/karaf/profile/command/ProfileDisplay.java
index 5eb65d0..fcd8145 100644
--- a/profile/src/main/java/org/apache/karaf/profile/command/ProfileDisplay.java
+++ b/profile/src/main/java/org/apache/karaf/profile/command/ProfileDisplay.java
@@ -85,18 +85,18 @@ public class ProfileDisplay implements Action {
             profile = profileService.getEffectiveProfile(profile);
         }
 
-        Map<String, Map<String, String>> configuration = new HashMap<>(profile.getConfigurations());
+        Map<String, Map<String, Object>> configuration = new HashMap<>(profile.getConfigurations());
         Map<String, byte[]> resources = profile.getFileConfigurations();
-        Map<String,String> agentConfiguration = profile.getConfiguration(Profile.INTERNAL_PID);
+        Map<String,Object> agentConfiguration = profile.getConfiguration(Profile.INTERNAL_PID);
         List<String> agentProperties = new ArrayList<String>();
         List<String> systemProperties = new ArrayList<String>();
         List<String> configProperties = new ArrayList<String>();
         List<String> otherResources = new ArrayList<String>();
-        for (Map.Entry<String, String> entry : agentConfiguration.entrySet()) {
+        for (Map.Entry<String, Object> entry : agentConfiguration.entrySet()) {
             String key = entry.getKey();
-            String value = entry.getValue();
-            if (value.contains(",")) {
-                value = "\t" + value.replace(",", ",\n\t\t");
+            Object value = entry.getValue();
+            if (value instanceof String && ((String) value).contains(",")) {
+                value = "\t" + ((String) value).replace(",", ",\n\t\t");
             }
 
             if (key.startsWith("system.")) {
@@ -149,10 +149,10 @@ public class ProfileDisplay implements Action {
 
         output.println("\nConfiguration details");
         output.println("----------------------------");
-        for (Map.Entry<String, Map<String, String>> cfg : configuration.entrySet()) {
+        for (Map.Entry<String, Map<String, Object>> cfg : configuration.entrySet()) {
             output.println("PID: " + cfg.getKey());
 
-            for (Map.Entry<String, String> values : cfg.getValue().entrySet()) {
+            for (Map.Entry<String, Object> values : cfg.getValue().entrySet()) {
                 output.println("  " + values.getKey() + " " + values.getValue());
             }
             output.println("\n");

http://git-wip-us.apache.org/repos/asf/karaf/blob/3cd6866b/profile/src/main/java/org/apache/karaf/profile/command/ProfileEdit.java
----------------------------------------------------------------------
diff --git a/profile/src/main/java/org/apache/karaf/profile/command/ProfileEdit.java b/profile/src/main/java/org/apache/karaf/profile/command/ProfileEdit.java
index 84b7b66..553d9fa 100644
--- a/profile/src/main/java/org/apache/karaf/profile/command/ProfileEdit.java
+++ b/profile/src/main/java/org/apache/karaf/profile/command/ProfileEdit.java
@@ -210,7 +210,7 @@ public class ProfileEdit implements Action {
      * Adds or remove the specified features to the specified profile.
      */
     private void handleFeatures(ProfileBuilder builder, String[] features, Profile profile) {
-        Map<String, String> conf = getConfigurationFromBuilder(builder, Profile.INTERNAL_PID);
+        Map<String, Object> conf = getConfigurationFromBuilder(builder, Profile.INTERNAL_PID);
         for (String feature : features) {
             if (delete) {
                 System.out.println("Deleting feature:" + feature + " from profile:" + profile.getId());
@@ -226,7 +226,7 @@ public class ProfileEdit implements Action {
      * Adds or remove the specified feature repositories to the specified profile.
      */
     private void handleFeatureRepositories(ProfileBuilder builder, String[] repositories, Profile profile) {
-        Map<String, String> conf = getConfigurationFromBuilder(builder, Profile.INTERNAL_PID);
+        Map<String, Object> conf = getConfigurationFromBuilder(builder, Profile.INTERNAL_PID);
         for (String repositoryURI : repositories) {
             if (set) {
                 System.out.println("Adding feature repository:" + repositoryURI + " to profile:" + profile.getId());
@@ -246,7 +246,7 @@ public class ProfileEdit implements Action {
      * @param libPrefix The prefix of the lib.
      */
     private void handleLibraries(ProfileBuilder builder, String[] libs, Profile profile, String libType, String libPrefix) {
-        Map<String, String> conf = getConfigurationFromBuilder(builder, Profile.INTERNAL_PID);
+        Map<String, Object> conf = getConfigurationFromBuilder(builder, Profile.INTERNAL_PID);
         for (String lib : libs) {
             if (set) {
                 System.out.println("Adding "+libType+":" + lib + " to profile:" + profile.getId());
@@ -264,7 +264,7 @@ public class ProfileEdit implements Action {
      * @param profile   The target profile.
      */
     private void handleBundles(ProfileBuilder builder, String[] bundles, Profile profile) {
-        Map<String, String> conf = getConfigurationFromBuilder(builder, Profile.INTERNAL_PID);
+        Map<String, Object> conf = getConfigurationFromBuilder(builder, Profile.INTERNAL_PID);
         for (String bundle : bundles) {
             if (set) {
                 System.out.println("Adding bundle:" + bundle + " to profile:" + profile.getId());
@@ -282,7 +282,7 @@ public class ProfileEdit implements Action {
      * @param profile       The target profile.
      */
     private void handleOverrides(ProfileBuilder builder, String[] overrides, Profile profile) {
-        Map<String, String> conf = getConfigurationFromBuilder(builder, Profile.INTERNAL_PID);
+        Map<String, Object> conf = getConfigurationFromBuilder(builder, Profile.INTERNAL_PID);
         for (String override : overrides) {
             if (set) {
                 System.out.println("Adding override:" + override + " to profile:" + profile.getId());
@@ -312,7 +312,7 @@ public class ProfileEdit implements Action {
             } else {
                 currentPid = pidProperty;
             }
-            Map<String, String> conf = getConfigurationFromBuilder(builder, currentPid);
+            Map<String, Object> conf = getConfigurationFromBuilder(builder, currentPid);
             
             // We only support import when a single pid is specified
             if (pidProperties.length == 1 && importPid) {
@@ -362,7 +362,7 @@ public class ProfileEdit implements Action {
      * @param profile               The target profile.
      */
     private void handleSystemProperties(ProfileBuilder builder, String[] systemProperties, Profile profile) {
-        Map<String, String> conf = getConfigurationFromBuilder(builder, Profile.INTERNAL_PID);
+        Map<String, Object> conf = getConfigurationFromBuilder(builder, Profile.INTERNAL_PID);
         for (String systemProperty : systemProperties) {
             Map<String, String> configMap = extractConfigs(systemProperty);
             for (Map.Entry<String, String> configEntries : configMap.entrySet()) {
@@ -389,7 +389,7 @@ public class ProfileEdit implements Action {
      * @param profile               The target profile.
      */
     private void handleConfigProperties(ProfileBuilder builder, String[] configProperties, Profile profile) {
-        Map<String, String> conf = getConfigurationFromBuilder(builder, Profile.INTERNAL_PID);
+        Map<String, Object> conf = getConfigurationFromBuilder(builder, Profile.INTERNAL_PID);
         for (String configProperty : configProperties) {
             Map<String, String> configMap = extractConfigs(configProperty);
             for (Map.Entry<String, String> configEntries : configMap.entrySet()) {
@@ -422,9 +422,9 @@ public class ProfileEdit implements Action {
         */
     }
 
-    public void updatedDelimitedList(Map<String, String> map, String key, String value, String delimiter, boolean set, boolean delete, boolean append, boolean remove) {
+    public void updatedDelimitedList(Map<String, Object> map, String key, String value, String delimiter, boolean set, boolean delete, boolean append, boolean remove) {
         if (append || remove) {
-            String oldValue = map.containsKey(key) ? map.get(key) : "";
+            String oldValue = map.containsKey(key) ? (String) map.get(key) : "";
             List<String> parts = new LinkedList<>(Arrays.asList(oldValue.split(delimiter)));
             //We need to remove any possible blanks.
             parts.remove("");
@@ -449,7 +449,7 @@ public class ProfileEdit implements Action {
         }
     }
 
-    private void updateConfig(Map<String, String> map, String key, String value, boolean set, boolean delete) {
+    private void updateConfig(Map<String, Object> map, String key, Object value, boolean set, boolean delete) {
         if (set) {
             map.put(key, value);
         } else if (delete) {
@@ -460,7 +460,7 @@ public class ProfileEdit implements Action {
     /**
      * Imports the pid to the target Map.
      */
-    private void importPidFromLocalConfigAdmin(String pid, Map<String, String> target) {
+    private void importPidFromLocalConfigAdmin(String pid, Map<String, Object> target) {
         try {
             Configuration[] configuration = configurationAdmin.listConfigurations("(service.pid=" + pid + ")");
             if (configuration != null && configuration.length > 0) {
@@ -580,7 +580,7 @@ public class ProfileEdit implements Action {
     }
         */
 
-    private Map<String, String> getConfigurationFromBuilder(ProfileBuilder builder, String pid) {
+    private Map<String, Object> getConfigurationFromBuilder(ProfileBuilder builder, String pid) {
         return builder.getConfiguration(pid);
     }
 

http://git-wip-us.apache.org/repos/asf/karaf/blob/3cd6866b/profile/src/main/java/org/apache/karaf/profile/impl/PlaceholderResolvers.java
----------------------------------------------------------------------
diff --git a/profile/src/main/java/org/apache/karaf/profile/impl/PlaceholderResolvers.java b/profile/src/main/java/org/apache/karaf/profile/impl/PlaceholderResolvers.java
index a15a830..dc46a23 100644
--- a/profile/src/main/java/org/apache/karaf/profile/impl/PlaceholderResolvers.java
+++ b/profile/src/main/java/org/apache/karaf/profile/impl/PlaceholderResolvers.java
@@ -27,25 +27,6 @@ public final class PlaceholderResolvers {
 
     private PlaceholderResolvers() { }
 
-    public static class PropertyPlaceholderResolver implements PlaceholderResolver {
-
-        private final Map<String, String> properties;
-
-        public PropertyPlaceholderResolver(Map<String, String> properties) {
-            this.properties = properties;
-        }
-
-        @Override
-        public String getScheme() {
-            return null;
-        }
-
-        @Override
-        public String resolve(Map<String, Map<String, String>> profile, String pid, String key, String value) {
-            return properties.get(value);
-        }
-    }
-
     public static class ProfilePlaceholderResolver implements PlaceholderResolver {
 
         public final String SCHEME = "profile";
@@ -63,7 +44,8 @@ public final class PlaceholderResolvers {
                 String propertyKey = value.substring(index + 1);
                 Map<String, String> props = profile.get(propertyPid);
                 if (props != null && props.containsKey(propertyKey)) {
-                    return props.get(propertyKey);
+                    Object v = props.get(propertyKey);
+                    return v.toString();
                 }
             }
             return null;

http://git-wip-us.apache.org/repos/asf/karaf/blob/3cd6866b/profile/src/main/java/org/apache/karaf/profile/impl/ProfileBuilderImpl.java
----------------------------------------------------------------------
diff --git a/profile/src/main/java/org/apache/karaf/profile/impl/ProfileBuilderImpl.java b/profile/src/main/java/org/apache/karaf/profile/impl/ProfileBuilderImpl.java
index e067564..532caf6 100644
--- a/profile/src/main/java/org/apache/karaf/profile/impl/ProfileBuilderImpl.java
+++ b/profile/src/main/java/org/apache/karaf/profile/impl/ProfileBuilderImpl.java
@@ -59,8 +59,8 @@ public final class ProfileBuilderImpl implements ProfileBuilder {
 
 	@Override
     public List<String> getParents() {
-        Map<String, String> config = getConfigurationInternal(Profile.INTERNAL_PID);
-        String pspec = config.get(PARENTS_ATTRIBUTE_KEY);
+        Map<String, Object> config = getConfigurationInternal(Profile.INTERNAL_PID);
+        String pspec = (String) config.get(PARENTS_ATTRIBUTE_KEY);
         String[] parentIds = pspec != null ? pspec.split(" ") : new String[0];
         return Arrays.asList(parentIds);
     }
@@ -101,7 +101,7 @@ public final class ProfileBuilderImpl implements ProfileBuilder {
 	}
 
     private void updateParentsAttribute(Collection<String> parentIds) {
-        Map<String, String> config = getConfigurationInternal(Profile.INTERNAL_PID);
+        Map<String, Object> config = getConfigurationInternal(Profile.INTERNAL_PID);
         config.remove(PARENTS_ATTRIBUTE_KEY);
         if (parentIds.size() > 0) {
             config.put(PARENTS_ATTRIBUTE_KEY, parentsAttributeValue(parentIds));
@@ -110,14 +110,7 @@ public final class ProfileBuilderImpl implements ProfileBuilder {
     }
 
     private String parentsAttributeValue(Collection<String> parentIds) {
-        String pspec = "";
-        if (parentIds.size() > 0) {
-            for (String parentId : parentIds) {
-                pspec += " " + parentId;
-            }
-            pspec = pspec.substring(1);
-        }
-        return pspec;
+	    return parentIds.isEmpty() ? "" : String.join(" ", parentIds);
     }
     
     @Override
@@ -149,25 +142,25 @@ public final class ProfileBuilderImpl implements ProfileBuilder {
     }
 
 	@Override
-	public ProfileBuilder setConfigurations(Map<String, Map<String, String>> configs) {
+	public ProfileBuilder setConfigurations(Map<String, Map<String, Object>> configs) {
 	    for (String pid : getConfigurationKeys()) {
 	        deleteConfiguration(pid);
 	    }
-		for (Entry<String, Map<String, String>> entry : configs.entrySet()) {
+		for (Entry<String, Map<String, Object>> entry : configs.entrySet()) {
 		    addConfiguration(entry.getKey(), new HashMap<>(entry.getValue()));
 		}
 		return this;
 	}
 
     @Override
-    public ProfileBuilder addConfiguration(String pid, Map<String, String> config) {
+    public ProfileBuilder addConfiguration(String pid, Map<String, Object> config) {
         fileMapping.put(pid + Profile.PROPERTIES_SUFFIX, Utils.toBytes(config));
         return this;
     }
 
     @Override
-    public ProfileBuilder addConfiguration(String pid, String key, String value) {
-        Map<String, String> config = getConfigurationInternal(pid);
+    public ProfileBuilder addConfiguration(String pid, String key, Object value) {
+        Map<String, Object> config = getConfigurationInternal(pid);
         config.put(key, value);
         return addConfiguration(pid, config);
     }
@@ -185,11 +178,11 @@ public final class ProfileBuilderImpl implements ProfileBuilder {
     }
 
     @Override
-    public Map<String, String> getConfiguration(String pid) {
+    public Map<String, Object> getConfiguration(String pid) {
         return getConfigurationInternal(pid);
     }
 
-    private Map<String, String> getConfigurationInternal(String pid) {
+    private Map<String, Object> getConfigurationInternal(String pid) {
         byte[] bytes = fileMapping.get(pid + Profile.PROPERTIES_SUFFIX);
         return Utils.toProperties(bytes);
     }
@@ -261,7 +254,7 @@ public final class ProfileBuilderImpl implements ProfileBuilder {
 
     @Override
     public ProfileBuilder setAttributes(Map<String, String> attributes) {
-        Map<String, String> config = getConfigurationInternal(Profile.INTERNAL_PID);
+        Map<String, Object> config = getConfigurationInternal(Profile.INTERNAL_PID);
         for (String key : new ArrayList<>(config.keySet())) {
             if (key.startsWith(Profile.ATTRIBUTE_PREFIX)) {
                 config.remove(key);
@@ -276,7 +269,7 @@ public final class ProfileBuilderImpl implements ProfileBuilder {
 
     private void addAgentConfiguration(ConfigListType type, List<String> values) {
         String prefix = type + ".";
-        Map<String, String> config = getConfigurationInternal(Profile.INTERNAL_PID);
+        Map<String, Object> config = getConfigurationInternal(Profile.INTERNAL_PID);
         for (String key : new ArrayList<>(config.keySet())) {
             if (key.startsWith(prefix)) {
                 config.remove(key);
@@ -290,7 +283,7 @@ public final class ProfileBuilderImpl implements ProfileBuilder {
 
     private void addAgentConfiguration(ConfigListType type, String value) {
         String prefix = type + ".";
-        Map<String, String> config = getConfigurationInternal(Profile.INTERNAL_PID);
+        Map<String, Object> config = getConfigurationInternal(Profile.INTERNAL_PID);
         config.put(prefix + value, value);
         addConfiguration(Profile.INTERNAL_PID, config);
     }

http://git-wip-us.apache.org/repos/asf/karaf/blob/3cd6866b/profile/src/main/java/org/apache/karaf/profile/impl/ProfileImpl.java
----------------------------------------------------------------------
diff --git a/profile/src/main/java/org/apache/karaf/profile/impl/ProfileImpl.java b/profile/src/main/java/org/apache/karaf/profile/impl/ProfileImpl.java
index f23c3c4..bcd1b03 100644
--- a/profile/src/main/java/org/apache/karaf/profile/impl/ProfileImpl.java
+++ b/profile/src/main/java/org/apache/karaf/profile/impl/ProfileImpl.java
@@ -43,7 +43,7 @@ final class ProfileImpl implements Profile {
     private final Map<String, String> attributes;
     private final List<String> parents = new ArrayList<>();
     private final Map<String, byte[]> fileConfigurations = new HashMap<>();
-    private final Map<String, Map<String, String>> configurations = new HashMap<>();
+    private final Map<String, Map<String, Object>> configurations = new HashMap<>();
     private final boolean isOverlay;
     private int hash;
 
@@ -97,13 +97,13 @@ final class ProfileImpl implements Profile {
 
     private Map<String, String> getPrefixedMap(String prefix) {
         Map<String, String> map = new HashMap<>();
-        Map<String, String> agentConfig = configurations.get(Profile.INTERNAL_PID);
+        Map<String, Object> agentConfig = configurations.get(Profile.INTERNAL_PID);
         if (agentConfig != null) {
             int prefixLength = prefix.length();
-            for (Entry<String, String> entry : agentConfig.entrySet()) {
+            for (Entry<String, Object> entry : agentConfig.entrySet()) {
                 String key = entry.getKey();
                 if (key.startsWith(prefix)) {
-                    map.put(key.substring(prefixLength), entry.getValue());
+                    map.put(key.substring(prefixLength), entry.getValue().toString());
                 }
             }
         }
@@ -147,12 +147,16 @@ final class ProfileImpl implements Profile {
 
     @Override
     public boolean isAbstract() {
-        return Boolean.parseBoolean(getAttributes().get(ABSTRACT));
+        return parseBoolean(getAttributes().get(ABSTRACT));
     }
 
     @Override
     public boolean isHidden() {
-        return Boolean.parseBoolean(getAttributes().get(HIDDEN));
+        return parseBoolean(getAttributes().get(HIDDEN));
+    }
+
+    private Boolean parseBoolean(Object obj) {
+        return obj instanceof Boolean ? (Boolean) obj : Boolean.parseBoolean(obj.toString());
     }
 
     public boolean isOverlay() {
@@ -174,24 +178,24 @@ final class ProfileImpl implements Profile {
         return fileConfigurations.get(fileName);
     }
 
-    public Map<String, Map<String, String>> getConfigurations() {
+    public Map<String, Map<String, Object>> getConfigurations() {
         return Collections.unmodifiableMap(configurations);
     }
 
     @Override
-    public Map<String, String> getConfiguration(String pid) {
-        Map<String, String> config = configurations.get(pid);
-        config = config != null ? config : Collections.<String, String> emptyMap();
+    public Map<String, Object> getConfiguration(String pid) {
+        Map<String, Object> config = configurations.get(pid);
+        config = config != null ? config : Collections.emptyMap();
         return Collections.unmodifiableMap(config);
     }
 
     private List<String> getContainerConfigList(ConfigListType type) {
-        Map<String, String> containerProps = getConfiguration(Profile.INTERNAL_PID);
+        Map<String, Object> containerProps = getConfiguration(Profile.INTERNAL_PID);
         List<String> rc = new ArrayList<>();
         String prefix = type + ".";
-        for (Map.Entry<String, String> e : containerProps.entrySet()) {
+        for (Map.Entry<String, Object> e : containerProps.entrySet()) {
             if ((e.getKey()).startsWith(prefix)) {
-                rc.add(e.getValue());
+                rc.add(e.getValue().toString());
             }
         }
         return rc;
@@ -239,7 +243,7 @@ final class ProfileImpl implements Profile {
 
         private String value;
 
-        private ConfigListType(String value) {
+        ConfigListType(String value) {
             this.value = value;
         }
 

http://git-wip-us.apache.org/repos/asf/karaf/blob/3cd6866b/profile/src/main/java/org/apache/karaf/profile/impl/Profiles.java
----------------------------------------------------------------------
diff --git a/profile/src/main/java/org/apache/karaf/profile/impl/Profiles.java b/profile/src/main/java/org/apache/karaf/profile/impl/Profiles.java
index 4fc3bd8..c9ded5c 100644
--- a/profile/src/main/java/org/apache/karaf/profile/impl/Profiles.java
+++ b/profile/src/main/java/org/apache/karaf/profile/impl/Profiles.java
@@ -24,19 +24,14 @@ import java.nio.file.Path;
 import java.nio.file.SimpleFileVisitor;
 import java.nio.file.StandardOpenOption;
 import java.nio.file.attribute.BasicFileAttributes;
-import java.util.AbstractMap;
-import java.util.AbstractSet;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.HashMap;
-import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
-import java.util.Set;
 
-import org.apache.felix.utils.properties.InterpolationHelper;
-import org.apache.felix.utils.properties.Properties;
+import org.apache.felix.utils.properties.TypedProperties;
 import org.apache.karaf.profile.PlaceholderResolver;
 import org.apache.karaf.profile.Profile;
 import org.apache.karaf.profile.ProfileBuilder;
@@ -142,7 +137,7 @@ public final class Profiles {
 
     public static Profile getEffective(final Profile profile, boolean finalSubstitution) {
         return getEffective(profile,
-                Collections.<PlaceholderResolver>singleton(new PlaceholderResolvers.ProfilePlaceholderResolver()),
+                Collections.singleton(new PlaceholderResolvers.ProfilePlaceholderResolver()),
                 finalSubstitution);
     }
 
@@ -156,165 +151,55 @@ public final class Profiles {
                                        boolean finalSubstitution) {
         assertNotNull(profile, "profile is null");
         assertNotNull(profile, "resolvers is null");
-        // Build dynamic configurations which can support lazy computation of substituted values
-        final Map<String, Map<String, String>> dynamic = new HashMap<>();
-        final Map<String, Properties> originals = new HashMap<>();
+
+        final Map<String, TypedProperties> originals = new HashMap<>();
         for (Map.Entry<String, byte[]> entry : profile.getFileConfigurations().entrySet()) {
             if (entry.getKey().endsWith(Profile.PROPERTIES_SUFFIX)) {
                 try {
                     String key = entry.getKey().substring(0, entry.getKey().length() - Profile.PROPERTIES_SUFFIX.length());
-                    Properties props = new Properties(false);
+                    TypedProperties props = new TypedProperties(false);
                     props.load(new ByteArrayInputStream(entry.getValue()));
                     originals.put(key, props);
-                    dynamic.put(key, new DynamicMap(dynamic, key, props, resolvers, finalSubstitution));
                 } catch (IOException e) {
                     throw new IllegalArgumentException("Can not load properties for " + entry.getKey());
                 }
             }
         }
-        // Force computation while preserving layout
-        ProfileBuilder builder = ProfileBuilder.Factory.createFrom(profile);
-        for (Map.Entry<String, Map<String, String>> cfg : dynamic.entrySet()) {
-            Properties original = originals.get(cfg.getKey());
-            original.keySet().retainAll(cfg.getValue().keySet());
-            original.putAll(cfg.getValue());
-            builder.addFileConfiguration(cfg.getKey() + Profile.PROPERTIES_SUFFIX, Utils.toBytes(original));
-        }
-        // Compute the new profile
-        return builder.getProfile();
-    }
-
-    private static class DynamicMap extends AbstractMap<String, String> {
-
-        private final Map<String, String> computed = new HashMap<>();
-        private final Map<String, String> cycles = new HashMap<>();
-        private final Map<String, Map<String, String>> profile;
-        private final String pid;
-        private final Map<String, String> original;
-        private final Collection<PlaceholderResolver> resolvers;
-        private final boolean finalSubstitution;
-
-        private DynamicMap(Map<String, Map<String, String>> profile,
-                          String pid,
-                          Map<String, String> original,
-                          Collection<PlaceholderResolver> resolvers,
-                          boolean finalSubstitution) {
-            this.profile = profile;
-            this.pid = pid;
-            this.original = original;
-            this.resolvers = resolvers;
-            this.finalSubstitution = finalSubstitution;
-        }
-
-        @Override
-        public Set<Entry<String, String>> entrySet() {
-            return new DynamicEntrySet();
-        }
-
-        private class DynamicEntrySet extends AbstractSet<Entry<String, String>> {
-
-            @Override
-            public Iterator<Entry<String, String>> iterator() {
-                return new DynamicEntrySetIterator();
-            }
-
-            @Override
-            public int size() {
-                return original.size();
-            }
-
-        }
-
-        private class DynamicEntrySetIterator implements Iterator<Entry<String, String>> {
-            final Iterator<Entry<String, String>> delegate = original.entrySet().iterator();
-
-            @Override
-            public boolean hasNext() {
-                return delegate.hasNext();
-            }
-
-            @Override
-            public Entry<String, String> next() {
-                final Entry<String, String> original = delegate.next();
-                return new DynamicEntry(original.getKey(), original.getValue());
-            }
-
-            @Override
-            public void remove() {
-                throw new UnsupportedOperationException();
-            }
-        }
-
-        private class DynamicEntry implements Entry<String, String> {
-
-            private final String key;
-            private final String value;
-
-            private DynamicEntry(String key, String value) {
-                this.key = key;
-                this.value = value;
-            }
-
-            @Override
-            public String getKey() {
-                return key;
-            }
-
-            @Override
-            public String getValue() {
-                String v = computed.get(key);
-                if (v == null) {
-                    v = compute();
-                    computed.put(key, v);
-                }
-                return v;
-            }
-
-            private String compute() {
-                InterpolationHelper.SubstitutionCallback callback = new InterpolationHelper.SubstitutionCallback() {
-                    public String getValue(String value) {
-                        if (value != null) {
-                            for (PlaceholderResolver resolver : resolvers) {
-                                if (resolver.getScheme() == null) {
-                                    String val = resolver.resolve(profile, pid, key, value);
-                                    if (val != null) {
-                                        return val;
-                                    }
-                                }
-                            }
-                            if (value.contains(":")) {
-                                String scheme = value.substring(0, value.indexOf(":"));
-                                String toSubst = value.substring(scheme.length() + 1);
-                                for (PlaceholderResolver resolver : resolvers) {
-                                    if (scheme.equals(resolver.getScheme())) {
-                                        String val = resolver.resolve(profile, pid, key, toSubst);
-                                        if (val != null) {
-                                            return val;
-                                        }
-                                    }
-                                }
-                            }
-                        }
-                        return null;
-                    }
-                };
-                String v = InterpolationHelper.substVars(value, key, cycles, DynamicMap.this, callback, finalSubstitution, finalSubstitution, finalSubstitution);
+        final Map<String, Map<String, String>> dynamic = TypedProperties.prepare(originals);
+        TypedProperties.substitute(originals, dynamic, (pid, key, value) -> {
+            if (value != null) {
                 for (PlaceholderResolver resolver : resolvers) {
-                    if (PlaceholderResolver.CATCH_ALL_SCHEME.equals(resolver.getScheme())) {
-                        String val = resolver.resolve(profile, pid, key, v);
+                    if (resolver.getScheme() == null) {
+                        String val = resolver.resolve(dynamic, pid, key, value);
                         if (val != null) {
-                            v = val;
+                            return val;
+                        }
+                    }
+                }
+                if (value.contains(":")) {
+                    String scheme = value.substring(0, value.indexOf(":"));
+                    String toSubst = value.substring(scheme.length() + 1);
+                    for (PlaceholderResolver resolver : resolvers) {
+                        if (scheme.equals(resolver.getScheme())) {
+                            String val = resolver.resolve(dynamic, pid, key, toSubst);
+                            if (val != null) {
+                                return val;
+                            }
                         }
                     }
                 }
-                return v;
             }
+            return null;
+        }, finalSubstitution);
 
-            @Override
-            public String setValue(String value) {
-                throw new UnsupportedOperationException();
-            }
+         // Force computation while preserving layout
+        ProfileBuilder builder = ProfileBuilder.Factory.createFrom(profile);
+        for (Map.Entry<String, TypedProperties> cfg : originals.entrySet()) {
+            TypedProperties original = cfg.getValue();
+            builder.addFileConfiguration(cfg.getKey() + Profile.PROPERTIES_SUFFIX, Utils.toBytes(original));
         }
+        // Compute the new profile
+        return builder.getProfile();
     }
 
     static private class OverlayOptionsProvider {
@@ -325,7 +210,7 @@ public final class Profiles {
 
         private static class SupplementControl {
             byte[] data;
-            Properties props;
+            TypedProperties props;
         }
 
         private OverlayOptionsProvider(Map<String, Profile> profiles, Profile self, String environment) {
@@ -391,13 +276,13 @@ public final class Profiles {
                     SupplementControl ctrl = aggregate.get(key);
                     if (ctrl != null) {
                         // we can update the file..
-                        Properties childMap = Utils.toProperties(value);
+                        TypedProperties childMap = Utils.toProperties(value);
                         if (childMap.remove(Profile.DELETED) != null) {
                             ctrl.props.clear();
                         }
 
                         // Update the entries...
-                        for (Map.Entry<String, String> p : childMap.entrySet()) {
+                        for (Map.Entry<String, Object> p : childMap.entrySet()) {
                             if (Profile.DELETED.equals(p.getValue())) {
                                 ctrl.props.remove(p.getKey());
                             } else {

http://git-wip-us.apache.org/repos/asf/karaf/blob/3cd6866b/profile/src/main/java/org/apache/karaf/profile/impl/Utils.java
----------------------------------------------------------------------
diff --git a/profile/src/main/java/org/apache/karaf/profile/impl/Utils.java b/profile/src/main/java/org/apache/karaf/profile/impl/Utils.java
index 7bc016a..ccc5b38 100644
--- a/profile/src/main/java/org/apache/karaf/profile/impl/Utils.java
+++ b/profile/src/main/java/org/apache/karaf/profile/impl/Utils.java
@@ -22,6 +22,7 @@ import java.io.IOException;
 import java.util.Map;
 
 import org.apache.felix.utils.properties.Properties;
+import org.apache.felix.utils.properties.TypedProperties;
 
 public final class Utils {
 
@@ -57,23 +58,33 @@ public final class Utils {
     }
 
 
+    public static byte[] toBytes(TypedProperties source) {
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        try {
+            source.save(baos);
+        } catch (IOException ex) {
+            throw new IllegalArgumentException("Cannot store properties", ex);
+        }
+        return baos.toByteArray();
+    }
+
     public static byte[] toBytes(Properties source) {
         ByteArrayOutputStream baos = new ByteArrayOutputStream();
         try {
-            source.store(baos, null);
+            source.save(baos);
         } catch (IOException ex) {
             throw new IllegalArgumentException("Cannot store properties", ex);
         }
         return baos.toByteArray();
     }
 
-    public static byte[] toBytes(Map<String, String> source) {
+    public static byte[] toBytes(Map<String, Object> source) {
         return toBytes(toProperties(source));
     }
 
-    public static Properties toProperties(byte[] source)  {
+    public static TypedProperties toProperties(byte[] source)  {
         try {
-            Properties rc = new Properties(false);
+            TypedProperties rc = new TypedProperties(false);
             if (source != null) {
                 rc.load(new ByteArrayInputStream(source));
             }
@@ -83,17 +94,13 @@ public final class Utils {
         }
     }
 
-    public static Properties toProperties(Map<String, String> source) {
-        try {
-            if (source instanceof Properties) {
-                return (Properties) source;
-            }
-            Properties rc = new Properties(false);
-            rc.putAll(source);
-            return rc;
-        } catch (IOException ex) {
-            throw new IllegalArgumentException("Cannot load properties", ex);
+    public static TypedProperties toProperties(Map<String, Object> source) {
+        if (source instanceof TypedProperties) {
+            return (TypedProperties) source;
         }
+        TypedProperties rc = new TypedProperties(false);
+        rc.putAll(source);
+        return rc;
     }
 
     public static String stripSuffix(String value, String suffix) {