[KARAF-2647] Add Karaf 3.0.0 support
diff --git a/plugins/org.apache.karaf.eik.core/src/main/java/org/apache/karaf/eik/core/IKarafConstants.java b/plugins/org.apache.karaf.eik.core/src/main/java/org/apache/karaf/eik/core/IKarafConstants.java
index 2ee7450..fa8bce5 100644
--- a/plugins/org.apache.karaf.eik.core/src/main/java/org/apache/karaf/eik/core/IKarafConstants.java
+++ b/plugins/org.apache.karaf.eik.core/src/main/java/org/apache/karaf/eik/core/IKarafConstants.java
@@ -30,7 +30,9 @@
 
     public static final String KARAF_DATA_PROP = "karaf.data";
 
-    public static final String KARAF_DEFAULT_BUNDLE_START_LEVEL = "60";
+    public static final String KARAF_ETC_PROP = "karaf.etc";
+
+    public static final String KARAF_DEFAULT_BUNDLE_START_LEVEL = "80";
 
     public static final String KARAF_DEFAULT_CONFIG_PROPERTIES_FILE = "config.properties";
 
diff --git a/plugins/org.apache.karaf.eik.core/src/main/java/org/apache/karaf/eik/core/configuration/internal/StartupSectionImpl.java b/plugins/org.apache.karaf.eik.core/src/main/java/org/apache/karaf/eik/core/configuration/internal/StartupSectionImpl.java
index 2c70edf..d217975 100644
--- a/plugins/org.apache.karaf.eik.core/src/main/java/org/apache/karaf/eik/core/configuration/internal/StartupSectionImpl.java
+++ b/plugins/org.apache.karaf.eik.core/src/main/java/org/apache/karaf/eik/core/configuration/internal/StartupSectionImpl.java
@@ -31,7 +31,7 @@
 import org.eclipse.osgi.service.resolver.BundleDescription;
 
 public class StartupSectionImpl extends AbstractPropertiesConfigurationSection implements
-                StartupSection {
+        StartupSection {
 
     /**
      * Simple object that models a start level and {@link BundleDescription}
@@ -70,9 +70,8 @@
      * Constructor. This will build the necessary data objects to support
      * querying the Karaf target platform startup state model.
      *
-     * @param karafModel
-     *            the {@link KarafPlatformModel} that will be used to build the
-     *            startup state model
+     * @param karafModel the {@link KarafPlatformModel} that will be used to build the
+     *                   startup state model
      */
     public StartupSectionImpl(KarafPlatformModel karafModel) {
         super(STARTUP_SECTION_ID, STARTUP_FILENAME, karafModel);
@@ -110,24 +109,53 @@
     }
 
     /**
+     * Converts a MVN url to a file path, relative to System.
+     * Code taken from MvnUrlConverter from UI plugin.
+     * TODO: move class MvnUrlConverter inside core plugin and use it
+     * as dependency from UI plugin.
+     */
+    protected String getPath(String url) {
+        if (url != null) {
+            if (url.startsWith("mvn:")) {
+                url = url.substring(4);
+                String[] repositorySplit = url.split("!");
+                String urlWithoutRepository = repositorySplit[repositorySplit.length - 1];
+
+                String[] segments = urlWithoutRepository.split("/");
+                if (segments.length >= 3) {
+                    String groupId = segments[0];
+                    String artifactId = segments[1];
+                    String version = segments[2];
+
+                    return groupId.replace(".", "/") + "/" + artifactId + "/" + version + "/" + artifactId + "-" + version + ".jar";
+                }
+            }
+        }
+
+        return url;
+    }
+
+    /**
      * Populates the startup state model with the {@link BundleDescriptions} of
      * the bundles found in the startup configuration.
      */
     protected void populateStartupStateModel() {
         final File rootBundleDir = getParent().getPluginRootDirectory().toFile();
         for (Object o : getProperties().keySet()) {
-            final File bundleLocation = new File(rootBundleDir, (String) o);
+            // In karaf-3.0.0, mvn urls are sored instead of raw paths.
+            // Then first try to convert mvn urls to raw path.
+            final File bundleLocation = new File(rootBundleDir, getPath((String) o));
 
             final BundleDescription desc = getParent().getState().getBundleByLocation(
-                            bundleLocation.getAbsolutePath());
+                    bundleLocation.getAbsolutePath());
 
             if (desc == null) {
                 KarafCorePluginActivator.getLogger().error(
-                                "Unable to locate bundle description for: "
-                                                + bundleLocation.getAbsolutePath());
+                        "Unable to locate bundle description for: "
+                                + bundleLocation.getAbsolutePath());
             } else {
                 final BundleStartEntry se = new BundleStartEntry(desc, (String) getProperties()
-                                .get(o));
+                        .get(o));
                 startupStateModel.put(desc.getSymbolicName(), se);
 
             }
diff --git a/plugins/org.apache.karaf.eik.ui/src/main/java/org/apache/karaf/eik/ui/features/FeaturesResolverJob.java b/plugins/org.apache.karaf.eik.ui/src/main/java/org/apache/karaf/eik/ui/features/FeaturesResolverJob.java
index c89917d..9dde301 100644
--- a/plugins/org.apache.karaf.eik.ui/src/main/java/org/apache/karaf/eik/ui/features/FeaturesResolverJob.java
+++ b/plugins/org.apache.karaf.eik.ui/src/main/java/org/apache/karaf/eik/ui/features/FeaturesResolverJob.java
@@ -55,7 +55,7 @@
     private static final String ORG_OPS4J_PAX_URL_MVN_CFG = "org.ops4j.pax.url.mvn.cfg";
 
     private final List<FeaturesRepository> featuresRepositories =
-        Collections.synchronizedList(new ArrayList<FeaturesRepository>());
+            Collections.synchronizedList(new ArrayList<FeaturesRepository>());
 
     private final FeaturesSection featuresSection;
 
@@ -90,10 +90,9 @@
     /**
      * Helper method that resolves Karaf Features.
      *
-     * @param monitor
-     *            the {@link IProgressMonitor} instance
+     * @param monitor the {@link IProgressMonitor} instance
      * @return the {@link Status#OK_STATUS} if the Features are successfully
-     *         resolved
+     * resolved
      */
     private IStatus resolveFeatures(final IProgressMonitor monitor) {
         monitor.beginTask("Loading Karaf Features", featuresSection.getRepositoryList().size());
@@ -108,7 +107,7 @@
                 try {
                     // Begin: Refactor this out in to an OPS4j mvn URL configuration
                     final Properties mvnConfiguration =
-                        KarafCorePluginUtils.loadProperties(karafPlatformModel.getConfigurationDirectory().toFile(), ORG_OPS4J_PAX_URL_MVN_CFG);
+                            KarafCorePluginUtils.loadProperties(karafPlatformModel.getConfigurationDirectory().toFile(), ORG_OPS4J_PAX_URL_MVN_CFG);
 
                     final IKarafProject karafProject = (IKarafProject) karafPlatformModel.getAdapter(IKarafProject.class);
                     final Properties runtimeProperties = karafProject.getRuntimeProperties();
@@ -118,7 +117,15 @@
                     final String defaultRepos = (String) mvnConfiguration.get("org.ops4j.pax.url.mvn.defaultRepositories");
                     final String repos = (String) mvnConfiguration.get("org.ops4j.pax.url.mvn.repositories");
 
-                    final String combinedRepos = KarafCorePluginUtils.join(Arrays.asList(new String[] { defaultRepos, repos }), ",");
+                    // In karaf-3.0.0, default repo may be null.
+                    // First check if it's null an if not then add it to repo list
+                    ArrayList<String> reposList = new ArrayList<String>();
+                    if (defaultRepos != null)
+                        reposList.add(defaultRepos);
+                    if (repos != null)
+                        reposList.add(repos);
+                    final String combinedRepos = KarafCorePluginUtils.join(reposList, ",");
+
                     mvnConfiguration.put("org.ops4j.pax.url.mvn.repositories", removeInvalidSuffixes(combinedRepos));
                     // End: Refactor
 
@@ -168,26 +175,24 @@
         }
     }
 
-	private String removeInvalidSuffixes(String mergedRepositories) {
-		String[] repositories = mergedRepositories.split(",");
-		
-		for (int i = 0; i < repositories.length; i++) {
-			String repository = repositories[0];
-			String[] segments = repository.split("@");
-			StringBuilder urlBuilder = new StringBuilder(segments[0]);
-			for (int j = 0; j < segments.length; ++j)
-			{
-				String segment = segments[j];
-				if (segment.trim().equalsIgnoreCase("snapshots") || segment.trim().equalsIgnoreCase("noreleases"))
-				{
-					urlBuilder.append("@");
-					urlBuilder.append(segment);
-				}
-			}
-			repositories[i] = urlBuilder.toString();
-		}
-		
-		return KarafCorePluginUtils.join(Arrays.asList(repositories), ",");
-	}
+    private String removeInvalidSuffixes(String mergedRepositories) {
+        String[] repositories = mergedRepositories.split(",");
+
+        for (int i = 0; i < repositories.length; i++) {
+            String repository = repositories[0];
+            String[] segments = repository.split("@");
+            StringBuilder urlBuilder = new StringBuilder(segments[0]);
+            for (int j = 0; j < segments.length; ++j) {
+                String segment = segments[j];
+                if (segment.trim().equalsIgnoreCase("snapshots") || segment.trim().equalsIgnoreCase("noreleases")) {
+                    urlBuilder.append("@");
+                    urlBuilder.append(segment);
+                }
+            }
+            repositories[i] = urlBuilder.toString();
+        }
+
+        return KarafCorePluginUtils.join(Arrays.asList(repositories), ",");
+    }
 
 }
diff --git a/plugins/org.apache.karaf.eik.ui/src/main/java/org/apache/karaf/eik/ui/project/KarafProjectBuilder.java b/plugins/org.apache.karaf.eik.ui/src/main/java/org/apache/karaf/eik/ui/project/KarafProjectBuilder.java
index c79ecf2..89f4283 100644
--- a/plugins/org.apache.karaf.eik.ui/src/main/java/org/apache/karaf/eik/ui/project/KarafProjectBuilder.java
+++ b/plugins/org.apache.karaf.eik.ui/src/main/java/org/apache/karaf/eik/ui/project/KarafProjectBuilder.java
@@ -194,6 +194,8 @@
         combinedProperties.put("karaf.home", karafHome);
         combinedProperties.put("karaf.base", karafHome);
         combinedProperties.put("karaf.data", getKarafPlatformModel().getRootDirectory().append("data").toOSString());
+        // Add ref to karaf.etc for karaf-3.0.0
+        combinedProperties.put("karaf.etc", getKarafPlatformModel().getRootDirectory().append("etc").toOSString());
 
         for (final String filename : new String[]{"config.properties", "system.properties", "users.properties"}) {
             final Properties fileProperties = KarafCorePluginUtils.loadProperties(getKarafPlatformModel().getConfigurationDirectory().toFile(), filename, true);
diff --git a/plugins/org.apache.karaf.eik.ui/src/main/java/org/apache/karaf/eik/ui/project/impl/KarafRuntimePropertyBuildUnit.java b/plugins/org.apache.karaf.eik.ui/src/main/java/org/apache/karaf/eik/ui/project/impl/KarafRuntimePropertyBuildUnit.java
index 9ff0dde..527c6a2 100644
--- a/plugins/org.apache.karaf.eik.ui/src/main/java/org/apache/karaf/eik/ui/project/impl/KarafRuntimePropertyBuildUnit.java
+++ b/plugins/org.apache.karaf.eik.ui/src/main/java/org/apache/karaf/eik/ui/project/impl/KarafRuntimePropertyBuildUnit.java
@@ -49,6 +49,8 @@
         final Properties combinedProperties = new Properties();
         combinedProperties.put("karaf.home", karafHome);
         combinedProperties.put("karaf.base", karafHome);
+        // Add ref to karaf.etc for karaf-3.0.0
+        combinedProperties.put("karaf.etc", getKarafPlatformModel().getRootDirectory().append("etc").toOSString());
         combinedProperties.put("karaf.data", getKarafPlatformModel().getRootDirectory().append("data").toOSString());
 
         for (final String filename : new String[] { "config.properties", "system.properties", "users.properties" }) {
diff --git a/plugins/org.apache.karaf.eik.ui/src/main/java/org/apache/karaf/eik/ui/workbench/internal/GenericKarafWorkbenchService.java b/plugins/org.apache.karaf.eik.ui/src/main/java/org/apache/karaf/eik/ui/workbench/internal/GenericKarafWorkbenchService.java
index ec58ad9..0be461d 100644
--- a/plugins/org.apache.karaf.eik.ui/src/main/java/org/apache/karaf/eik/ui/workbench/internal/GenericKarafWorkbenchService.java
+++ b/plugins/org.apache.karaf.eik.ui/src/main/java/org/apache/karaf/eik/ui/workbench/internal/GenericKarafWorkbenchService.java
@@ -71,8 +71,7 @@
          * Returns the console for the given {@link IProcess}, or {@code null}
          * if none.
          *
-         * @param process
-         *            the {@code IProcess} whose console is to be found
+         * @param process the {@code IProcess} whose console is to be found
          * @return the console for the given process, or {@code null} if none
          */
         public IConsole findConsole(final IProcess process) {
@@ -94,10 +93,9 @@
          * Returns the {@link IDocument} for the {@link IProcess}, or
          * {@code null} if none is available.
          *
-         * @param process
-         *            the {@code IProcess} whose document is to be retrieved
+         * @param process the {@code IProcess} whose document is to be retrieved
          * @return the {@code IDocument} for the specified {@code IProcess} or
-         *         {@code null} if one could not be found
+         * {@code null} if one could not be found
          */
         public IDocument getConsoleDocument(final IProcess process) {
             final KarafRemoteConsole console = (KarafRemoteConsole) findConsole(process);
@@ -127,18 +125,18 @@
                 final String encoding = launch.getAttribute(DebugPlugin.ATTR_CONSOLE_ENCODING);
 
                 final KarafPlatformModel karafPlatform =
-                    (KarafPlatformModel) launch.getLaunchConfiguration().getAdapter(KarafPlatformModel.class);
+                        (KarafPlatformModel) launch.getLaunchConfiguration().getAdapter(KarafPlatformModel.class);
 
                 final KarafSshConnectionUrl sshConnectionUrl =
-                    (KarafSshConnectionUrl) karafPlatform.getAdapter(KarafSshConnectionUrl.class);
+                        (KarafSshConnectionUrl) karafPlatform.getAdapter(KarafSshConnectionUrl.class);
 
                 final KarafSshShellConnection.Credentials credentials;
 
                 try {
                     final String username =
-                        launch.getLaunchConfiguration().getAttribute(KarafLaunchConfigurationConstants.KARAF_REMOTE_CONSOLE_USERNAME, "karaf");
+                            launch.getLaunchConfiguration().getAttribute(KarafLaunchConfigurationConstants.KARAF_REMOTE_CONSOLE_USERNAME, "karaf");
                     final String password =
-                        launch.getLaunchConfiguration().getAttribute(KarafLaunchConfigurationConstants.KARAF_REMOTE_CONSOLE_PASSWORD, "karaf");
+                            launch.getLaunchConfiguration().getAttribute(KarafLaunchConfigurationConstants.KARAF_REMOTE_CONSOLE_PASSWORD, "karaf");
 
                     credentials = new KarafSshShellConnection.Credentials(username, password);
                 } catch (final CoreException e) {
@@ -155,7 +153,7 @@
 
                 remoteConsole.setAttribute(IDebugUIConstants.ATTR_CONSOLE_PROCESS, process);
 
-                ConsolePlugin.getDefault().getConsoleManager().addConsoles(new IConsole[] { remoteConsole });
+                ConsolePlugin.getDefault().getConsoleManager().addConsoles(new IConsole[]{remoteConsole});
             }
         }
 
@@ -170,7 +168,7 @@
 
                 if (console != null) {
                     final IConsoleManager manager = ConsolePlugin.getDefault().getConsoleManager();
-                    manager.removeConsoles(new IConsole[] { console });
+                    manager.removeConsoles(new IConsole[]{console});
                 }
             }
         }
@@ -178,8 +176,7 @@
         /**
          * Determines whether or not the {@link ILaunch} is from an EIK launch
          *
-         * @param launch
-         *            the {@code ILaunch} to evaluate
+         * @param launch the {@code ILaunch} to evaluate
          * @return true if the {@code ILaunch} is an EIK launch
          */
         private boolean isKarafLaunch(final ILaunch launch) {
@@ -229,12 +226,12 @@
             }
 
             final String bundleLocation =
-                KarafCorePluginUtils.getBundleLocation(b);
+                    KarafCorePluginUtils.getBundleLocation(b);
 
             if (bundleLocation != null) {
                 final BundleEntry entry =
                         new BundleEntry.Builder(bundleLocation).startLevel("1").autostart("start").build(); //$NON-NLS-1$ $NON-NLS-2$
-                
+
                 bundleEntries.add(entry);
             }
         }
@@ -253,10 +250,10 @@
         final Properties currentConfig;
         try {
             currentConfig =
-                KarafCorePluginUtils.loadProperties(
-                    platformModel.getParentKarafModel().getConfigurationDirectory().toFile(),
-                    IKarafConstants.KARAF_DEFAULT_CONFIG_PROPERTIES_FILE,
-                    true);
+                    KarafCorePluginUtils.loadProperties(
+                            platformModel.getParentKarafModel().getConfigurationDirectory().toFile(),
+                            IKarafConstants.KARAF_DEFAULT_CONFIG_PROPERTIES_FILE,
+                            true);
 
             final Properties systemProperties = createLaunchSystemProperties(platformModel, configuration);
             currentConfig.putAll(systemProperties);
@@ -264,9 +261,9 @@
             PropertyUtils.interpolateVariables(currentConfig, currentConfig);
 
             for (final Map.Entry<Object, Object> e : currentConfig.entrySet()) {
-                equinoxProperties.put((String)e.getKey(), (String)e.getValue());
+                equinoxProperties.put((String) e.getKey(), (String) e.getValue());
             }
-        } catch(final CoreException e) {
+        } catch (final CoreException e) {
             KarafUIPluginActivator.getLogger().error("Unable to load configuration file: " + platformModel.getParentKarafModel().getConfigurationDirectory(), e);
         }
 
@@ -295,8 +292,7 @@
     public List<String> getVMArguments(
             final KarafWorkingPlatformModel platformModel,
             final ILaunchConfiguration configuration)
-        throws CoreException
-    {
+            throws CoreException {
         if (!platformModel.getParentKarafModel().getClass().equals(GenericKarafPlatformModel.class)) {
             return Collections.emptyList();
         }
@@ -351,8 +347,7 @@
             final ILaunchConfiguration configuration,
             final String mode,
             final ILaunch launch,
-            final IProgressMonitor monitor) throws CoreException
-    {
+            final IProgressMonitor monitor) throws CoreException {
         if (!platformModel.getParentKarafModel().getClass().equals(GenericKarafPlatformModel.class)) {
             return;
         }
@@ -398,7 +393,7 @@
         }
 
         final ManagementSection managementSection =
-            (ManagementSection) platformModel.getAdapter(ManagementSection.class);
+                (ManagementSection) platformModel.getAdapter(ManagementSection.class);
 
         managementSection.load();
         managementSection.setPort(jmxRegistryPort);
@@ -413,12 +408,12 @@
         }
 
         final FeaturesSection featuresSection =
-            (FeaturesSection) platformModel.getAdapter(FeaturesSection.class);
+                (FeaturesSection) platformModel.getAdapter(FeaturesSection.class);
 
         featuresSection.load();
 
         final String bootFeaturesString =
-            configuration.getAttribute(KarafLaunchConfigurationConstants.KARAF_LAUNCH_BOOT_FEATURES, ""); //$NON-NLS-1$
+                configuration.getAttribute(KarafLaunchConfigurationConstants.KARAF_LAUNCH_BOOT_FEATURES, ""); //$NON-NLS-1$
         final String[] bootFeaturesArray = bootFeaturesString.split(",");
 
         final List<String> features = new ArrayList<String>();
@@ -438,36 +433,41 @@
                 platformModel.getParentKarafModel().getRootDirectory().toString());
 
         systemProperties.put(
-            IKarafConstants.KARAF_HOME_PROP,
-            platformModel.getParentKarafModel().getRootDirectory().toString());
+                IKarafConstants.KARAF_HOME_PROP,
+                platformModel.getParentKarafModel().getRootDirectory().toString());
+
+        // Add ref to karaf.etc for karaf 3.0.0
+        systemProperties.put(
+                IKarafConstants.KARAF_ETC_PROP,
+                platformModel.getParentKarafModel().getRootDirectory().append("etc").toOSString());
 
         systemProperties.put(
-            "java.util.logging.config.file", //$NON-NLS-1$
-            platformModel.getParentKarafModel().getConfigurationDirectory().append("java.util.logging.properties").toString()); //$NON-NLS-1$
+                "java.util.logging.config.file", //$NON-NLS-1$
+                platformModel.getParentKarafModel().getConfigurationDirectory().append("java.util.logging.properties").toString()); //$NON-NLS-1$
 
         systemProperties.put(
-            IKarafConstants.KARAF_DATA_PROP,
-            platformModel.getParentKarafModel().getRootDirectory().append("data").toString()); //$NON-NLS-1$
+                IKarafConstants.KARAF_DATA_PROP,
+                platformModel.getParentKarafModel().getRootDirectory().append("data").toString()); //$NON-NLS-1$
 
         systemProperties.put(
-            IKarafConstants.KARAF_INSTANCES_PROP,
-            platformModel.getParentKarafModel().getRootDirectory().append("instances").toString()); //$NON-NLS-1$
+                IKarafConstants.KARAF_INSTANCES_PROP,
+                platformModel.getParentKarafModel().getRootDirectory().append("instances").toString()); //$NON-NLS-1$
 
         final Boolean startLocalConsole =
-            configuration.getAttribute(
-                    KarafLaunchConfigurationConstants.KARAF_LAUNCH_START_LOCAL_CONSOLE,
-                    true);
+                configuration.getAttribute(
+                        KarafLaunchConfigurationConstants.KARAF_LAUNCH_START_LOCAL_CONSOLE,
+                        true);
         systemProperties.put(
-            "karaf.startLocalConsole", //$NON-NLS-1$
-            startLocalConsole.toString());
+                "karaf.startLocalConsole", //$NON-NLS-1$
+                startLocalConsole.toString());
 
         final Boolean startRemoteConsole =
-            configuration.getAttribute(
-                    KarafLaunchConfigurationConstants.KARAF_LAUNCH_START_REMOTE_CONSOLE,
-                    false);
+                configuration.getAttribute(
+                        KarafLaunchConfigurationConstants.KARAF_LAUNCH_START_REMOTE_CONSOLE,
+                        false);
         systemProperties.put(
-            "karaf.startRemoteShell", //$NON-NLS-1$
-            startRemoteConsole.toString());
+                "karaf.startRemoteShell", //$NON-NLS-1$
+                startRemoteConsole.toString());
 
         PropertyUtils.interpolateVariables(systemProperties, systemProperties);
         return systemProperties;
@@ -477,13 +477,13 @@
 
         try {
             final Properties properties =
-                KarafCorePluginUtils.loadProperties(
-                    platformModel.getParentKarafModel().getConfigurationDirectory().toFile(),
-                    IKarafConstants.KARAF_DEFAULT_SYSTEM_PROPERTIES_FILE,
-                    true);
+                    KarafCorePluginUtils.loadProperties(
+                            platformModel.getParentKarafModel().getConfigurationDirectory().toFile(),
+                            IKarafConstants.KARAF_DEFAULT_SYSTEM_PROPERTIES_FILE,
+                            true);
 
             return properties;
-        } catch(final CoreException e) {
+        } catch (final CoreException e) {
             KarafUIPluginActivator.getLogger().error("Unable to load configuration file: " + platformModel.getConfigurationDirectory(), e);
         }