Convert SaltEntity to a SoftwareProcess entity
diff --git a/software/cm/salt/src/main/java/org/apache/brooklyn/entity/cm/salt/SaltEntity.java b/software/cm/salt/src/main/java/org/apache/brooklyn/entity/cm/salt/SaltEntity.java
index 4428658..e308a20 100644
--- a/software/cm/salt/src/main/java/org/apache/brooklyn/entity/cm/salt/SaltEntity.java
+++ b/software/cm/salt/src/main/java/org/apache/brooklyn/entity/cm/salt/SaltEntity.java
@@ -23,7 +23,6 @@
 import org.apache.brooklyn.api.catalog.Catalog;
 import org.apache.brooklyn.api.entity.ImplementedBy;
 import org.apache.brooklyn.api.sensor.AttributeSensor;
-import org.apache.brooklyn.entity.cm.salt.impl.SaltEntityImpl;
 import org.apache.brooklyn.config.ConfigKey;
 import org.apache.brooklyn.core.annotation.Effector;
 import org.apache.brooklyn.core.annotation.EffectorParam;
diff --git a/software/cm/salt/src/main/java/org/apache/brooklyn/entity/cm/salt/SaltEntityDriver.java b/software/cm/salt/src/main/java/org/apache/brooklyn/entity/cm/salt/SaltEntityDriver.java
index 19a88ed..a435991 100644
--- a/software/cm/salt/src/main/java/org/apache/brooklyn/entity/cm/salt/SaltEntityDriver.java
+++ b/software/cm/salt/src/main/java/org/apache/brooklyn/entity/cm/salt/SaltEntityDriver.java
@@ -19,7 +19,8 @@
 package org.apache.brooklyn.entity.cm.salt;
 
 import org.apache.brooklyn.entity.software.base.SoftwareProcessDriver;
+import org.apache.brooklyn.util.core.task.system.ProcessTaskWrapper;
 
 public interface SaltEntityDriver extends SoftwareProcessDriver {
-
+    ProcessTaskWrapper<Integer> saltCall(String spec);
 }
diff --git a/software/cm/salt/src/main/java/org/apache/brooklyn/entity/cm/salt/impl/SaltEntityImpl.java b/software/cm/salt/src/main/java/org/apache/brooklyn/entity/cm/salt/SaltEntityImpl.java
similarity index 79%
rename from software/cm/salt/src/main/java/org/apache/brooklyn/entity/cm/salt/impl/SaltEntityImpl.java
rename to software/cm/salt/src/main/java/org/apache/brooklyn/entity/cm/salt/SaltEntityImpl.java
index bea2581..e93ebe7 100644
--- a/software/cm/salt/src/main/java/org/apache/brooklyn/entity/cm/salt/impl/SaltEntityImpl.java
+++ b/software/cm/salt/src/main/java/org/apache/brooklyn/entity/cm/salt/SaltEntityImpl.java
@@ -7,7 +7,7 @@
  * "License"); you may not use this file except in compliance
  * with the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing,
  * software distributed under the License is distributed on an
@@ -16,25 +16,29 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.brooklyn.entity.cm.salt.impl;
+package org.apache.brooklyn.entity.cm.salt;
 
-import com.google.common.annotations.Beta;
-import org.apache.brooklyn.entity.cm.salt.SaltConfig;
-import org.apache.brooklyn.entity.cm.salt.SaltEntity;
-import org.apache.brooklyn.entity.stock.EffectorStartableImpl;
-import org.apache.brooklyn.util.core.task.DynamicTasks;
+import java.util.Set;
+
+import org.apache.brooklyn.entity.software.base.SoftwareProcessImpl;
 import org.apache.brooklyn.util.core.task.system.ProcessTaskWrapper;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import java.util.Set;
+import com.google.common.annotations.Beta;
 
 @Beta
-public class SaltEntityImpl extends EffectorStartableImpl implements SaltEntity {
+public class SaltEntityImpl extends SoftwareProcessImpl implements SaltEntity {
     private static final Logger LOG = LoggerFactory.getLogger(SaltEntityImpl.class);
 
-    public SaltEntityImpl() {
-        super();
+    @Override
+    public Class getDriverInterface() {
+        return SaltEntityDriver.class;
+    }
+
+    @Override
+    public SaltEntityDriver getDriver() {
+        return (SaltEntityDriver) super.getDriver();
     }
 
     @Override
@@ -60,7 +64,6 @@
 
         SaltConfig.SaltMode mode = getConfig(SaltConfig.SALT_MODE);
         LOG.debug("Initialize SaltStack {} mode", mode.name());
-        new SaltLifecycleEffectorTasks().attachLifecycleEffectors(this);
     }
 
     @Override
@@ -70,8 +73,10 @@
 
     @Override
     public String saltCall(String spec) {
-        final ProcessTaskWrapper<Integer> command = DynamicTasks.queue(SaltSshTasks.saltCall(spec));
+        final ProcessTaskWrapper<Integer> command = getDriver().saltCall(spec);
+
         command.asTask().blockUntilEnded();
+
         if (0 == command.getExitCode()) {
             return command.getStdout();
         } else {
diff --git a/software/cm/salt/src/main/java/org/apache/brooklyn/entity/cm/salt/impl/SaltLifecycleEffectorTasks.java b/software/cm/salt/src/main/java/org/apache/brooklyn/entity/cm/salt/SaltEntitySshDriver.java
similarity index 68%
rename from software/cm/salt/src/main/java/org/apache/brooklyn/entity/cm/salt/impl/SaltLifecycleEffectorTasks.java
rename to software/cm/salt/src/main/java/org/apache/brooklyn/entity/cm/salt/SaltEntitySshDriver.java
index 2051ed6..dac9756 100644
--- a/software/cm/salt/src/main/java/org/apache/brooklyn/entity/cm/salt/impl/SaltLifecycleEffectorTasks.java
+++ b/software/cm/salt/src/main/java/org/apache/brooklyn/entity/cm/salt/SaltEntitySshDriver.java
@@ -7,7 +7,7 @@
  * "License"); you may not use this file except in compliance
  * with the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing,
  * software distributed under the License is distributed on an
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.brooklyn.entity.cm.salt.impl;
+package org.apache.brooklyn.entity.cm.salt;
 
 import static java.util.regex.Pattern.DOTALL;
 import static java.util.regex.Pattern.MULTILINE;
@@ -28,8 +28,6 @@
 import java.util.regex.Pattern;
 
 import org.apache.brooklyn.api.effector.Effector;
-import org.apache.brooklyn.api.entity.Entity;
-import org.apache.brooklyn.api.location.MachineLocation;
 import org.apache.brooklyn.api.mgmt.TaskAdaptable;
 import org.apache.brooklyn.camp.brooklyn.BrooklynCampConstants;
 import org.apache.brooklyn.core.effector.Effectors;
@@ -37,10 +35,9 @@
 import org.apache.brooklyn.core.entity.lifecycle.Lifecycle;
 import org.apache.brooklyn.core.entity.lifecycle.ServiceStateLogic;
 import org.apache.brooklyn.core.entity.trait.Startable;
-import org.apache.brooklyn.entity.cm.salt.SaltConfig;
+import org.apache.brooklyn.entity.software.base.AbstractSoftwareProcessSshDriver;
 import org.apache.brooklyn.entity.software.base.SoftwareProcess;
-import org.apache.brooklyn.entity.software.base.SoftwareProcess.StopSoftwareParameters;
-import org.apache.brooklyn.entity.software.base.lifecycle.MachineLifecycleEffectorTasks;
+import org.apache.brooklyn.location.ssh.SshMachineLocation;
 import org.apache.brooklyn.util.collections.MutableSet;
 import org.apache.brooklyn.util.core.config.ConfigBag;
 import org.apache.brooklyn.util.core.task.DynamicTasks;
@@ -51,43 +48,35 @@
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import com.google.common.annotations.Beta;
 import com.google.common.base.Preconditions;
-import com.google.common.base.Supplier;
 import com.google.common.collect.ImmutableMap;
 
-@Beta
-public class SaltLifecycleEffectorTasks extends MachineLifecycleEffectorTasks implements SaltConfig {
-    private static final Logger LOG = LoggerFactory.getLogger(SaltLifecycleEffectorTasks.class);
+// TODO: does this belong to the _.impl package?
+public class SaltEntitySshDriver extends AbstractSoftwareProcessSshDriver implements SaltEntityDriver {
+    private static final Logger LOG = LoggerFactory.getLogger(SaltEntitySshDriver.class);
+    private static final Pattern FAILURES = Pattern.compile(".*^Failed:\\s+(\\d+)$.*", MULTILINE | DOTALL);
+    private static final String ZERO = "0";
+
+    public SaltEntitySshDriver(SaltEntityImpl entity, SshMachineLocation machine) {
+        super(entity, machine);
+    }
 
     @Override
-    protected String startProcessesAtMachine(Supplier<MachineLocation> machineS) {
-        SaltMode mode = detectSaltMode(entity());
-        final MachineLocation machine = machineS.get();
-        LOG.info("Starting salt in '{}' mode at '{}'", mode, machine.getDisplayName());
-        if (mode == SaltMode.MASTERLESS) {
-            startWithSshAsync();
-        } else {
+    public void install() {
+        SaltConfig.SaltMode mode = getEntity().config().get(SaltConfig.SALT_MODE);
+        Preconditions.checkNotNull(mode, "Required config " + SaltConfig.SALT_MODE + " not provided for entity: " + entity);
+        LOG.info("Starting salt in '{}' mode at '{}'", mode, getMachine().getDisplayName());
+
+        if (mode != SaltConfig.SaltMode.MASTERLESS) {
             // TODO: implement MASTER and MINION
             throw new IllegalStateException("Unknown salt mode: " + mode.name());
         }
-        return "salt tasks submitted (" + mode + ")";
-    }
 
-
-    protected static SaltMode detectSaltMode(Entity entity) {
-        SaltMode mode = entity.getConfig(SaltConfig.SALT_MODE);
-        Preconditions.checkNotNull(mode, "Required config " + SaltConfig.SALT_MODE + " not provided for entity: " + entity);
-        return mode;
-    }
-
-    protected void startWithSshAsync() {
-
-        final Set<? extends String> startStates = entity().getConfig(SaltConfig.START_STATES);
-        final Set<? extends String> formulas = entity().getConfig(SaltConfig.SALT_FORMULAS);
-        final Set<? extends String> pillars = entity().getConfig(SaltConfig.SALT_PILLARS);
-        final Set<? extends String> pillarUrls = entity().getConfig(SaltConfig.SALT_PILLAR_URLS);
-        final String entityId = entity().getConfig(BrooklynCampConstants.PLAN_ID);
+        final Set<? extends String> startStates = getEntity().config().get(SaltConfig.START_STATES);
+        final Set<? extends String> formulas = getEntity().config().get(SaltConfig.SALT_FORMULAS);
+        final Set<? extends String> pillars = getEntity().config().get(SaltConfig.SALT_PILLARS);
+        final Set<? extends String> pillarUrls = getEntity().config().get(SaltConfig.SALT_PILLAR_URLS);
+        final String entityId = getEntity().config().get(BrooklynCampConstants.PLAN_ID);
 
         final ProcessTaskWrapper<Integer> installedAlready = queueAndBlock(SaltSshTasks.isSaltInstalled(false));
 
@@ -96,10 +85,10 @@
                 @Override
                 public void run() {
                     DynamicTasks.queue(
-                        SaltSshTasks.installSalt(false),
-                        SaltSshTasks.installSaltUtilities(false),
-                        SaltSshTasks.configureForMasterlessOperation(false),
-                        SaltSshTasks.installTopFile(startStates, false));
+                            SaltSshTasks.installSalt(false),
+                            SaltSshTasks.installSaltUtilities(false),
+                            SaltSshTasks.configureForMasterlessOperation(false),
+                            SaltSshTasks.installTopFile(startStates, false));
 
                     if (Strings.isNonBlank(entityId)) {
                         DynamicTasks.queue(SaltSshTasks.setMinionId(entityId));
@@ -109,18 +98,17 @@
                 }
             });
         }
-
-        startSalt();
-
-        connectSensors();
     }
 
+    @Override
+    public void customize() {
+        newScript(CUSTOMIZING).execute();
+    }
 
-    private static final Pattern FAILURES = Pattern.compile(".*^Failed:\\s+(\\d+)$.*", MULTILINE | DOTALL);
-    private static final String ZERO = "0";
-
-    private void startSalt() {
+    @Override
+    public void launch() {
         String name = "apply top states";
+
         final ProcessTaskWrapper<Integer> topStates = queueAndBlock(SaltSshTasks.applyTopStates(false).summary(name));
 
         // Salt apply returns exit code 0 even upon failure so check the stdout.
@@ -128,10 +116,70 @@
         if (!failCount.matches() || !ZERO.equals(failCount.group(1))) {
             LOG.warn("Encountered error in applying Salt top states: {}", topStates.getStdout());
             throw new RuntimeException(
-                "Encountered error in applying Salt top states, see '" + name + "' in activities for details");
+                    "Encountered error in applying Salt top states, see '" + name + "' in activities for details");
         }
     }
 
+    @Override
+    public void runPostLaunchCommand() {
+        super.runPostLaunchCommand();
+
+        final ProcessTaskWrapper<String> retrieveHighstate = SaltSshTasks.retrieveHighstate();
+        final ProcessTaskWrapper<String> highstate = DynamicTasks.queue(retrieveHighstate).block();
+        String stateDescription = highstate.get();
+
+        SaltHighstate.applyHighstate(stateDescription, getEntity());
+
+        getEntity().sensors().set(SoftwareProcess.SERVICE_UP, true);
+    }
+
+    @Override
+    public boolean isRunning() {
+        return true;
+    }
+
+    @Override
+    public void stop() {
+        final Set<? extends String> stopStates = getEntity().config().get(SaltConfig.STOP_STATES);
+        LOG.debug("Executing Salt stopProcessesAtMachine with states {}", stopStates);
+        if (stopStates.isEmpty()) {
+            stopBasedOnStartStates();
+        } else {
+            applyStates(stopStates);
+        }
+    }
+
+    @Override
+    public void restart() {
+        ServiceStateLogic.setExpectedState(getEntity(), Lifecycle.STOPPING);
+
+        try {
+            final Set<? extends String> restartStates = getEntity().config().get(SaltConfig.RESTART_STATES);
+            LOG.debug("Executing Salt restart with states {}", restartStates);
+            if (restartStates.isEmpty()) {
+                restartBasedOnStartStates();
+            } else {
+                applyStates(restartStates);
+            }
+            ServiceStateLogic.setExpectedState(getEntity(), Lifecycle.RUNNING);
+        } catch (Exception e) {
+            getEntity().sensors().set(ServiceStateLogic.SERVICE_NOT_UP_DIAGNOSTICS,
+                    ImmutableMap.<String, Object>of("restart", e.getMessage()));
+            ServiceStateLogic.setExpectedState(getEntity(), Lifecycle.ON_FIRE);
+        }
+    }
+
+    @Override
+    public ProcessTaskWrapper<Integer> saltCall(String spec) {
+        return DynamicTasks.queue(SaltSshTasks.saltCall(spec));
+    }
+
+    private ProcessTaskWrapper<Integer> queueAndBlock(ProcessTaskFactory<Integer> taskFactory) {
+        final ProcessTaskWrapper<Integer> queued = DynamicTasks.queue(taskFactory);
+        queued.asTask().blockUntilEnded();
+        return queued;
+    }
+
     private void installFormulas(Set<? extends String> formulas) {
         if (formulas.size() > 0) {
             DynamicTasks.queue(SaltSshTasks.enableFileRoots(false));
@@ -148,7 +196,7 @@
         if (pillarUrls.size() > 0) {
             final TaskBuilder<Object> pillarTasks = TaskBuilder.builder().displayName("install pillars");
             pillarTasks.add(SaltSshTasks.invokeSaltUtility("init_pillar_config", null, false)
-                .summary("init pillar config").newTask());
+                    .summary("init pillar config").newTask());
             for (String pillar : pillars) {
                 pillarTasks.add(SaltSshTasks.addPillarToTop(pillar, false).newTask());
             }
@@ -159,32 +207,12 @@
         }
     }
 
-    private void connectSensors() {
-        final ProcessTaskWrapper<String> retrieveHighstate = SaltSshTasks.retrieveHighstate();
-        final ProcessTaskWrapper<String> highstate = DynamicTasks.queue(retrieveHighstate).block();
-        String stateDescription = highstate.get();
-
-        SaltHighstate.applyHighstate(stateDescription, entity());
-    }
-
-    @Override
-    protected void postStartCustom() {
-        // TODO: check for package installed?
-        entity().sensors().set(SoftwareProcess.SERVICE_UP, true);
-        super.postStartCustom();
-    }
-
-
-    @Override
-    protected String stopProcessesAtMachine() {
-        final Set<? extends String> stopStates = entity().getConfig(SaltConfig.STOP_STATES);
-        LOG.debug("Executing Salt stopProcessesAtMachine with states {}", stopStates);
-        if (stopStates.isEmpty()) {
-            stopBasedOnStartStates();
-        } else {
-            applyStates(stopStates);
+    private MutableSet<String> addSuffix(Set<? extends String> names, String suffix) {
+        final MutableSet<String> suffixed = MutableSet.of();
+        for (String name : names) {
+            suffixed.add(name + suffix);
         }
-        return null;
+        return suffixed;
     }
 
     private void applyStates(Set<? extends String> states) {
@@ -194,10 +222,10 @@
     }
 
     private void stopBasedOnStartStates() {
-        final Set<? extends String> startStates = entity().getConfig(SaltConfig.START_STATES);
+        final Set<? extends String> startStates = getEntity().config().get(SaltConfig.START_STATES);
         final MutableSet<String> stopStates = addSuffix(startStates, ".stop");
         final ProcessTaskWrapper<Integer> checkStops =
-            queueAndBlock(SaltSshTasks.verifyStates(stopStates, false).summary("check stop states"));
+                queueAndBlock(SaltSshTasks.verifyStates(stopStates, false).summary("check stop states"));
         if (0 != checkStops.getExitCode()) {
             throw new RuntimeException("No stop_states configured and not all start_states have matching stop states");
         } else {
@@ -205,31 +233,11 @@
         }
     }
 
-    @Override
-    public void restart(ConfigBag parameters) {
-        ServiceStateLogic.setExpectedState(entity(), Lifecycle.STOPPING);
-
-        try {
-            final Set<? extends String> restartStates = entity().getConfig(SaltConfig.RESTART_STATES);
-            LOG.debug("Executing Salt restart with states {}", restartStates);
-            if (restartStates.isEmpty()) {
-                restartBasedOnStartStates();
-            } else {
-                applyStates(restartStates);
-            }
-            ServiceStateLogic.setExpectedState(entity(), Lifecycle.RUNNING);
-        } catch (Exception e) {
-            entity().sensors().set(ServiceStateLogic.SERVICE_NOT_UP_DIAGNOSTICS,
-                ImmutableMap.<String, Object>of("restart", e.getMessage()));
-            ServiceStateLogic.setExpectedState(entity(), Lifecycle.ON_FIRE);
-        }
-    }
-
     private void restartBasedOnStartStates() {
-        final Set<? extends String> startStates = entity().getConfig(SaltConfig.START_STATES);
+        final Set<? extends String> startStates = getEntity().config().get(SaltConfig.START_STATES);
         final MutableSet<String> restartStates = addSuffix(startStates, ".restart");
         final ProcessTaskWrapper<Integer> queued =
-            queueAndBlock(SaltSshTasks.findStates(restartStates, false).summary("check restart states"));
+                queueAndBlock(SaltSshTasks.findStates(restartStates, false).summary("check restart states"));
         final String stdout = queued.getStdout();
         String[] foundStates = Strings.isNonBlank(stdout) ? stdout.split("\\n") : null;
 
@@ -248,28 +256,14 @@
             // (and in that effector we'd fail if stop was not well-defined)
             LOG.debug("No stop states available, invoking stop and start effectors");
             invokeEffector(Startable.STOP, ConfigBag.newInstance()
-                .configure(StopSoftwareParameters.STOP_PROCESS_MODE, ALWAYS)
-                .configure(StopSoftwareParameters.STOP_MACHINE_MODE, NEVER));
+                    .configure(SoftwareProcess.StopSoftwareParameters.STOP_PROCESS_MODE, ALWAYS)
+                    .configure(SoftwareProcess.StopSoftwareParameters.STOP_MACHINE_MODE, NEVER));
             invokeEffector(Startable.START, ConfigBag.EMPTY);
         }
     }
 
-    private ProcessTaskWrapper<Integer> queueAndBlock(ProcessTaskFactory<Integer> taskFactory) {
-        final ProcessTaskWrapper<Integer> queued = DynamicTasks.queue(taskFactory);
-        queued.asTask().blockUntilEnded();
-        return queued;
-    }
-
     private void invokeEffector(Effector<Void> effector, ConfigBag config) {
-        final TaskAdaptable<Void> stop = Entities.submit(entity(), Effectors.invocation(entity(), effector, config));
+        final TaskAdaptable<Void> stop = Entities.submit(getEntity(), Effectors.invocation(getEntity(), effector, config));
         stop.asTask().blockUntilEnded();
     }
-
-    private MutableSet<String> addSuffix(Set<? extends String> names, String suffix) {
-        final MutableSet<String> suffixed = MutableSet.of();
-        for (String name : names) {
-            suffixed.add(name + suffix);
-        }
-        return suffixed;
-    }
 }
diff --git a/software/cm/salt/src/main/java/org/apache/brooklyn/entity/cm/salt/impl/SaltHighstate.java b/software/cm/salt/src/main/java/org/apache/brooklyn/entity/cm/salt/SaltHighstate.java
similarity index 97%
rename from software/cm/salt/src/main/java/org/apache/brooklyn/entity/cm/salt/impl/SaltHighstate.java
rename to software/cm/salt/src/main/java/org/apache/brooklyn/entity/cm/salt/SaltHighstate.java
index fdae93b..16a4224 100644
--- a/software/cm/salt/src/main/java/org/apache/brooklyn/entity/cm/salt/impl/SaltHighstate.java
+++ b/software/cm/salt/src/main/java/org/apache/brooklyn/entity/cm/salt/SaltHighstate.java
@@ -7,7 +7,7 @@
  * "License"); you may not use this file except in compliance
  * with the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing,
  * software distributed under the License is distributed on an
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.brooklyn.entity.cm.salt.impl;
+package org.apache.brooklyn.entity.cm.salt;
 
 import com.google.common.reflect.TypeToken;
 
diff --git a/software/cm/salt/src/main/java/org/apache/brooklyn/entity/cm/salt/impl/SaltSshTasks.java b/software/cm/salt/src/main/java/org/apache/brooklyn/entity/cm/salt/SaltSshTasks.java
similarity index 98%
rename from software/cm/salt/src/main/java/org/apache/brooklyn/entity/cm/salt/impl/SaltSshTasks.java
rename to software/cm/salt/src/main/java/org/apache/brooklyn/entity/cm/salt/SaltSshTasks.java
index a8e1af6..03daf8e 100644
--- a/software/cm/salt/src/main/java/org/apache/brooklyn/entity/cm/salt/impl/SaltSshTasks.java
+++ b/software/cm/salt/src/main/java/org/apache/brooklyn/entity/cm/salt/SaltSshTasks.java
@@ -7,7 +7,7 @@
  * "License"); you may not use this file except in compliance
  * with the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing,
  * software distributed under the License is distributed on an
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.brooklyn.entity.cm.salt.impl;
+package org.apache.brooklyn.entity.cm.salt;
 
 import org.apache.brooklyn.api.mgmt.TaskAdaptable;
 import org.apache.brooklyn.api.mgmt.TaskFactory;
diff --git a/software/cm/salt/src/main/java/org/apache/brooklyn/entity/cm/salt/impl/SaltUtils.java b/software/cm/salt/src/main/java/org/apache/brooklyn/entity/cm/salt/SaltUtils.java
similarity index 93%
rename from software/cm/salt/src/main/java/org/apache/brooklyn/entity/cm/salt/impl/SaltUtils.java
rename to software/cm/salt/src/main/java/org/apache/brooklyn/entity/cm/salt/SaltUtils.java
index b11c06e..fc18a86 100644
--- a/software/cm/salt/src/main/java/org/apache/brooklyn/entity/cm/salt/impl/SaltUtils.java
+++ b/software/cm/salt/src/main/java/org/apache/brooklyn/entity/cm/salt/SaltUtils.java
@@ -7,7 +7,7 @@
  * "License"); you may not use this file except in compliance
  * with the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing,
  * software distributed under the License is distributed on an
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.brooklyn.entity.cm.salt.impl;
+package org.apache.brooklyn.entity.cm.salt;
 
 import org.apache.brooklyn.api.location.LocationDefinition;
 import org.apache.brooklyn.api.mgmt.ManagementContext;
diff --git a/software/cm/salt/src/main/java/org/apache/brooklyn/entity/cm/salt/impl/SaltEntitySshDriver.java b/software/cm/salt/src/main/java/org/apache/brooklyn/entity/cm/salt/impl/SaltEntitySshDriver.java
deleted file mode 100644
index 7531c27..0000000
--- a/software/cm/salt/src/main/java/org/apache/brooklyn/entity/cm/salt/impl/SaltEntitySshDriver.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.brooklyn.entity.cm.salt.impl;
-
-import org.apache.brooklyn.entity.cm.salt.SaltEntityDriver;
-import org.apache.brooklyn.entity.software.base.AbstractSoftwareProcessSshDriver;
-import org.apache.brooklyn.location.ssh.SshMachineLocation;
-
-// TODO: does this belong to the _.impl package?
-public class SaltEntitySshDriver extends AbstractSoftwareProcessSshDriver implements SaltEntityDriver {
-
-    public SaltEntitySshDriver(SaltEntityImpl entity, SshMachineLocation machine) {
-        super(entity, machine);
-    }
-
-    @Override
-    public SaltEntityImpl getEntity() {
-        return (SaltEntityImpl) super.getEntity();
-    }
-
-    @Override
-    public void install() {
-    }
-
-    @Override
-    public void customize() {
-    }
-
-    @Override
-    public void launch() {
-    }
-
-    @Override
-    public boolean isRunning() {
-        return true;
-    }
-
-    @Override
-    public void stop() {
-    }
-
-}
diff --git a/software/cm/salt/src/main/java/org/apache/brooklyn/entity/cm/salt/impl/SaltSshDriver.java b/software/cm/salt/src/main/java/org/apache/brooklyn/entity/cm/salt/impl/SaltSshDriver.java
deleted file mode 100644
index cd9cb38..0000000
--- a/software/cm/salt/src/main/java/org/apache/brooklyn/entity/cm/salt/impl/SaltSshDriver.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.brooklyn.entity.cm.salt.impl;
-
-
-public class SaltSshDriver {
-
-    private SaltSshDriver() {
-        // Utility class
-    }
-
-}
diff --git a/software/cm/salt/src/test/java/org/apache/brooklyn/entity/cm/salt/HighstateTest.java b/software/cm/salt/src/test/java/org/apache/brooklyn/entity/cm/salt/HighstateTest.java
index 50205e0..e5d130a 100644
--- a/software/cm/salt/src/test/java/org/apache/brooklyn/entity/cm/salt/HighstateTest.java
+++ b/software/cm/salt/src/test/java/org/apache/brooklyn/entity/cm/salt/HighstateTest.java
@@ -20,7 +20,6 @@
 
 import com.google.common.collect.ImmutableSet;
 import org.apache.brooklyn.api.entity.EntitySpec;
-import org.apache.brooklyn.entity.cm.salt.impl.SaltHighstate;
 import org.apache.brooklyn.core.entity.Entities;
 import org.apache.brooklyn.core.sensor.Sensors;
 import org.apache.brooklyn.core.test.entity.TestApplication;