http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/64c2b2e5/software/base/src/main/java/brooklyn/entity/basic/SoftwareProcessDriver.java
----------------------------------------------------------------------
diff --git 
a/software/base/src/main/java/brooklyn/entity/basic/SoftwareProcessDriver.java 
b/software/base/src/main/java/brooklyn/entity/basic/SoftwareProcessDriver.java
deleted file mode 100644
index bd3d8b3..0000000
--- 
a/software/base/src/main/java/brooklyn/entity/basic/SoftwareProcessDriver.java
+++ /dev/null
@@ -1,75 +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 brooklyn.entity.basic;
-
-import org.apache.brooklyn.api.entity.drivers.EntityDriver;
-import org.apache.brooklyn.api.internal.EntityLocal;
-import org.apache.brooklyn.entity.trait.Startable;
-
-/**
- * The {@link EntityDriver} for a {@link SoftwareProcess}.
- *
- * <p/>
- * In many cases it is cleaner to store entity lifecycle effectors (and 
sometimes other implementations) in a class to
- * which the entity delegates.  Classes implementing this interface provide 
this delegate, often inheriting utilities
- * specific to a particular transport (e.g. ssh) shared among many different 
entities.
- * <p/>
- * In this way, it is also possible for entities to cleanly support multiple 
mechanisms for start/stop and other methods.
- */
-public interface SoftwareProcessDriver extends EntityDriver {
-
-    /**
-     * The entity whose components we are controlling.
-     */
-    EntityLocal getEntity();
-
-    /**
-     * Whether the entity components have started.
-     */
-    boolean isRunning();
-
-    /**
-     * Rebinds the driver to a pre-existing software process.
-     */
-    void rebind();
-
-    /**
-     * Performs software start (or queues tasks to do this)
-     */
-    void start();
-
-    /**
-     * Performs software restart (or queues tasks to do this).
-     * Unlike stop/start implementations here are expected to update 
SERVICE_STATE for STOPPING and STARTING
-     * as appropriate (but framework will set RUNNING afterwards, after 
detecting it is running).
-     * @see Startable#restart()
-     */
-    void restart();
-
-    /**
-     * Performs software stop (or queues tasks to do this) 
-     * @see Startable#stop()
-     */
-    void stop();
-
-    /**
-     * Kills the process, ungracefully and immediately where possible (e.g. 
with `kill -9`).
-     */
-    void kill();
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/64c2b2e5/software/base/src/main/java/brooklyn/entity/basic/SoftwareProcessDriverLifecycleEffectorTasks.java
----------------------------------------------------------------------
diff --git 
a/software/base/src/main/java/brooklyn/entity/basic/SoftwareProcessDriverLifecycleEffectorTasks.java
 
b/software/base/src/main/java/brooklyn/entity/basic/SoftwareProcessDriverLifecycleEffectorTasks.java
deleted file mode 100644
index 5ce7667..0000000
--- 
a/software/base/src/main/java/brooklyn/entity/basic/SoftwareProcessDriverLifecycleEffectorTasks.java
+++ /dev/null
@@ -1,262 +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 brooklyn.entity.basic;
-
-import java.util.Map;
-
-import org.apache.brooklyn.api.location.MachineLocation;
-import org.apache.brooklyn.api.location.MachineProvisioningLocation;
-import org.apache.brooklyn.api.mgmt.TaskAdaptable;
-import org.apache.brooklyn.entity.core.Attributes;
-import org.apache.brooklyn.entity.core.Entities;
-import org.apache.brooklyn.entity.lifecycle.Lifecycle;
-import org.apache.brooklyn.entity.lifecycle.ServiceStateLogic;
-import org.apache.brooklyn.entity.trait.StartableMethods;
-import org.apache.brooklyn.util.core.config.ConfigBag;
-import org.apache.brooklyn.util.core.task.DynamicTasks;
-import org.apache.brooklyn.util.text.Strings;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import brooklyn.entity.basic.SoftwareProcess.ChildStartableMode;
-import brooklyn.entity.basic.SoftwareProcess.RestartSoftwareParameters;
-import 
brooklyn.entity.basic.SoftwareProcess.RestartSoftwareParameters.RestartMachineMode;
-import brooklyn.entity.software.MachineLifecycleEffectorTasks;
-
-import com.google.common.annotations.Beta;
-import com.google.common.base.Supplier;
-
-/** Thin shim delegating to driver to do start/stop/restart, wrapping as tasks,
- * with common code pulled up to {@link MachineLifecycleEffectorTasks} for 
non-driver usage 
- * @since 0.6.0 */
-@Beta
-public class SoftwareProcessDriverLifecycleEffectorTasks extends 
MachineLifecycleEffectorTasks {
-    
-    private static final Logger log = 
LoggerFactory.getLogger(SoftwareProcessDriverLifecycleEffectorTasks.class);
-    
-    public void restart(ConfigBag parameters) {
-        RestartMachineMode isRestartMachine = 
parameters.get(RestartSoftwareParameters.RESTART_MACHINE_TYPED);
-        if (isRestartMachine==null) 
-            isRestartMachine=RestartMachineMode.AUTO;
-        if (isRestartMachine==RestartMachineMode.AUTO) 
-            isRestartMachine = getDefaultRestartStopsMachine() ? 
RestartMachineMode.TRUE : RestartMachineMode.FALSE; 
-
-        if (isRestartMachine==RestartMachineMode.TRUE) {
-            log.debug("restart of "+entity()+" requested be applied at machine 
level");
-            super.restart(parameters);
-            return;
-        }
-        
-        DynamicTasks.queue("pre-restart", new PreRestartTask());
-
-        log.debug("restart of "+entity()+" appears to have driver and hostname 
- doing driver-level restart");
-        entity().getDriver().restart();
-        
-        restartChildren(parameters);
-        
-        DynamicTasks.queue("post-restart", new PostRestartTask());
-    }
-
-    private class PreRestartTask implements Runnable {
-        @Override
-        public void run() {
-            preRestartCustom();
-        }
-    }
-
-    private class PostRestartTask implements Runnable {
-        @Override
-        public void run() {
-            postStartCustom();
-            postRestartCustom();
-            ServiceStateLogic.setExpectedState(entity(), Lifecycle.RUNNING);
-        }
-    }
-    
-    @Override
-    protected boolean getDefaultRestartStopsMachine() {
-        if (entity().getDriver() == null) {
-            log.debug("restart of "+entity()+" has no driver - doing 
machine-level restart");
-            return true;
-        }
-
-        if (Strings.isEmpty(entity().getAttribute(Attributes.HOSTNAME))) {
-            log.debug("restart of "+entity()+" has no hostname - doing 
machine-level restart");
-            return true;
-        }
-        
-        return false;
-    }
-    
-    @Override
-    protected SoftwareProcessImpl entity() {
-        return (SoftwareProcessImpl) super.entity();
-    }
-    
-    @Override
-    protected Map<String, Object> obtainProvisioningFlags(final 
MachineProvisioningLocation<?> location) {
-        return entity().obtainProvisioningFlags(location);
-    }
-     
-    @Override
-    protected void preStartCustom(MachineLocation machine) {
-        entity().initDriver(machine);
-
-        // Note: must only apply config-sensors after adding to locations and 
creating driver; 
-        // otherwise can't do things like acquire free port from location, or 
allowing driver to set up ports
-        super.preStartCustom(machine);
-        
-        entity().preStart();
-    }
-
-    /** returns how children startables should be handled (reporting none for 
efficiency if there are no children) */
-    protected ChildStartableMode getChildrenStartableModeEffective() {
-        if (entity().getChildren().isEmpty()) return ChildStartableMode.NONE;
-        ChildStartableMode result = 
entity().getConfig(SoftwareProcess.CHILDREN_STARTABLE_MODE);
-        if (result!=null) return result;
-        return ChildStartableMode.NONE;
-    }
-
-    @Override
-    protected String startProcessesAtMachine(final Supplier<MachineLocation> 
machineS) {
-        ChildStartableMode mode = getChildrenStartableModeEffective();
-        TaskAdaptable<?> children = null;
-        if (!mode.isDisabled) {
-            children = StartableMethods.startingChildren(entity(), 
machineS.get());
-            // submit rather than queue so it runs in parallel
-            // (could also wrap as parallel task with driver.start() -
-            // but only benefit is that child starts show as child task,
-            // rather than bg task, so not worth the code complexity)
-            if (!mode.isLate) Entities.submit(entity(), children);
-        }
-        
-        entity().getDriver().start();
-        String result = "Started with driver "+entity().getDriver();
-        
-        if (!mode.isDisabled) {
-            if (mode.isLate) {
-                DynamicTasks.waitForLast();
-                if (mode.isBackground) {
-                    Entities.submit(entity(), children);
-                } else {
-                    // when running foreground late, there is no harm here in 
queueing
-                    DynamicTasks.queue(children);
-                }
-            }
-            if (!mode.isBackground) children.asTask().getUnchecked();
-            result += "; children started "+mode;
-        }
-        return result;
-    }
-
-    @Override
-    protected void postStartCustom() {
-        entity().postDriverStart();
-        if (entity().connectedSensors) {
-            // many impls aren't idempotent - though they should be!
-            log.debug("skipping connecting sensors for "+entity()+" in 
driver-tasks postStartCustom because already connected (e.g. restarting)");
-        } else {
-            log.debug("connecting sensors for "+entity()+" in driver-tasks 
postStartCustom because already connected (e.g. restarting)");
-            entity().connectSensors();
-        }
-        entity().waitForServiceUp();
-        entity().postStart();
-    }
-    
-    @Override
-    protected void preStopConfirmCustom() {
-        super.preStopConfirmCustom();
-        
-        entity().preStopConfirmCustom();
-    }
-    
-    @Override
-    protected void preStopCustom() {
-        super.preStopCustom();
-        
-        entity().preStop();
-    }
-
-    @Override
-    protected void preRestartCustom() {
-        super.preRestartCustom();
-        
-        entity().preRestart();
-    }
-
-    @Override
-    protected void postRestartCustom() {
-        super.postRestartCustom();
-        
-        entity().postRestart();
-    }
-
-    @Override
-    protected String stopProcessesAtMachine() {
-        String result;
-        
-        ChildStartableMode mode = getChildrenStartableModeEffective();
-        TaskAdaptable<?> children = null;
-        Exception childException = null;
-        
-        if (!mode.isDisabled) {
-            children = StartableMethods.stoppingChildren(entity());
-            
-            if (mode.isBackground || !mode.isLate) Entities.submit(entity(), 
children);
-            else {
-                DynamicTasks.queue(children);
-                try {
-                    DynamicTasks.waitForLast();
-                } catch (Exception e) {
-                    childException = e;
-                }
-            }
-        }
-        
-        if (entity().getDriver() != null) { 
-            entity().getDriver().stop();
-            result = "Driver stop completed";
-        } else {
-            result = "No driver (nothing to do here)";
-        }
-
-        if (!mode.isDisabled && !mode.isBackground) {
-            try {
-                children.asTask().get();
-            } catch (Exception e) {
-                childException = e;
-                log.debug("Error stopping children; continuing and will 
rethrow if no other errors", e);
-            }            
-        }
-        
-        if (childException!=null)
-            throw new IllegalStateException(result+"; but error stopping 
child: "+childException, childException);
-
-        return result;
-    }
-    
-    @Override
-    protected void postStopCustom() {
-        super.postStopCustom();
-        
-        entity().postStop();
-    }
-
-}
-

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/64c2b2e5/software/base/src/main/java/brooklyn/entity/basic/SoftwareProcessImpl.java
----------------------------------------------------------------------
diff --git 
a/software/base/src/main/java/brooklyn/entity/basic/SoftwareProcessImpl.java 
b/software/base/src/main/java/brooklyn/entity/basic/SoftwareProcessImpl.java
deleted file mode 100644
index bb9717e..0000000
--- a/software/base/src/main/java/brooklyn/entity/basic/SoftwareProcessImpl.java
+++ /dev/null
@@ -1,651 +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 brooklyn.entity.basic;
-
-import groovy.time.TimeDuration;
-
-import java.util.Collection;
-import java.util.Map;
-import java.util.Set;
-import java.util.Timer;
-import java.util.TimerTask;
-import java.util.concurrent.Callable;
-import java.util.concurrent.TimeUnit;
-
-import org.apache.brooklyn.api.entity.Entity;
-import org.apache.brooklyn.api.entity.drivers.DriverDependentEntity;
-import org.apache.brooklyn.api.entity.drivers.EntityDriverManager;
-import org.apache.brooklyn.api.internal.EntityLocal;
-import org.apache.brooklyn.api.location.Location;
-import org.apache.brooklyn.api.location.MachineLocation;
-import org.apache.brooklyn.api.location.MachineProvisioningLocation;
-import org.apache.brooklyn.api.location.PortRange;
-import org.apache.brooklyn.api.mgmt.Task;
-import org.apache.brooklyn.api.sensor.EnricherSpec;
-import org.apache.brooklyn.api.sensor.SensorEvent;
-import org.apache.brooklyn.api.sensor.SensorEventListener;
-import org.apache.brooklyn.config.ConfigKey;
-import org.apache.brooklyn.entity.core.AbstractEntity;
-import org.apache.brooklyn.entity.core.Attributes;
-import org.apache.brooklyn.entity.core.BrooklynConfigKeys;
-import org.apache.brooklyn.entity.core.Entities;
-import org.apache.brooklyn.entity.lifecycle.Lifecycle;
-import org.apache.brooklyn.entity.lifecycle.ServiceStateLogic;
-import org.apache.brooklyn.entity.lifecycle.Lifecycle.Transition;
-import 
org.apache.brooklyn.entity.lifecycle.ServiceStateLogic.ServiceNotUpLogic;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.apache.brooklyn.location.basic.LocationConfigKeys;
-import org.apache.brooklyn.location.basic.SshMachineLocation;
-import org.apache.brooklyn.location.cloud.CloudLocationConfig;
-import org.apache.brooklyn.sensor.enricher.AbstractEnricher;
-import org.apache.brooklyn.sensor.feed.function.FunctionFeed;
-import org.apache.brooklyn.sensor.feed.function.FunctionPollConfig;
-import org.apache.brooklyn.util.collections.MutableMap;
-import org.apache.brooklyn.util.collections.MutableSet;
-import org.apache.brooklyn.util.core.config.ConfigBag;
-import org.apache.brooklyn.util.core.flags.TypeCoercions;
-import org.apache.brooklyn.util.core.task.DynamicTasks;
-import org.apache.brooklyn.util.core.task.Tasks;
-import org.apache.brooklyn.util.exceptions.Exceptions;
-import org.apache.brooklyn.util.guava.Maybe;
-import org.apache.brooklyn.util.time.CountdownTimer;
-import org.apache.brooklyn.util.time.Duration;
-import org.apache.brooklyn.util.time.Time;
-
-import com.google.common.base.Functions;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.Iterables;
-import com.google.common.collect.Sets;
-import com.google.common.reflect.TypeToken;
-
-/**
- * An {@link Entity} representing a piece of software which can be installed, 
run, and controlled.
- * A single such entity can only run on a single {@link MachineLocation} at a 
time (you can have multiple on the machine). 
- * It typically takes config keys for suggested versions, filesystem locations 
to use, and environment variables to set.
- * <p>
- * It exposes sensors for service state (Lifecycle) and status (String), and 
for host info, log file location.
- */
-public abstract class SoftwareProcessImpl extends AbstractEntity implements 
SoftwareProcess, DriverDependentEntity {
-    private static final Logger log = 
LoggerFactory.getLogger(SoftwareProcessImpl.class);
-    
-    private transient SoftwareProcessDriver driver;
-
-    /** @see #connectServiceUpIsRunning() */
-    private volatile FunctionFeed serviceProcessIsRunning;
-
-    protected boolean connectedSensors = false;
-    
-    public SoftwareProcessImpl() {
-        super(MutableMap.of(), null);
-    }
-    public SoftwareProcessImpl(Entity parent) {
-        this(MutableMap.of(), parent);
-    }
-    public SoftwareProcessImpl(Map properties) {
-        this(properties, null);
-    }
-    public SoftwareProcessImpl(Map properties, Entity parent) {
-        super(properties, parent);
-    }
-
-    protected void setProvisioningLocation(MachineProvisioningLocation val) {
-        if (getAttribute(PROVISIONING_LOCATION) != null) throw new 
IllegalStateException("Cannot change provisioning location: 
existing="+getAttribute(PROVISIONING_LOCATION)+"; new="+val);
-        setAttribute(PROVISIONING_LOCATION, val);
-    }
-    
-    protected MachineProvisioningLocation getProvisioningLocation() {
-        return getAttribute(PROVISIONING_LOCATION);
-    }
-    
-    @Override
-    public SoftwareProcessDriver getDriver() {
-        return driver;
-    }
-
-    protected SoftwareProcessDriver newDriver(MachineLocation loc){
-        EntityDriverManager entityDriverManager = 
getManagementContext().getEntityDriverManager();
-        return (SoftwareProcessDriver)entityDriverManager.build(this, loc);
-    }
-
-    protected MachineLocation getMachineOrNull() {
-        return Iterables.get(Iterables.filter(getLocations(), 
MachineLocation.class), 0, null);
-    }
-
-    @Override
-    public void init() {
-        super.init();
-        getLifecycleEffectorTasks().attachLifecycleEffectors(this);
-    }
-    
-    @Override
-    protected void initEnrichers() {
-        super.initEnrichers();
-        ServiceNotUpLogic.updateNotUpIndicator(this, 
SERVICE_PROCESS_IS_RUNNING, "No information yet on whether this service is 
running");
-        // add an indicator above so that if is_running comes through, the map 
is cleared and an update is guaranteed
-        
addEnricher(EnricherSpec.create(UpdatingNotUpFromServiceProcessIsRunning.class).uniqueTag("service-process-is-running-updating-not-up"));
-        
addEnricher(EnricherSpec.create(ServiceNotUpDiagnosticsCollector.class).uniqueTag("service-not-up-diagnostics-collector"));
-    }
-    
-    /**
-     * @since 0.8.0
-     */
-    protected static class ServiceNotUpDiagnosticsCollector extends 
AbstractEnricher implements SensorEventListener<Object> {
-        public ServiceNotUpDiagnosticsCollector() {
-        }
-        
-        @Override
-        public void setEntity(EntityLocal entity) {
-            super.setEntity(entity);
-            if (!(entity instanceof SoftwareProcess)) {
-                throw new IllegalArgumentException("Expected SoftwareProcess, 
but got entity "+entity);
-            }
-            subscribe(entity, Attributes.SERVICE_UP, this);
-            onUpdated();
-        }
-
-        @Override
-        public void onEvent(SensorEvent<Object> event) {
-            onUpdated();
-        }
-
-        protected void onUpdated() {
-            Boolean up = entity.getAttribute(SERVICE_UP);
-            if (up == null || up) {
-                
entity.setAttribute(ServiceStateLogic.SERVICE_NOT_UP_DIAGNOSTICS, 
ImmutableMap.<String, Object>of());
-            } else {
-                ((SoftwareProcess)entity).populateServiceNotUpDiagnostics();
-            }
-        }
-    }
-    
-    @Override
-    public void populateServiceNotUpDiagnostics() {
-        if (getDriver() == null) {
-            ServiceStateLogic.updateMapSensorEntry(this, 
ServiceStateLogic.SERVICE_NOT_UP_DIAGNOSTICS, "driver", "No driver");
-            return;
-        }
-
-        Location loc = getDriver().getLocation();
-        if (loc instanceof SshMachineLocation) {
-            if (!((SshMachineLocation)loc).isSshable()) {
-                ServiceStateLogic.updateMapSensorEntry(
-                        this, 
-                        ServiceStateLogic.SERVICE_NOT_UP_DIAGNOSTICS, 
-                        "sshable", 
-                        "The machine for this entity does not appear to be 
sshable");
-            }
-            return;
-        }
-
-        boolean processIsRunning = getDriver().isRunning();
-        if (!processIsRunning) {
-            ServiceStateLogic.updateMapSensorEntry(
-                    this, 
-                    ServiceStateLogic.SERVICE_NOT_UP_DIAGNOSTICS, 
-                    SERVICE_PROCESS_IS_RUNNING.getName(), 
-                    "The software process for this entity does not appear to 
be running");
-        }
-    }
-
-    /** subscribes to SERVICE_PROCESS_IS_RUNNING and SERVICE_UP; the latter 
has no effect if the former is set,
-     * but to support entities which set SERVICE_UP directly we want to make 
sure that the absence of 
-     * SERVICE_PROCESS_IS_RUNNING does not trigger any not-up indicators */
-    protected static class UpdatingNotUpFromServiceProcessIsRunning extends 
AbstractEnricher implements SensorEventListener<Object> {
-        public UpdatingNotUpFromServiceProcessIsRunning() {}
-        
-        @Override
-        public void setEntity(EntityLocal entity) {
-            super.setEntity(entity);
-            subscribe(entity, SERVICE_PROCESS_IS_RUNNING, this);
-            subscribe(entity, Attributes.SERVICE_UP, this);
-            onUpdated();
-        }
-
-        @Override
-        public void onEvent(SensorEvent<Object> event) {
-            onUpdated();
-        }
-
-        protected void onUpdated() {
-            Boolean isRunning = 
entity.getAttribute(SERVICE_PROCESS_IS_RUNNING);
-            if (Boolean.FALSE.equals(isRunning)) {
-                ServiceNotUpLogic.updateNotUpIndicator(entity, 
SERVICE_PROCESS_IS_RUNNING, "The software process for this entity does not 
appear to be running");
-                return;
-            }
-            if (Boolean.TRUE.equals(isRunning)) {
-                ServiceNotUpLogic.clearNotUpIndicator(entity, 
SERVICE_PROCESS_IS_RUNNING);
-                return;
-            }
-            // no info on "isRunning"
-            Boolean isUp = entity.getAttribute(Attributes.SERVICE_UP);
-            if (Boolean.TRUE.equals(isUp)) {
-                // if service explicitly set up, then don't apply our rule
-                ServiceNotUpLogic.clearNotUpIndicator(entity, 
SERVICE_PROCESS_IS_RUNNING);
-                return;
-            }
-            // service not up, or no info
-            ServiceNotUpLogic.updateNotUpIndicator(entity, 
SERVICE_PROCESS_IS_RUNNING, "No information on whether this service is 
running");
-        }
-    }
-    
-    /**
-     * Called before driver.start; guarantees the driver will exist, and 
locations will have been set.
-     */
-    protected void preStart() {
-    }
-    
-    /**
-     * Called after driver.start(). Default implementation is to wait to 
confirm the driver 
-     * definitely started the process.
-     */
-    protected void postDriverStart() {
-        waitForEntityStart();
-    }
-
-    /**
-     * For binding to the running app (e.g. connecting sensors to registry). 
Will be called
-     * on start() and on rebind().
-     * <p>
-     * Implementations should be idempotent (ie tell whether sensors already 
connected),
-     * though the framework is pretty good about not calling when already 
connected. 
-     * TODO improve the framework's feed system to detect duplicate additions
-     */
-    protected void connectSensors() {
-        connectedSensors = true;
-    }
-
-    /**
-     * For connecting the {@link #SERVICE_UP} sensor to the value of the 
{@code getDriver().isRunning()} expression.
-     * <p>
-     * Should be called inside {@link #connectSensors()}.
-     *
-     * @see #disconnectServiceUpIsRunning()
-     */
-    protected void connectServiceUpIsRunning() {
-        serviceProcessIsRunning = FunctionFeed.builder()
-                .entity(this)
-                .period(Duration.FIVE_SECONDS)
-                .poll(new FunctionPollConfig<Boolean, 
Boolean>(SERVICE_PROCESS_IS_RUNNING)
-                        .suppressDuplicates(true)
-                        .onException(Functions.constant(Boolean.FALSE))
-                        .callable(new Callable<Boolean>() {
-                            public Boolean call() {
-                                return getDriver().isRunning();
-                            }
-                        }))
-                .build();
-    }
-
-    /**
-     * For disconnecting the {@link #SERVICE_UP} feed.
-     * <p>
-     * Should be called from {@link #disconnectSensors()}.
-     *
-     * @see #connectServiceUpIsRunning()
-     */
-    protected void disconnectServiceUpIsRunning() {
-        if (serviceProcessIsRunning != null) serviceProcessIsRunning.stop();
-        // set null so the SERVICE_UP enricher runs (possibly removing it), 
then remove so everything is removed
-        // TODO race because the is-running check may be mid-task
-        setAttribute(SERVICE_PROCESS_IS_RUNNING, null);
-        removeAttribute(SERVICE_PROCESS_IS_RUNNING);
-    }
-
-    /**
-     * Called after the rest of start has completed (after {@link 
#connectSensors()} and {@link #waitForServiceUp()})
-     */
-    protected void postStart() {
-    }
-    
-    protected void preStopConfirmCustom() {
-    }
-    
-    protected void preStop() {
-        // note asymmetry that disconnectSensors is done in the entity not the 
driver
-        // whereas on start the *driver* calls connectSensors, before calling 
postStart,
-        // ie waiting for the entity truly to be started before calling 
postStart;
-        // TODO feels like that confusion could be eliminated with a single 
place for pre/post logic!)
-        log.debug("disconnecting sensors for "+this+" in entity.preStop");
-        disconnectSensors();
-        
-        // Must set the serviceProcessIsRunning explicitly to false - we've 
disconnected the sensors
-        // so nothing else will.
-        // Otherwise, if restarted, there will be no change to 
serviceProcessIsRunning, so the
-        // serviceUpIndicators will not change, so serviceUp will not be reset.
-        // TODO Is there a race where disconnectSensors could leave a task of 
the feeds still running
-        // which could set serviceProcessIsRunning to true again before the 
task completes and the feed
-        // is fully terminated?
-        setAttribute(SoftwareProcess.SERVICE_PROCESS_IS_RUNNING, false);
-    }
-
-    /**
-     * Called after the rest of stop has completed (after VM deprovisioned, 
but before state set to STOPPED)
-     */
-    protected void postStop() {
-    }
-
-    /**
-     * Called before driver.restart; guarantees the driver will exist, and 
locations will have been set.
-     */
-    protected void preRestart() {
-    }
-
-    protected void postRestart() {
-    }
-
-    /**
-     * For disconnecting from the running app. Will be called on stop.
-     */
-    protected void disconnectSensors() {
-        connectedSensors = false;
-    }
-
-    /**
-     * Called after this entity is fully rebound (i.e. it is fully managed).
-     */
-    protected void postRebind() {
-    }
-    
-    protected void callRebindHooks() {
-        Duration configuredMaxDelay = 
getConfig(MAXIMUM_REBIND_SENSOR_CONNECT_DELAY);
-        if (configuredMaxDelay == null || 
Duration.ZERO.equals(configuredMaxDelay)) {
-            connectSensors();
-        } else {
-            long delay = (long) (Math.random() * 
configuredMaxDelay.toMilliseconds());
-            log.debug("Scheduled reconnection of sensors on {} in {}ms", this, 
delay);
-            Timer timer = new Timer();
-            timer.schedule(new TimerTask() {
-                @Override public void run() {
-                    try {
-                        if (getManagementSupport().isNoLongerManaged()) {
-                            log.debug("Entity {} no longer managed; ignoring 
scheduled connect sensors on rebind", SoftwareProcessImpl.this);
-                            return;
-                        }
-                        connectSensors();
-                    } catch (Throwable e) {
-                        log.warn("Problem connecting sensors on rebind of 
"+SoftwareProcessImpl.this, e);
-                        Exceptions.propagateIfFatal(e);
-                    }
-                }
-            }, delay);
-        }
-        // don't wait here - it may be long-running, e.g. if remote entity has 
died, and we don't want to block rebind waiting or cause it to fail
-        // the service will subsequently show service not up and thus failure
-//        waitForServiceUp();
-    }
-
-    @Override 
-    public void onManagementStarting() {
-        super.onManagementStarting();
-        
-        Lifecycle state = getAttribute(SERVICE_STATE_ACTUAL);
-        if (state == null || state == Lifecycle.CREATED) {
-            // Expect this is a normal start() sequence (i.e. start() will 
subsequently be called)
-            setAttribute(SERVICE_UP, false);
-            ServiceStateLogic.setExpectedState(this, Lifecycle.CREATED);
-            // force actual to be created because this is expected subsequently
-            setAttribute(SERVICE_STATE_ACTUAL, Lifecycle.CREATED);
-        }
-    }
-    
-    @Override 
-    public void onManagementStarted() {
-        super.onManagementStarted();
-        
-        Lifecycle state = getAttribute(SERVICE_STATE_ACTUAL);
-        if (state != null && state != Lifecycle.CREATED) {
-            postRebind();
-        }
-    }
-    
-    @Override
-    public void rebind() {
-        //SERVICE_STATE_ACTUAL might be ON_FIRE due to a temporary condition 
(problems map non-empty)
-        //Only if the expected state is ON_FIRE then the entity has 
permanently failed.
-        Transition expectedState = getAttribute(SERVICE_STATE_EXPECTED);
-        if (expectedState == null || expectedState.getState() != 
Lifecycle.RUNNING) {
-            log.warn("On rebind of {}, not calling software process rebind 
hooks because expected state is {}", this, expectedState);
-            return;
-        }
-
-        Lifecycle actualState = getAttribute(SERVICE_STATE_ACTUAL);
-        if (actualState == null || actualState != Lifecycle.RUNNING) {
-            log.warn("Rebinding entity {}, even though actual state is {}. 
Expected state is {}", new Object[] {this, actualState, expectedState});
-        }
-
-        // e.g. rebinding to a running instance
-        // FIXME For rebind, what to do about things in STARTING or STOPPING 
state?
-        // FIXME What if location not set?
-        log.info("Rebind {} connecting to pre-running service", this);
-        
-        MachineLocation machine = getMachineOrNull();
-        if (machine != null) {
-            initDriver(machine);
-            driver.rebind();
-            if (log.isDebugEnabled()) log.debug("On rebind of {}, re-created 
driver {}", this, driver);
-        } else {
-            log.info("On rebind of {}, no MachineLocation found (with 
locations {}) so not generating driver",
-                    this, getLocations());
-        }
-        
-        callRebindHooks();
-    }
-    
-    public void waitForServiceUp() {
-        Duration timeout = getConfig(BrooklynConfigKeys.START_TIMEOUT);
-        waitForServiceUp(timeout);
-    }
-    public void waitForServiceUp(Duration duration) {
-        Entities.waitForServiceUp(this, duration);
-    }
-    public void waitForServiceUp(TimeDuration duration) {
-        waitForServiceUp(duration.toMilliseconds(), TimeUnit.MILLISECONDS);
-    }
-    public void waitForServiceUp(long duration, TimeUnit units) {
-        Entities.waitForServiceUp(this, Duration.of(duration, units));
-    }
-
-    protected Map<String,Object> 
obtainProvisioningFlags(MachineProvisioningLocation location) {
-        ConfigBag result = 
ConfigBag.newInstance(location.getProvisioningFlags(ImmutableList.of(getClass().getName())));
-        result.putAll(getConfig(PROVISIONING_PROPERTIES));
-        if (result.get(CloudLocationConfig.INBOUND_PORTS) == null) {
-            Collection<Integer> ports = getRequiredOpenPorts();
-            Object requiredPorts = 
result.get(CloudLocationConfig.ADDITIONAL_INBOUND_PORTS);
-            if (requiredPorts instanceof Integer) {
-                ports.add((Integer) requiredPorts);
-            } else if (requiredPorts instanceof Iterable) {
-                for (Object o : (Iterable<?>) requiredPorts) {
-                    if (o instanceof Integer) ports.add((Integer) o);
-                }
-            }
-            if (ports != null && ports.size() > 0) 
result.put(CloudLocationConfig.INBOUND_PORTS, ports);
-        }
-        result.put(LocationConfigKeys.CALLER_CONTEXT, this);
-        return result.getAllConfigMutable();
-    }
-
-    /** returns the ports that this entity wants to use;
-     * default implementation returns {@link 
SoftwareProcess#REQUIRED_OPEN_LOGIN_PORTS} plus first value 
-     * for each {@link 
org.apache.brooklyn.sensor.core.PortAttributeSensorAndConfigKey} config key 
{@link PortRange}
-     * plus any ports defined with a config keys ending in {@code .port}.
-     */
-    protected Collection<Integer> getRequiredOpenPorts() {
-        Set<Integer> ports = 
MutableSet.copyOf(getConfig(REQUIRED_OPEN_LOGIN_PORTS));
-        Map<ConfigKey<?>, ?> allConfig = 
config().getBag().getAllConfigAsConfigKeyMap();
-        Set<ConfigKey<?>> configKeys = Sets.newHashSet(allConfig.keySet());
-        configKeys.addAll(getEntityType().getConfigKeys());
-
-        /* TODO: This won't work if there's a port collision, which will cause 
the corresponding port attribute
-           to be incremented until a free port is found. In that case the 
entity will use the free port, but the
-           firewall will open the initial port instead. Mostly a problem for 
SameServerEntity, localhost location.
-         */
-        for (ConfigKey<?> k: configKeys) {
-            Object value;
-            if (PortRange.class.isAssignableFrom(k.getType()) || 
k.getName().matches(".*\\.port")) {
-                value = config().get(k);
-            } else {
-                // config().get() will cause this to block until all config 
has been resolved
-                // using config().getRaw(k) means that we won't be able to use 
e.g. 'http.port: $brooklyn:component("x").attributeWhenReady("foo")'
-                // but that's unlikely to be used
-                Maybe<Object> maybeValue = config().getRaw(k);
-                value = maybeValue.isPresent() ? maybeValue.get() : null;
-            }
-
-            Maybe<PortRange> maybePortRange = TypeCoercions.tryCoerce(value, 
new TypeToken<PortRange>() {});
-
-            if (maybePortRange.isPresentAndNonNull()) {
-                PortRange p = maybePortRange.get();
-                if (p != null && !p.isEmpty()) ports.add(p.iterator().next());
-            }
-        }        
-        
-        log.debug("getRequiredOpenPorts detected default {} for {}", ports, 
this);
-        return ports;
-    }
-
-    protected void initDriver(MachineLocation machine) {
-        SoftwareProcessDriver newDriver = doInitDriver(machine);
-        if (newDriver == null) {
-            throw new UnsupportedOperationException("cannot start "+this+" on 
"+machine+": no driver available");
-        }
-        driver = newDriver;
-    }
-
-    /**
-     * Creates the driver (if does not already exist or needs replaced for 
some reason). Returns either the existing driver
-     * or a new driver. Must not return null.
-     */
-    protected SoftwareProcessDriver doInitDriver(MachineLocation machine) {
-        if (driver!=null) {
-            if ((driver instanceof AbstractSoftwareProcessDriver) && 
machine.equals(((AbstractSoftwareProcessDriver)driver).getLocation())) {
-                return driver; //just reuse
-            } else {
-                log.warn("driver/location change is untested for {} at {}; 
changing driver and continuing", this, machine);
-                return newDriver(machine);
-            }
-        } else {
-            return newDriver(machine);
-        }
-    }
-    
-    // TODO Find a better way to detect early death of process.
-    public void waitForEntityStart() {
-        if (log.isDebugEnabled()) log.debug("waiting to ensure {} doesn't 
abort prematurely", this);
-        Duration startTimeout = getConfig(START_TIMEOUT);
-        CountdownTimer timer = startTimeout.countdownTimer();
-        boolean isRunningResult = false;
-        long delay = 100;
-        Exception firstFailure = null;
-        while (!isRunningResult && !timer.isExpired()) {
-            Time.sleep(delay);
-            try {
-                isRunningResult = driver.isRunning();
-                if (log.isDebugEnabled()) log.debug("checked {}, 'is running' 
returned: {}", this, isRunningResult);
-            } catch (Exception  e) {
-                Exceptions.propagateIfFatal(e);
-
-                isRunningResult = false;
-                if (driver != null) {
-                    String msg = "checked " + this + ", 'is running' threw an 
exception; logging subsequent exceptions at debug level";
-                    if (firstFailure == null) {
-                        log.error(msg, e);
-                    } else {
-                        log.debug(msg, e);
-                    }
-                } else {
-                    // provide extra context info, as we're seeing this happen 
in strange circumstances
-                    log.error(this+" concurrent start and shutdown detected", 
e);
-                }
-                if (firstFailure == null) {
-                    firstFailure = e;
-                }
-            }
-            // slow exponential delay -- 1.1^N means after 40 tries and 50s 
elapsed, it reaches the max of 5s intervals
-            // TODO use Repeater 
-            delay = Math.min(delay*11/10, 5000);
-        }
-        if (!isRunningResult) {
-            String msg = "Software process entity "+this+" did not pass 
is-running check within "+
-                    "the required "+startTimeout+" limit 
("+timer.getDurationElapsed().toStringRounded()+" elapsed)";
-            if (firstFailure != null) {
-                msg += "; check failed at least once with exception: " + 
firstFailure.getMessage() + ", see logs for details";
-            }
-            log.warn(msg+" (throwing)");
-            ServiceStateLogic.setExpectedState(this, Lifecycle.RUNNING);
-            throw new IllegalStateException(msg, firstFailure);
-        }
-    }
-
-    /**
-     * If custom behaviour is required by sub-classes, consider overriding 
{@link #preStart()} or {@link #postStart()})}.
-     * Also consider adding additional work via tasks, executed using {@link 
DynamicTasks#queue(String, Callable)}.
-     */
-    @Override
-    public final void start(final Collection<? extends Location> locations) {
-        if (DynamicTasks.getTaskQueuingContext() != null) {
-            getLifecycleEffectorTasks().start(locations);
-        } else {
-            Task<?> task = Tasks.builder().name("start (sequential)").body(new 
Runnable() { public void run() { getLifecycleEffectorTasks().start(locations); 
} }).build();
-            Entities.submit(this, task).getUnchecked();
-        }
-    }
-
-    /**
-     * If custom behaviour is required by sub-classes, consider overriding  
{@link #preStop()} or {@link #postStop()}.
-     * Also consider adding additional work via tasks, executed using {@link 
DynamicTasks#queue(String, Callable)}.
-     */
-    @Override
-    public final void stop() {
-        // TODO There is a race where we set SERVICE_UP=false while 
sensor-adapter threads may still be polling.
-        // The other thread might reset SERVICE_UP to true immediately after 
we set it to false here.
-        // Deactivating adapters before setting SERVICE_UP reduces the race, 
and it is reduced further by setting
-        // SERVICE_UP to false at the end of stop as well.
-        
-        // Perhaps we should wait until all feeds have completed here, 
-        // or do a SERVICE_STATE check before setting SERVICE_UP to true in a 
feed (?).
-
-        if (DynamicTasks.getTaskQueuingContext() != null) {
-            getLifecycleEffectorTasks().stop(ConfigBag.EMPTY);
-        } else {
-            Task<?> task = Tasks.builder().name("stop").body(new Runnable() { 
public void run() { getLifecycleEffectorTasks().stop(ConfigBag.EMPTY); } 
}).build();
-            Entities.submit(this, task).getUnchecked();
-        }
-    }
-
-    /**
-     * If custom behaviour is required by sub-classes, consider overriding 
{@link #preRestart()} or {@link #postRestart()}.
-     * Also consider adding additional work via tasks, executed using {@link 
DynamicTasks#queue(String, Callable)}.
-     */
-    @Override
-    public final void restart() {
-        if (DynamicTasks.getTaskQueuingContext() != null) {
-            getLifecycleEffectorTasks().restart(ConfigBag.EMPTY);
-        } else {
-            Task<?> task = Tasks.builder().name("restart").body(new Runnable() 
{ public void run() { getLifecycleEffectorTasks().restart(ConfigBag.EMPTY); } 
}).build();
-            Entities.submit(this, task).getUnchecked();
-        }
-    }
-    
-    protected SoftwareProcessDriverLifecycleEffectorTasks 
getLifecycleEffectorTasks() {
-        return getConfig(LIFECYCLE_EFFECTOR_TASKS);
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/64c2b2e5/software/base/src/main/java/brooklyn/entity/basic/VanillaSoftwareProcess.java
----------------------------------------------------------------------
diff --git 
a/software/base/src/main/java/brooklyn/entity/basic/VanillaSoftwareProcess.java 
b/software/base/src/main/java/brooklyn/entity/basic/VanillaSoftwareProcess.java
deleted file mode 100644
index 4049e0f..0000000
--- 
a/software/base/src/main/java/brooklyn/entity/basic/VanillaSoftwareProcess.java
+++ /dev/null
@@ -1,62 +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 brooklyn.entity.basic;
-
-import org.apache.brooklyn.api.catalog.Catalog;
-import org.apache.brooklyn.api.entity.ImplementedBy;
-import org.apache.brooklyn.config.ConfigKey;
-import org.apache.brooklyn.core.config.ConfigKeys;
-
-/** 
- * A {@link SoftwareProcess} entity that runs commands from an archive.
- * <p>
- * Downloads and unpacks the archive indicated (optionally) then runs the 
management commands (scripts) indicated
- * (relative to the root of the archive if supplied, otherwise in a tmp 
working dir) to manage. Uses config keys
- * to identify the files or commands to use.
- * <p>
- * In the simplest mode, simply provide either:
- * <ul>
- * <li> an archive in {@link #DOWNLOAD_URL} containing a 
<code>./start.sh</code>
- * <li> a start command to invoke in {@link #LAUNCH_COMMAND}
- * </ul>
- * The only constraint is that the start command must write the PID into the 
file pointed to by the injected environment
- * variable {@code PID_FILE} unless one of the options below is supported.
- * <p>
- * The start command can be a complex bash command, downloading and unpacking 
files, and handling the {@code PID_FILE} requirement.
- * For example {@code export MY_PID_FILE=$PID_FILE ; ./my_start.sh} or {@code 
nohup ./start.sh & ; echo $! > $PID_FILE ; sleep 5}.
- * </pre>
- * You can supply both {@link #DOWNLOAD_URL} and {@link #LAUNCH_COMMAND} 
configuration as well..
- * <p>
- * In addition, you can supply an {@link #INSTALL_COMMAND} and / or a {@link 
#CUSTOMIZE_COMMAND} to reduce the complexity
- * of the {@link #LAUNCH_COMMAND}, and to avoid repeating actions that are 
unnecessary in subsequent launches.
- * <p>
- * By default the PID is used to stop the process using {@code kill} followed 
by {@code kill -9} if needed and restart
- * is implemented by stopping the process and then running {@link 
VanillaSoftwareProcessSshDriver#launch()}, but it is
- * possible to override this behavior through config keys:
- * <ul>
- * <li> A custom {@link #CHECK_RUNNING_COMMAND}
- * <li> A custom {@link #STOP_COMMAND}
- * <li> A different {@link SoftwareProcess#PID_FILE} to use
- * <li>
- */
-@Catalog(name="Vanilla Software Process", description="A software process 
configured with scripts, e.g. for launch, check-running and stop")
-@ImplementedBy(VanillaSoftwareProcessImpl.class)
-public interface VanillaSoftwareProcess extends AbstractVanillaProcess {
-    ConfigKey<String> LAUNCH_COMMAND = 
ConfigKeys.newConfigKeyWithDefault(AbstractVanillaProcess.LAUNCH_COMMAND, 
"./start.sh");
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/64c2b2e5/software/base/src/main/java/brooklyn/entity/basic/VanillaSoftwareProcessDriver.java
----------------------------------------------------------------------
diff --git 
a/software/base/src/main/java/brooklyn/entity/basic/VanillaSoftwareProcessDriver.java
 
b/software/base/src/main/java/brooklyn/entity/basic/VanillaSoftwareProcessDriver.java
deleted file mode 100644
index aa98086..0000000
--- 
a/software/base/src/main/java/brooklyn/entity/basic/VanillaSoftwareProcessDriver.java
+++ /dev/null
@@ -1,23 +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 brooklyn.entity.basic;
-
-public interface VanillaSoftwareProcessDriver extends SoftwareProcessDriver {
-
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/64c2b2e5/software/base/src/main/java/brooklyn/entity/basic/VanillaSoftwareProcessImpl.java
----------------------------------------------------------------------
diff --git 
a/software/base/src/main/java/brooklyn/entity/basic/VanillaSoftwareProcessImpl.java
 
b/software/base/src/main/java/brooklyn/entity/basic/VanillaSoftwareProcessImpl.java
deleted file mode 100644
index e7a9f70..0000000
--- 
a/software/base/src/main/java/brooklyn/entity/basic/VanillaSoftwareProcessImpl.java
+++ /dev/null
@@ -1,37 +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 brooklyn.entity.basic;
-
-
-public class VanillaSoftwareProcessImpl extends SoftwareProcessImpl implements 
VanillaSoftwareProcess {
-    @Override
-    public Class<?> getDriverInterface() {
-        return VanillaSoftwareProcessDriver.class;
-    }
-    @Override
-    protected void connectSensors() {
-        super.connectSensors();
-        connectServiceUpIsRunning();
-    }
-    @Override
-    protected void disconnectSensors() {
-        disconnectServiceUpIsRunning();
-        super.disconnectSensors();
-    }
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/64c2b2e5/software/base/src/main/java/brooklyn/entity/basic/VanillaSoftwareProcessSshDriver.java
----------------------------------------------------------------------
diff --git 
a/software/base/src/main/java/brooklyn/entity/basic/VanillaSoftwareProcessSshDriver.java
 
b/software/base/src/main/java/brooklyn/entity/basic/VanillaSoftwareProcessSshDriver.java
deleted file mode 100644
index 4a85565..0000000
--- 
a/software/base/src/main/java/brooklyn/entity/basic/VanillaSoftwareProcessSshDriver.java
+++ /dev/null
@@ -1,164 +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 brooklyn.entity.basic;
-
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.brooklyn.api.entity.drivers.downloads.DownloadResolver;
-import org.apache.brooklyn.api.internal.EntityLocal;
-import org.apache.brooklyn.entity.core.Entities;
-
-import brooklyn.entity.basic.lifecycle.ScriptHelper;
-
-import org.apache.brooklyn.location.basic.SshMachineLocation;
-import org.apache.brooklyn.util.collections.MutableMap;
-import org.apache.brooklyn.util.core.file.ArchiveUtils;
-import org.apache.brooklyn.util.guava.Maybe;
-import org.apache.brooklyn.util.net.Urls;
-import org.apache.brooklyn.util.os.Os;
-import org.apache.brooklyn.util.ssh.BashCommands;
-import org.apache.brooklyn.util.text.Identifiers;
-import org.apache.brooklyn.util.text.Strings;
-
-public class VanillaSoftwareProcessSshDriver extends 
AbstractSoftwareProcessSshDriver implements VanillaSoftwareProcessDriver {
-
-    public VanillaSoftwareProcessSshDriver(EntityLocal entity, 
SshMachineLocation machine) {
-        super(entity, machine);
-    }
-
-    String downloadedFilename = null;
-
-    /** needed because the download url might be different! */
-    @Override
-    protected String getInstallLabelExtraSalt() {
-        Maybe<Object> url = 
getEntity().getConfigRaw(SoftwareProcess.DOWNLOAD_URL, true);
-        if (url.isAbsent()) return null;
-        // TODO a user-friendly hash would be nice, but tricky since we don't 
want it to be too long or contain path chars
-        return Identifiers.makeIdFromHash( url.get().hashCode() );
-    }
-    
-    @Override
-    public void install() {
-        Maybe<Object> url = 
getEntity().getConfigRaw(SoftwareProcess.DOWNLOAD_URL, true);
-        if (url.isPresentAndNonNull()) {
-            DownloadResolver resolver = Entities.newDownloader(this);
-            List<String> urls = resolver.getTargets();
-            downloadedFilename = resolver.getFilename();
-
-            List<String> commands = new LinkedList<String>();
-            commands.addAll(BashCommands.commandsToDownloadUrlsAs(urls, 
downloadedFilename));
-            commands.addAll(ArchiveUtils.installCommands(downloadedFilename));
-
-            int result = newScript(INSTALLING)
-                    .failOnNonZeroResultCode(false)
-                    .body.append(commands)
-                    .execute();
-            
-            if (result!=0) {
-                // could not install at remote machine; try resolving URL here 
and copying across
-                for (String urlI: urls) {
-                    result = ArchiveUtils.install(getMachine(), urlI, 
Urls.mergePaths(getInstallDir(), downloadedFilename));
-                    if (result==0) 
-                        break;
-                }
-                if (result != 0) 
-                    throw new IllegalStateException("Error installing archive: 
" + downloadedFilename);
-            }
-        }
-        
-        String installCommand = 
getEntity().getConfig(VanillaSoftwareProcess.INSTALL_COMMAND);
-        
-        if (Strings.isNonBlank(installCommand)) {
-            newScript(INSTALLING)
-                .failOnNonZeroResultCode()
-                .environmentVariablesReset(getShellEnvironment())
-                .body.append(installCommand)
-                .execute();
-        }
-    }
-
-    @Override
-    public void customize() {
-        if (downloadedFilename != null) {
-            newScript(CUSTOMIZING)
-                    .failOnNonZeroResultCode()
-                    // don't set vars yet -- it resolves dependencies (e.g. 
DB) which we don't want until we start
-                    .environmentVariablesReset()
-                    
.body.append(ArchiveUtils.extractCommands(downloadedFilename, getInstallDir()))
-                    .execute();
-        }
-        
-        String customizeCommand = 
getEntity().getConfig(VanillaSoftwareProcess.CUSTOMIZE_COMMAND);
-        
-        if (Strings.isNonBlank(customizeCommand)) {
-            newScript(CUSTOMIZING)
-                .failOnNonZeroResultCode()
-                .body.append(customizeCommand)
-                .execute();
-        }
-    }
-
-    @Override
-    public Map<String, String> getShellEnvironment() {
-        return MutableMap.copyOf(super.getShellEnvironment()).add("PID_FILE", 
getPidFile());
-    }
-
-    public String getPidFile() {
-        // TODO see note in VanillaSoftwareProcess about PID_FILE as a config 
key
-        // if (getEntity().getConfigRaw(PID_FILE, includeInherited)) ...
-        return Os.mergePathsUnix(getRunDir(), PID_FILENAME);
-    }
-
-    @Override
-    public void launch() {
-        newScript(LAUNCHING)
-            .failOnNonZeroResultCode()
-            
.body.append(getEntity().getConfig(VanillaSoftwareProcess.LAUNCH_COMMAND))
-            .execute();
-    }
-
-    @Override
-    public boolean isRunning() {
-        String customCommand = 
getEntity().getConfig(VanillaSoftwareProcess.CHECK_RUNNING_COMMAND);
-        ScriptHelper script = null;
-        if (customCommand == null) {
-            script = newScript(MutableMap.of(USE_PID_FILE, getPidFile()), 
CHECK_RUNNING);
-        } else {
-            // TODO: template substitutions?
-            script = newScript(CHECK_RUNNING).body.append(customCommand);
-        }
-        return script.execute() == 0;
-    }
-
-    @Override
-    public void stop() {
-        String customCommand = 
getEntity().getConfig(VanillaSoftwareProcess.STOP_COMMAND);
-        ScriptHelper script = null;
-        if (customCommand == null) {
-            script = newScript(MutableMap.of(USE_PID_FILE, getPidFile()), 
STOPPING);
-        } else {
-            // TODO: template substitutions?
-            script = newScript(STOPPING).body.append(customCommand);
-        }
-        script.execute();
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/64c2b2e5/software/base/src/main/java/brooklyn/entity/basic/VanillaWindowsProcess.java
----------------------------------------------------------------------
diff --git 
a/software/base/src/main/java/brooklyn/entity/basic/VanillaWindowsProcess.java 
b/software/base/src/main/java/brooklyn/entity/basic/VanillaWindowsProcess.java
deleted file mode 100644
index 3fce37f..0000000
--- 
a/software/base/src/main/java/brooklyn/entity/basic/VanillaWindowsProcess.java
+++ /dev/null
@@ -1,64 +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 brooklyn.entity.basic;
-
-import java.util.Collection;
-
-import org.apache.brooklyn.api.entity.ImplementedBy;
-import org.apache.brooklyn.api.sensor.AttributeSensor;
-import org.apache.brooklyn.config.ConfigKey;
-import org.apache.brooklyn.core.config.ConfigKeys;
-import org.apache.brooklyn.sensor.core.Sensors;
-import org.apache.brooklyn.util.time.Duration;
-
-import com.google.common.collect.ImmutableSet;
-
-@ImplementedBy(VanillaWindowsProcessImpl.class)
-public interface VanillaWindowsProcess extends AbstractVanillaProcess {
-    // 3389 is RDP; 5985 is WinRM (3389 isn't used by Brooklyn, but useful for 
the end-user subsequently)
-    ConfigKey<Collection<Integer>> REQUIRED_OPEN_LOGIN_PORTS = 
ConfigKeys.newConfigKeyWithDefault(
-            SoftwareProcess.REQUIRED_OPEN_LOGIN_PORTS,
-            ImmutableSet.of(5985, 3389));
-    ConfigKey<String> PRE_INSTALL_POWERSHELL_COMMAND = 
ConfigKeys.newStringConfigKey("pre.install.powershell.command",
-            "powershell command to run during the pre-install phase");
-    ConfigKey<Boolean> PRE_INSTALL_REBOOT_REQUIRED = 
ConfigKeys.newBooleanConfigKey("pre.install.reboot.required",
-            "indicates that a reboot should be performed after the pre-install 
command is run", false);
-    ConfigKey<Boolean> INSTALL_REBOOT_REQUIRED = 
ConfigKeys.newBooleanConfigKey("install.reboot.required",
-            "indicates that a reboot should be performed after the install 
command is run", false);
-    ConfigKey<Boolean> CUSTOMIZE_REBOOT_REQUIRED = 
ConfigKeys.newBooleanConfigKey("customize.reboot.required",
-            "indicates that a reboot should be performed after the customize 
command is run", false);
-    ConfigKey<String> LAUNCH_POWERSHELL_COMMAND = 
ConfigKeys.newStringConfigKey("launch.powershell.command",
-            "command to run to launch the process");
-    ConfigKey<String> CHECK_RUNNING_POWERSHELL_COMMAND = 
ConfigKeys.newStringConfigKey("checkRunning.powershell.command",
-            "command to determine whether the process is running");
-    ConfigKey<String> STOP_POWERSHELL_COMMAND = 
ConfigKeys.newStringConfigKey("stop.powershell.command",
-            "command to run to stop the process");
-    ConfigKey<String> CUSTOMIZE_POWERSHELL_COMMAND = 
ConfigKeys.newStringConfigKey("customize.powershell.command",
-            "powershell command to run during the customization phase");
-    ConfigKey<String> INSTALL_POWERSHELL_COMMAND = 
ConfigKeys.newStringConfigKey("install.powershell.command",
-            "powershell command to run during the install phase");
-    ConfigKey<Duration> REBOOT_BEGUN_TIMEOUT = 
ConfigKeys.newDurationConfigKey("reboot.begun.timeout",
-            "duration to wait whilst waiting for a machine to begin rebooting, 
and thus become unavailable", Duration.TWO_MINUTES);
-    // TODO If automatic updates are enabled and there are updates waiting to 
be installed, thirty minutes may not be sufficient...
-    ConfigKey<Duration> REBOOT_COMPLETED_TIMEOUT = 
ConfigKeys.newDurationConfigKey("reboot.completed.timeout",
-            "duration to wait whilst waiting for a machine to finish 
rebooting, and thus to become available again", Duration.minutes(30));
-    
-    AttributeSensor<Integer> RDP_PORT = Sensors.newIntegerSensor("rdpPort");
-    AttributeSensor<Integer> WINRM_PORT = 
Sensors.newIntegerSensor("winrmPort");
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/64c2b2e5/software/base/src/main/java/brooklyn/entity/basic/VanillaWindowsProcessDriver.java
----------------------------------------------------------------------
diff --git 
a/software/base/src/main/java/brooklyn/entity/basic/VanillaWindowsProcessDriver.java
 
b/software/base/src/main/java/brooklyn/entity/basic/VanillaWindowsProcessDriver.java
deleted file mode 100644
index 7e9fd8c..0000000
--- 
a/software/base/src/main/java/brooklyn/entity/basic/VanillaWindowsProcessDriver.java
+++ /dev/null
@@ -1,23 +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 brooklyn.entity.basic;
-
-public interface VanillaWindowsProcessDriver extends SoftwareProcessDriver {
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/64c2b2e5/software/base/src/main/java/brooklyn/entity/basic/VanillaWindowsProcessImpl.java
----------------------------------------------------------------------
diff --git 
a/software/base/src/main/java/brooklyn/entity/basic/VanillaWindowsProcessImpl.java
 
b/software/base/src/main/java/brooklyn/entity/basic/VanillaWindowsProcessImpl.java
deleted file mode 100644
index aaa6641..0000000
--- 
a/software/base/src/main/java/brooklyn/entity/basic/VanillaWindowsProcessImpl.java
+++ /dev/null
@@ -1,47 +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 brooklyn.entity.basic;
-
-
-public class VanillaWindowsProcessImpl extends SoftwareProcessImpl implements 
VanillaWindowsProcess {
-    @Override
-    public Class getDriverInterface() {
-        return VanillaWindowsProcessDriver.class;
-    }
-
-    @Override
-    protected void preStart() {
-        super.preStart();
-        setAttribute(RDP_PORT, 3389);
-        setAttribute(WINRM_PORT, 5985);
-    }
-    
-    @Override
-    protected void connectSensors() {
-        super.connectSensors();
-        connectServiceUpIsRunning();
-    }
-
-    @Override
-    protected void disconnectSensors() {
-        disconnectServiceUpIsRunning();
-        super.disconnectSensors();
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/64c2b2e5/software/base/src/main/java/brooklyn/entity/basic/VanillaWindowsProcessWinRmDriver.java
----------------------------------------------------------------------
diff --git 
a/software/base/src/main/java/brooklyn/entity/basic/VanillaWindowsProcessWinRmDriver.java
 
b/software/base/src/main/java/brooklyn/entity/basic/VanillaWindowsProcessWinRmDriver.java
deleted file mode 100644
index 2c952b0..0000000
--- 
a/software/base/src/main/java/brooklyn/entity/basic/VanillaWindowsProcessWinRmDriver.java
+++ /dev/null
@@ -1,84 +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 brooklyn.entity.basic;
-
-import org.apache.brooklyn.api.internal.EntityLocal;
-import org.apache.brooklyn.entity.core.Attributes;
-import org.apache.brooklyn.location.basic.WinRmMachineLocation;
-import org.apache.brooklyn.util.net.UserAndHostAndPort;
-
-public class VanillaWindowsProcessWinRmDriver extends 
AbstractSoftwareProcessWinRmDriver implements VanillaWindowsProcessDriver {
-
-    public VanillaWindowsProcessWinRmDriver(EntityLocal entity, 
WinRmMachineLocation location) {
-        super(entity, location);
-    }
-
-    @Override
-    public void start() {
-        WinRmMachineLocation machine = (WinRmMachineLocation) location;
-        UserAndHostAndPort winrmAddress = 
UserAndHostAndPort.fromParts(machine.getUser(), 
machine.getAddress().getHostName(), 
machine.config().get(WinRmMachineLocation.WINRM_PORT));
-        getEntity().setAttribute(Attributes.WINRM_ADDRESS, winrmAddress);
-
-        super.start();
-    }
-    
-    @Override
-    public void preInstall() {
-        super.preInstall();
-        executeCommand(VanillaWindowsProcess.PRE_INSTALL_COMMAND, 
VanillaWindowsProcess.PRE_INSTALL_POWERSHELL_COMMAND, true);
-        if 
(entity.getConfig(VanillaWindowsProcess.PRE_INSTALL_REBOOT_REQUIRED)) {
-            rebootAndWait();
-        }
-    }
-
-    @Override
-    public void install() {
-        // TODO: Follow install path of VanillaSoftwareProcessSshDriver
-        executeCommand(VanillaWindowsProcess.INSTALL_COMMAND, 
VanillaWindowsProcess.INSTALL_POWERSHELL_COMMAND, true);
-        if (entity.getConfig(VanillaWindowsProcess.INSTALL_REBOOT_REQUIRED)) {
-            rebootAndWait();
-        }
-    }
-
-    @Override
-    public void customize() {
-        // TODO: Follow customize path of VanillaSoftwareProcessSshDriver
-        executeCommand(VanillaWindowsProcess.CUSTOMIZE_COMMAND, 
VanillaWindowsProcess.CUSTOMIZE_POWERSHELL_COMMAND, true);
-        if (entity.getConfig(VanillaWindowsProcess.CUSTOMIZE_REBOOT_REQUIRED)) 
{
-            rebootAndWait();
-        }
-    }
-
-    @Override
-    public void launch() {
-        executeCommand(VanillaWindowsProcess.LAUNCH_COMMAND, 
VanillaWindowsProcess.LAUNCH_POWERSHELL_COMMAND, true);
-    }
-
-    @Override
-    public boolean isRunning() {
-        return executeCommand(VanillaWindowsProcess.CHECK_RUNNING_COMMAND,
-                VanillaWindowsProcess.CHECK_RUNNING_POWERSHELL_COMMAND, 
false).getStatusCode() == 0;
-    }
-
-    @Override
-    public void stop() {
-        executeCommand(VanillaWindowsProcess.STOP_COMMAND, 
VanillaWindowsProcess.STOP_POWERSHELL_COMMAND, true);
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/64c2b2e5/software/base/src/main/java/brooklyn/entity/basic/lifecycle/NaiveScriptRunner.java
----------------------------------------------------------------------
diff --git 
a/software/base/src/main/java/brooklyn/entity/basic/lifecycle/NaiveScriptRunner.java
 
b/software/base/src/main/java/brooklyn/entity/basic/lifecycle/NaiveScriptRunner.java
deleted file mode 100644
index 1e5e901..0000000
--- 
a/software/base/src/main/java/brooklyn/entity/basic/lifecycle/NaiveScriptRunner.java
+++ /dev/null
@@ -1,43 +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 brooklyn.entity.basic.lifecycle;
-
-import java.util.List;
-import java.util.Map;
-
-import org.apache.brooklyn.util.core.task.ssh.SshTasks;
-
-/** Marks something which can run scripts. Called "Naive" because it hides too 
much of the complexity,
- * about script execution and other ssh-related tasks (put, etc). The {@link 
SshTasks} approach seems better.
- * <p> 
- * Not gone so far as deprecating (yet, in 0.6.0) although we might.  Feedback 
welcome. 
- * @since 0.6.0 */
-public interface NaiveScriptRunner {
-
-    /** Runs a script and returns the result code */
-    int execute(List<String> script, String summaryForLogging);
-
-    /** Runs a script and returns the result code, supporting flags including:
-     *  out, err as output/error streams;
-     *  logPrefix, prefix string to put in log output;
-     *  env, map of environment vars to pass to shell environment */
-    @SuppressWarnings("rawtypes")
-    int execute(Map flags, List<String> script, String summaryForLogging);
-
-}

Reply via email to