You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@brooklyn.apache.org by ha...@apache.org on 2015/08/17 21:18:03 UTC

[32/42] incubator-brooklyn git commit: [BROOKLYN-162] Refactor package in ./core/util

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/a4c0e5fd/core/src/main/java/brooklyn/util/task/ValueResolver.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/util/task/ValueResolver.java b/core/src/main/java/brooklyn/util/task/ValueResolver.java
deleted file mode 100644
index 37f4269..0000000
--- a/core/src/main/java/brooklyn/util/task/ValueResolver.java
+++ /dev/null
@@ -1,426 +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.util.task;
-
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.Callable;
-import java.util.concurrent.Future;
-import java.util.concurrent.atomic.AtomicBoolean;
-
-import org.apache.brooklyn.api.entity.Entity;
-import org.apache.brooklyn.api.management.ExecutionContext;
-import org.apache.brooklyn.api.management.Task;
-import org.apache.brooklyn.api.management.TaskAdaptable;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import brooklyn.entity.basic.BrooklynTaskTags;
-import brooklyn.entity.basic.EntityInternal;
-import brooklyn.util.exceptions.Exceptions;
-import brooklyn.util.flags.TypeCoercions;
-import brooklyn.util.guava.Maybe;
-import brooklyn.util.javalang.JavaClassNames;
-import brooklyn.util.repeat.Repeater;
-import brooklyn.util.time.CountdownTimer;
-import brooklyn.util.time.Duration;
-import brooklyn.util.time.Durations;
-
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
-import com.google.common.collect.Sets;
-import com.google.common.reflect.TypeToken;
-
-/** 
- * Resolves a given object, as follows:
- * <li> If it is a {@link Tasks} or a {@link DeferredSupplier} then get its contents
- * <li> If it's a map and {@link #deep(boolean)} is requested, it applies resolution to contents
- * <li> It applies coercion
- * <p>
- * Fluent-style API exposes a number of other options.
- */
-public class ValueResolver<T> implements DeferredSupplier<T> {
-
-    /** 
-     * Period to wait if we're expected to return real quick 
-     * but we want fast things to have time to finish.
-     * <p>
-     * Timings are always somewhat arbitrary but this at least
-     * allows some intention to be captured in code rather than arbitrary values. */
-    public static Duration REAL_QUICK_WAIT = Duration.millis(50);
-    /** 
-     * Period to wait if we're expected to return quickly 
-     * but we want to be a bit more generous for things to finish,
-     * without letting a caller get annoyed. 
-     * <p>
-     * See {@link #REAL_QUICK_WAIT}. */
-    public static Duration PRETTY_QUICK_WAIT = Duration.millis(200);
-    
-    /** Period to wait when we have to poll but want to give the illusion of no wait.
-     * See {@link Repeater#DEFAULT_REAL_QUICK_PERIOD} */ 
-    public static Duration REAL_QUICK_PERIOD = Repeater.DEFAULT_REAL_QUICK_PERIOD;
-    
-    private static final Logger log = LoggerFactory.getLogger(ValueResolver.class);
-    
-    final Object value;
-    final Class<T> type;
-    ExecutionContext exec;
-    String description;
-    boolean forceDeep;
-    /** null means do it if you can; true means always, false means never */
-    Boolean embedResolutionInTask;
-    /** timeout on execution, if possible, or if embedResolutionInTask is true */
-    Duration timeout;
-    boolean isTransientTask = true;
-    
-    T defaultValue = null;
-    boolean returnDefaultOnGet = false;
-    boolean swallowExceptions = false;
-    
-    // internal fields
-    final Object parentOriginalValue;
-    final CountdownTimer parentTimer;
-    AtomicBoolean started = new AtomicBoolean(false);
-    boolean expired;
-    
-    ValueResolver(Object v, Class<T> type) {
-        this.value = v;
-        this.type = type;
-        checkTypeNotNull();
-        parentOriginalValue = null;
-        parentTimer = null;
-    }
-    
-    ValueResolver(Object v, Class<T> type, ValueResolver<?> parent) {
-        this.value = v;
-        this.type = type;
-        checkTypeNotNull();
-        
-        exec = parent.exec;
-        description = parent.description;
-        forceDeep = parent.forceDeep;
-        embedResolutionInTask = parent.embedResolutionInTask;
-
-        parentOriginalValue = parent.getOriginalValue();
-
-        timeout = parent.timeout;
-        parentTimer = parent.parentTimer;
-        if (parentTimer!=null && parentTimer.isExpired())
-            expired = true;
-        
-        // default value and swallow exceptions do not need to be nested
-    }
-
-    public static class ResolverBuilderPretype {
-        final Object v;
-        public ResolverBuilderPretype(Object v) {
-            this.v = v;
-        }
-        public <T> ValueResolver<T> as(Class<T> type) {
-            return new ValueResolver<T>(v, type);
-        }
-    }
-
-    /** returns a copy of this resolver which can be queried, even if the original (single-use instance) has already been copied */
-    public ValueResolver<T> clone() {
-        ValueResolver<T> result = new ValueResolver<T>(value, type)
-            .context(exec).description(description)
-            .embedResolutionInTask(embedResolutionInTask)
-            .deep(forceDeep)
-            .timeout(timeout);
-        if (returnDefaultOnGet) result.defaultValue(defaultValue);
-        if (swallowExceptions) result.swallowExceptions();
-        return result;
-    }
-    
-    /** execution context to use when resolving; required if resolving unsubmitted tasks or running with a time limit */
-    public ValueResolver<T> context(ExecutionContext exec) {
-        this.exec = exec;
-        return this;
-    }
-    /** as {@link #context(ExecutionContext)} for use from an entity */
-    public ValueResolver<T> context(Entity entity) {
-        return context(entity!=null ? ((EntityInternal)entity).getExecutionContext() : null);
-    }
-    
-    /** sets a message which will be displayed in status reports while it waits (e.g. the name of the config key being looked up) */
-    public ValueResolver<T> description(String description) {
-        this.description = description;
-        return this;
-    }
-    
-    /** sets a default value which will be returned on a call to {@link #get()} if the task does not complete
-     * or completes with an error
-     * <p>
-     * note that {@link #getMaybe()} returns an absent object even in the presence of
-     * a default, so that any error can still be accessed */
-    public ValueResolver<T> defaultValue(T defaultValue) {
-        this.defaultValue = defaultValue;
-        this.returnDefaultOnGet = true;
-        return this;
-    }
-
-    /** indicates that no default value should be returned on a call to {@link #get()}, and instead it should throw
-     * (this is the default; this method is provided to undo a call to {@link #defaultValue(Object)}) */
-    public ValueResolver<T> noDefaultValue() {
-        this.returnDefaultOnGet = false;
-        this.defaultValue = null;
-        return this;
-    }
-    
-    /** indicates that exceptions in resolution should not be thrown on a call to {@link #getMaybe()}, 
-     * but rather used as part of the {@link Maybe#get()} if it's absent, 
-     * and swallowed altogether on a call to {@link #get()} in the presence of a {@link #defaultValue(Object)} */
-    public ValueResolver<T> swallowExceptions() {
-        this.swallowExceptions = true;
-        return this;
-    }
-    
-    /** whether the task should be marked as transient; defaults true */
-    public ValueResolver<T> transientTask(boolean isTransientTask) {
-        this.isTransientTask = isTransientTask;
-        return this;
-    }
-    
-    public Maybe<T> getDefault() {
-        if (returnDefaultOnGet) return Maybe.of(defaultValue);
-        else return Maybe.absent("No default value set");
-    }
-    
-    /** causes nested structures (maps, lists) to be descended and nested unresolved values resolved */
-    public ValueResolver<T> deep(boolean forceDeep) {
-        this.forceDeep = forceDeep;
-        return this;
-    }
-
-    /** if true, forces execution of a deferred supplier to be run in a task;
-     * if false, it prevents it (meaning time limits may not be applied);
-     * if null, the default, it runs in a task if a time limit is applied.
-     * <p>
-     * running inside a task is required for some {@link DeferredSupplier}
-     * instances which look up a task {@link ExecutionContext}. */
-    public ValueResolver<T> embedResolutionInTask(Boolean embedResolutionInTask) {
-        this.embedResolutionInTask = embedResolutionInTask;
-        return this;
-    }
-    
-    /** sets a time limit on executions
-     * <p>
-     * used for {@link Task} and {@link DeferredSupplier} instances.
-     * may require an execution context at runtime. */
-    public ValueResolver<T> timeout(Duration timeout) {
-        this.timeout = timeout;
-        return this;
-    }
-    
-    protected void checkTypeNotNull() {
-        if (type==null) 
-            throw new NullPointerException("type must be set to resolve, for '"+value+"'"+(description!=null ? ", "+description : ""));
-    }
-
-    public T get() {
-        Maybe<T> m = getMaybe();
-        if (m.isPresent()) return m.get();
-        if (returnDefaultOnGet) return defaultValue;
-        return m.get();
-    }
-    
-    public Maybe<T> getMaybe() {
-        Maybe<T> result = getMaybeInternal();
-        if (log.isTraceEnabled()) {
-            log.trace(this+" evaluated as "+result);
-        }
-        return result;
-    }
-    
-    @SuppressWarnings({ "unchecked", "rawtypes" })
-    protected Maybe<T> getMaybeInternal() {
-        if (started.getAndSet(true))
-            throw new IllegalStateException("ValueResolver can only be used once");
-        
-        if (expired) return Maybe.absent("Nested resolution of "+getOriginalValue()+" did not complete within "+timeout);
-        
-        ExecutionContext exec = this.exec;
-        if (exec==null) {
-            // if execution context not specified, take it from the current task if present
-            exec = BasicExecutionContext.getCurrentExecutionContext();
-        }
-        
-        CountdownTimer timerU = parentTimer;
-        if (timerU==null && timeout!=null)
-            timerU = timeout.countdownTimer();
-        final CountdownTimer timer = timerU;
-        if (timer!=null && !timer.isRunning())
-            timer.start();
-        
-        checkTypeNotNull();
-        Object v = this.value;
-        
-        //if the expected type is a closure or map and that's what we have, we're done (or if it's null);
-        //but not allowed to return a future or DeferredSupplier as the resolved value
-        if (v==null || (!forceDeep && type.isInstance(v) && !Future.class.isInstance(v) && !DeferredSupplier.class.isInstance(v)))
-            return Maybe.of((T) v);
-        
-        try {
-            //if it's a task or a future, we wait for the task to complete
-            if (v instanceof TaskAdaptable<?>) {
-                //if it's a task, we make sure it is submitted
-                if (!((TaskAdaptable<?>) v).asTask().isSubmitted() ) {
-                    if (exec==null)
-                        return Maybe.absent("Value for unsubmitted task '"+getDescription()+"' requested but no execution context available");
-                    exec.submit(((TaskAdaptable<?>) v).asTask());
-                }
-            }
-
-            if (v instanceof Future) {
-                final Future<?> vfuture = (Future<?>) v;
-
-                //including tasks, above
-                if (!vfuture.isDone()) {
-                    Callable<Maybe> callable = new Callable<Maybe>() {
-                        public Maybe call() throws Exception {
-                            return Durations.get(vfuture, timer);
-                        } };
-
-                    String description = getDescription();
-                    Maybe vm = Tasks.withBlockingDetails("Waiting for "+description, callable);
-                    if (vm.isAbsent()) return vm;
-                    v = vm.get();
-
-                } else {
-                    v = vfuture.get();
-                    
-                }
-
-            } else if (v instanceof DeferredSupplier<?>) {
-                final Object vf = v;
-
-                if ((!Boolean.FALSE.equals(embedResolutionInTask) && (exec!=null || timeout!=null)) || Boolean.TRUE.equals(embedResolutionInTask)) {
-                    if (exec==null)
-                        return Maybe.absent("Embedding in task needed for '"+getDescription()+"' but no execution context available");
-                        
-                    Callable<Object> callable = new Callable<Object>() {
-                        public Object call() throws Exception {
-                            try {
-                                Tasks.setBlockingDetails("Retrieving "+vf);
-                                return ((DeferredSupplier<?>) vf).get();
-                            } finally {
-                                Tasks.resetBlockingDetails();
-                            }
-                        } };
-                    String description = getDescription();
-                    TaskBuilder<Object> vb = Tasks.<Object>builder().body(callable).name("Resolving dependent value").description(description);
-                    if (isTransientTask) vb.tag(BrooklynTaskTags.TRANSIENT_TASK_TAG);
-                    Task<Object> vt = exec.submit(vb.build());
-                    // TODO to handle immediate resolution, it would be nice to be able to submit 
-                    // so it executes in the current thread,
-                    // or put a marker in the target thread or task while it is running that the task 
-                    // should never wait on anything other than another value being resolved 
-                    // (though either could recurse infinitely) 
-                    Maybe<Object> vm = Durations.get(vt, timer);
-                    vt.cancel(true);
-                    if (vm.isAbsent()) return (Maybe<T>)vm;
-                    v = vm.get();
-                    
-                } else {
-                    try {
-                        Tasks.setBlockingDetails("Retrieving (non-task) "+vf);
-                        v = ((DeferredSupplier<?>) vf).get();
-                    } finally {
-                        Tasks.resetBlockingDetails();
-                    }
-                }
-
-            } else if (v instanceof Map) {
-                //and if a map or list we look inside
-                Map result = Maps.newLinkedHashMap();
-                for (Map.Entry<?,?> entry : ((Map<?,?>)v).entrySet()) {
-                    Maybe<?> kk = new ValueResolver(entry.getKey(), type, this)
-                        .description( (description!=null ? description+", " : "") + "map key "+entry.getKey() )
-                        .getMaybe();
-                    if (kk.isAbsent()) return (Maybe<T>)kk;
-                    Maybe<?> vv = new ValueResolver(entry.getValue(), type, this)
-                        .description( (description!=null ? description+", " : "") + "map value for key "+kk.get() )
-                        .getMaybe();
-                    if (vv.isAbsent()) return (Maybe<T>)vv;
-                    result.put(kk.get(), vv.get());
-                }
-                return Maybe.of((T) result);
-
-            } else if (v instanceof Set) {
-                Set result = Sets.newLinkedHashSet();
-                int count = 0;
-                for (Object it : (Set)v) {
-                    Maybe<?> vv = new ValueResolver(it, type, this)
-                        .description( (description!=null ? description+", " : "") + "entry "+count )
-                        .getMaybe();
-                    if (vv.isAbsent()) return (Maybe<T>)vv;
-                    result.add(vv.get());
-                    count++;
-                }
-                return Maybe.of((T) result);
-
-            } else if (v instanceof Iterable) {
-                List result = Lists.newArrayList();
-                int count = 0;
-                for (Object it : (Iterable)v) {
-                    Maybe<?> vv = new ValueResolver(it, type, this)
-                        .description( (description!=null ? description+", " : "") + "entry "+count )
-                        .getMaybe();
-                    if (vv.isAbsent()) return (Maybe<T>)vv;
-                    result.add(vv.get());
-                    count++;
-                }
-                return Maybe.of((T) result);
-
-            } else {
-                return TypeCoercions.tryCoerce(v, TypeToken.of(type));
-            }
-
-        } catch (Exception e) {
-            Exceptions.propagateIfFatal(e);
-            
-            IllegalArgumentException problem = new IllegalArgumentException("Error resolving "+(description!=null ? description+", " : "")+v+", in "+exec+": "+e, e);
-            if (swallowExceptions) {
-                if (log.isDebugEnabled())
-                    log.debug("Resolution of "+this+" failed, swallowing and returning: "+e);
-                return Maybe.absent(problem);
-            }
-            if (log.isDebugEnabled())
-                log.debug("Resolution of "+this+" failed, throwing: "+e);
-            throw problem;
-        }
-        
-        return new ValueResolver(v, type, this).getMaybe();
-    }
-
-    protected String getDescription() {
-        return description!=null ? description : ""+value;
-    }
-    protected Object getOriginalValue() {
-        if (parentOriginalValue!=null) return parentOriginalValue;
-        return value;
-    }
-    
-    @Override
-    public String toString() {
-        return JavaClassNames.cleanSimpleClassName(this)+"["+JavaClassNames.cleanSimpleClassName(type)+" "+value+"]";
-    }
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/a4c0e5fd/core/src/main/java/brooklyn/util/task/ssh/SshFetchTaskFactory.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/util/task/ssh/SshFetchTaskFactory.java b/core/src/main/java/brooklyn/util/task/ssh/SshFetchTaskFactory.java
deleted file mode 100644
index bd9e96e..0000000
--- a/core/src/main/java/brooklyn/util/task/ssh/SshFetchTaskFactory.java
+++ /dev/null
@@ -1,89 +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.util.task.ssh;
-
-import org.apache.brooklyn.api.management.TaskFactory;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import org.apache.brooklyn.location.basic.SshMachineLocation;
-import brooklyn.util.config.ConfigBag;
-
-// cannot be (cleanly) instantiated due to nested generic self-referential type; however trivial subclasses do allow it 
-public class SshFetchTaskFactory implements TaskFactory<SshFetchTaskWrapper> {
-    
-    private static final Logger log = LoggerFactory.getLogger(SshFetchTaskFactory.class);
-    
-    private boolean dirty = false;
-    
-    protected SshMachineLocation machine;
-    protected String remoteFile;
-    protected final ConfigBag config = ConfigBag.newInstance();
-
-    /** constructor where machine will be added later */
-    public SshFetchTaskFactory(String remoteFile) {
-        remoteFile(remoteFile);
-    }
-
-    /** convenience constructor to supply machine immediately */
-    public SshFetchTaskFactory(SshMachineLocation machine, String remoteFile) {
-        machine(machine);
-        remoteFile(remoteFile);
-    }
-
-    protected SshFetchTaskFactory self() { return this; }
-
-    protected void markDirty() {
-        dirty = true;
-    }
-    
-    public SshFetchTaskFactory machine(SshMachineLocation machine) {
-        markDirty();
-        this.machine = machine;
-        return self();
-    }
-        
-    public SshMachineLocation getMachine() {
-        return machine;
-    }
-    
-    public SshFetchTaskFactory remoteFile(String remoteFile) {
-        this.remoteFile = remoteFile;
-        return self();
-    }
-
-    public ConfigBag getConfig() {
-        return config;
-    }
-    
-    @Override
-    public SshFetchTaskWrapper newTask() {
-        dirty = false;
-        return new SshFetchTaskWrapper(this);
-    }
-
-    @Override
-    protected void finalize() throws Throwable {
-        // help let people know of API usage error
-        if (dirty)
-            log.warn("Task "+this+" was modified but modification was never used");
-        super.finalize();
-    }
-
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/a4c0e5fd/core/src/main/java/brooklyn/util/task/ssh/SshFetchTaskWrapper.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/util/task/ssh/SshFetchTaskWrapper.java b/core/src/main/java/brooklyn/util/task/ssh/SshFetchTaskWrapper.java
deleted file mode 100644
index 9553b4f..0000000
--- a/core/src/main/java/brooklyn/util/task/ssh/SshFetchTaskWrapper.java
+++ /dev/null
@@ -1,135 +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.util.task.ssh;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.concurrent.Callable;
-
-import org.apache.brooklyn.api.management.Task;
-import org.apache.brooklyn.api.management.TaskWrapper;
-import org.apache.commons.io.FileUtils;
-import org.apache.commons.io.FilenameUtils;
-
-import org.apache.brooklyn.location.basic.SshMachineLocation;
-import brooklyn.util.config.ConfigBag;
-import brooklyn.util.exceptions.Exceptions;
-import brooklyn.util.os.Os;
-import brooklyn.util.task.TaskBuilder;
-import brooklyn.util.task.Tasks;
-import brooklyn.util.task.system.ProcessTaskWrapper;
-
-import com.google.common.annotations.Beta;
-import com.google.common.base.Preconditions;
-
-/**
- * As {@link ProcessTaskWrapper}, but putting a file on the remote machine
- * 
- * @since 0.6.0
- */
-@Beta
-public class SshFetchTaskWrapper implements TaskWrapper<String> {
-
-    private final Task<String> task;
-
-    private final String remoteFile;
-    private final SshMachineLocation machine;
-    private File backingFile;
-    private final ConfigBag config;
-    
-    
-    // package private as only AbstractSshTaskFactory should invoke
-    SshFetchTaskWrapper(SshFetchTaskFactory factory) {
-        this.remoteFile = Preconditions.checkNotNull(factory.remoteFile, "remoteFile");
-        this.machine = Preconditions.checkNotNull(factory.machine, "machine");
-        TaskBuilder<String> tb = TaskBuilder.<String>builder().dynamic(false).name("ssh fetch "+factory.remoteFile);
-        task = tb.body(new SshFetchJob()).build();
-        config = factory.getConfig();
-    }
-    
-    @Override
-    public Task<String> asTask() {
-        return getTask();
-    }
-    
-    @Override
-    public Task<String> getTask() {
-        return task;
-    }
-    
-    public String getRemoteFile() {
-        return remoteFile;
-    }
-    
-    public SshMachineLocation getMachine() {
-        return machine;
-    }
-        
-    private class SshFetchJob implements Callable<String> {
-        @Override
-        public String call() throws Exception {
-            int result = -1;
-            try {
-                Preconditions.checkNotNull(getMachine(), "machine");
-                backingFile = Os.newTempFile("brooklyn-ssh-fetch-", FilenameUtils.getName(remoteFile));
-                backingFile.deleteOnExit();
-                
-                result = getMachine().copyFrom(config.getAllConfig(), remoteFile, backingFile.getPath());
-            } catch (Exception e) {
-                throw new IllegalStateException("SSH fetch "+getRemoteFile()+" from "+getMachine()+" returned threw exception, in "+Tasks.current()+": "+e, e);
-            }
-            if (result!=0) {
-                throw new IllegalStateException("SSH fetch "+getRemoteFile()+" from "+getMachine()+" returned non-zero exit code  "+result+", in "+Tasks.current());
-            }
-            return FileUtils.readFileToString(backingFile);
-        }
-    }
-    
-    @Override
-    public String toString() {
-        return super.toString()+"["+task+"]";
-    }
-
-    /** blocks, returns the fetched file as a string, throwing if there was an exception */
-    public String get() {
-        return getTask().getUnchecked();
-    }
-    
-    /** blocks, returns the fetched file as bytes, throwing if there was an exception */
-    public byte[] getBytes() {
-        block();
-        try {
-            return FileUtils.readFileToByteArray(backingFile);
-        } catch (IOException e) {
-            throw Exceptions.propagate(e);
-        }
-    }
-    
-    /** blocks until the task completes; does not throw */
-    public SshFetchTaskWrapper block() {
-        getTask().blockUntilEnded();
-        return this;
-    }
- 
-    /** true iff the ssh job has completed (with or without failure) */
-    public boolean isDone() {
-        return getTask().isDone();
-    }   
-
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/a4c0e5fd/core/src/main/java/brooklyn/util/task/ssh/SshPutTaskFactory.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/util/task/ssh/SshPutTaskFactory.java b/core/src/main/java/brooklyn/util/task/ssh/SshPutTaskFactory.java
deleted file mode 100644
index e2c5502..0000000
--- a/core/src/main/java/brooklyn/util/task/ssh/SshPutTaskFactory.java
+++ /dev/null
@@ -1,123 +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.util.task.ssh;
-
-import java.io.InputStream;
-import java.io.Reader;
-
-import org.apache.brooklyn.api.management.TaskFactory;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import org.apache.brooklyn.location.basic.SshMachineLocation;
-import brooklyn.util.stream.KnownSizeInputStream;
-import brooklyn.util.stream.ReaderInputStream;
-
-import com.google.common.base.Suppliers;
-
-// cannot be (cleanly) instantiated due to nested generic self-referential type; however trivial subclasses do allow it 
-public class SshPutTaskFactory extends SshPutTaskStub implements TaskFactory<SshPutTaskWrapper> {
-    
-    private static final Logger log = LoggerFactory.getLogger(SshPutTaskFactory.class);
-    
-    private boolean dirty = false;
-
-    /** constructor where machine will be added later */
-    public SshPutTaskFactory(String remoteFile) {
-        remoteFile(remoteFile);
-    }
-
-    /** convenience constructor to supply machine immediately */
-    public SshPutTaskFactory(SshMachineLocation machine, String remoteFile) {
-        machine(machine);
-        remoteFile(remoteFile);
-    }
-
-    protected SshPutTaskFactory self() { return this; }
-
-    protected void markDirty() {
-        dirty = true;
-    }
-    
-    public SshPutTaskFactory machine(SshMachineLocation machine) {
-        markDirty();
-        this.machine = machine;
-        return self();
-    }
-        
-    public SshPutTaskFactory remoteFile(String remoteFile) {
-        this.remoteFile = remoteFile;
-        return self();
-    }
-
-    public SshPutTaskFactory summary(String summary) {
-        markDirty();
-        this.summary = summary;
-        return self();
-    }
-
-    public SshPutTaskFactory contents(String contents) {
-        markDirty();
-        this.contents = Suppliers.ofInstance(KnownSizeInputStream.of(contents));  
-        return self();
-    }
-
-    public SshPutTaskFactory contents(byte[] contents) {
-        markDirty();
-        this.contents = Suppliers.ofInstance(KnownSizeInputStream.of(contents));  
-        return self();
-    }
-
-    public SshPutTaskFactory contents(InputStream stream) {
-        markDirty();
-        this.contents = Suppliers.ofInstance(stream);  
-        return self();
-    }
-
-    public SshPutTaskFactory contents(Reader reader) {
-        markDirty();
-        this.contents = Suppliers.ofInstance(new ReaderInputStream(reader));  
-        return self();
-    }
-
-    public SshPutTaskFactory allowFailure() {
-        markDirty();
-        allowFailure = true;
-        return self();
-    }
-    
-    public SshPutTaskFactory createDirectory() {
-        markDirty();
-        createDirectory = true;
-        return self();
-    }
-    
-    public SshPutTaskWrapper newTask() {
-        dirty = false;
-        return new SshPutTaskWrapper(this);
-    }
-
-    @Override
-    protected void finalize() throws Throwable {
-        // help let people know of API usage error
-        if (dirty)
-            log.warn("Task "+this+" was modified but modification was never used");
-        super.finalize();
-    }
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/a4c0e5fd/core/src/main/java/brooklyn/util/task/ssh/SshPutTaskStub.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/util/task/ssh/SshPutTaskStub.java b/core/src/main/java/brooklyn/util/task/ssh/SshPutTaskStub.java
deleted file mode 100644
index 185e819..0000000
--- a/core/src/main/java/brooklyn/util/task/ssh/SshPutTaskStub.java
+++ /dev/null
@@ -1,69 +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.util.task.ssh;
-
-import java.io.InputStream;
-
-import org.apache.brooklyn.location.basic.SshMachineLocation;
-import brooklyn.util.config.ConfigBag;
-
-import com.google.common.base.Supplier;
-
-public class SshPutTaskStub {
-
-    protected String remoteFile;
-    protected SshMachineLocation machine;
-    protected Supplier<? extends InputStream> contents;
-    protected String summary;
-    protected String permissions;
-    protected boolean allowFailure = false;
-    protected boolean createDirectory = false;
-    protected final ConfigBag config = ConfigBag.newInstance();
-
-    protected SshPutTaskStub() {
-    }
-    
-    protected SshPutTaskStub(SshPutTaskStub constructor) {
-        this.remoteFile = constructor.remoteFile;
-        this.machine = constructor.machine;
-        this.contents = constructor.contents;
-        this.summary = constructor.summary;
-        this.allowFailure = constructor.allowFailure;
-        this.createDirectory = constructor.createDirectory;
-        this.permissions = constructor.permissions;
-        this.config.copy(constructor.config);
-    }
-
-    public String getRemoteFile() {
-        return remoteFile;
-    }
-    
-    public String getSummary() {
-        if (summary!=null) return summary;
-        return "scp put: "+remoteFile;
-    }
-
-    public SshMachineLocation getMachine() {
-        return machine;
-    }
-    
-    protected ConfigBag getConfig() {
-        return config;
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/a4c0e5fd/core/src/main/java/brooklyn/util/task/ssh/SshPutTaskWrapper.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/util/task/ssh/SshPutTaskWrapper.java b/core/src/main/java/brooklyn/util/task/ssh/SshPutTaskWrapper.java
deleted file mode 100644
index 4f0cd76..0000000
--- a/core/src/main/java/brooklyn/util/task/ssh/SshPutTaskWrapper.java
+++ /dev/null
@@ -1,190 +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.util.task.ssh;
-
-import java.util.Arrays;
-import java.util.concurrent.Callable;
-
-import org.apache.brooklyn.api.management.Task;
-import org.apache.brooklyn.api.management.TaskWrapper;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import brooklyn.util.config.ConfigBag;
-import brooklyn.util.internal.ssh.SshTool;
-import brooklyn.util.task.TaskBuilder;
-import brooklyn.util.task.Tasks;
-import brooklyn.util.task.system.ProcessTaskWrapper;
-
-import com.google.common.annotations.Beta;
-import com.google.common.base.Preconditions;
-
-/** As {@link ProcessTaskWrapper}, but putting a file on the remote machine */
-@Beta
-public class SshPutTaskWrapper extends SshPutTaskStub implements TaskWrapper<Void> {
-
-    private static final Logger log = LoggerFactory.getLogger(SshPutTaskWrapper.class);
-    
-    private final Task<Void> task;
-
-    protected Integer exitCodeOfCopy = null;
-    protected Exception exception = null;
-    protected boolean successful = false;
-    
-    // package private as only AbstractSshTaskFactory should invoke
-    SshPutTaskWrapper(SshPutTaskFactory constructor) {
-        super(constructor);
-        TaskBuilder<Void> tb = TaskBuilder.<Void>builder().dynamic(false).name(getSummary());
-        task = tb.body(new SshPutJob()).build();
-    }
-    
-    @Override
-    public Task<Void> asTask() {
-        return getTask();
-    }
-    
-    @Override
-    public Task<Void> getTask() {
-        return task;
-    }
-        
-    // TODO:
-    //   verify
-    //   copyAsRoot
-    //   owner
-    //   lastModificationDate - see {@link #PROP_LAST_MODIFICATION_DATE}; not supported by all SshTool implementations
-    //   lastAccessDate - see {@link #PROP_LAST_ACCESS_DATE}; not supported by all SshTool implementations
-
-    private class SshPutJob implements Callable<Void> {
-        @Override
-        public Void call() throws Exception {
-            try {
-                Preconditions.checkNotNull(getMachine(), "machine");
-                
-                String remoteFile = getRemoteFile();
-
-                if (createDirectory) {
-                    String remoteDir = remoteFile;
-                    int exitCodeOfCreate = -1;
-                    try {
-                        int li = remoteDir.lastIndexOf("/");
-                        if (li>=0) {
-                            remoteDir = remoteDir.substring(0, li+1);
-                            exitCodeOfCreate = getMachine().execCommands("creating directory for "+getSummary(), 
-                                    Arrays.asList("mkdir -p "+remoteDir));
-                        } else {
-                            // nothing to create
-                            exitCodeOfCreate = 0;
-                        }
-                    } catch (Exception e) {
-                        if (log.isDebugEnabled())
-                            log.debug("SSH put "+getRemoteFile()+" (create dir, in task "+getSummary()+") to "+getMachine()+" threw exception: "+e);
-                        exception = e;
-                    }
-                    if (exception!=null || !((Integer)0).equals(exitCodeOfCreate)) {
-                        if (!allowFailure) {
-                            if (exception != null) {
-                                throw new IllegalStateException(getSummary()+" (creating dir "+remoteDir+" for SSH put task) ended with exception, in "+Tasks.current()+": "+exception, exception);
-                            }
-                            if (exitCodeOfCreate!=0) {
-                                exception = new IllegalStateException(getSummary()+" (creating dir "+remoteDir+" SSH put task) ended with exit code "+exitCodeOfCreate+", in "+Tasks.current());
-                                throw exception;
-                            }
-                        }
-                        // not successful, but allowed
-                        return null;
-                    }
-                }
-                
-                ConfigBag config = ConfigBag.newInstanceCopying(getConfig());
-                if (permissions!=null) config.put(SshTool.PROP_PERMISSIONS, permissions);
-                
-                exitCodeOfCopy = getMachine().copyTo(config.getAllConfig(), contents.get(), remoteFile);
-
-                if (log.isDebugEnabled())
-                    log.debug("SSH put "+getRemoteFile()+" (task "+getSummary()+") to "+getMachine()+" completed with exit code "+exitCodeOfCopy);
-            } catch (Exception e) {
-                if (log.isDebugEnabled())
-                    log.debug("SSH put "+getRemoteFile()+" (task "+getSummary()+") to "+getMachine()+" threw exception: "+e);
-                exception = e;
-            }
-            
-            if (exception!=null || !((Integer)0).equals(exitCodeOfCopy)) {
-                if (!allowFailure) {
-                    if (exception != null) {
-                        throw new IllegalStateException(getSummary()+" (SSH put task) ended with exception, in "+Tasks.current()+": "+exception, exception);
-                    }
-                    if (exitCodeOfCopy!=0) {
-                        exception = new IllegalStateException(getSummary()+" (SSH put task) ended with exit code "+exitCodeOfCopy+", in "+Tasks.current());
-                        throw exception;
-                    }
-                }
-                // not successful, but allowed
-                return null;
-            }
-            
-            // TODO verify
-
-            successful = (exception==null && ((Integer)0).equals(exitCodeOfCopy));
-            return null;
-        }
-    }
-    
-    @Override
-    public String toString() {
-        return super.toString()+"["+task+"]";
-    }
-
-    /** blocks, throwing if there was an exception */
-    public Void get() {
-        return getTask().getUnchecked();
-    }
-    
-    /** returns the exit code from the copy, 0 on success; 
-     * null if it has not completed or threw exception
-     * (not sure if this is ever a non-zero integer or if it is meaningful)
-     * <p>
-     * most callers will want the simpler {@link #isSuccessful()} */
-    public Integer getExitCode() {
-        return exitCodeOfCopy;
-    }
-    
-    /** returns any exception encountered in the operation */
-    public Exception getException() {
-        return exception;
-    }
-    
-    /** blocks until the task completes; does not throw */
-    public SshPutTaskWrapper block() {
-        getTask().blockUntilEnded();
-        return this;
-    }
- 
-    /** true iff the ssh job has completed (with or without failure) */
-    public boolean isDone() {
-        return getTask().isDone();
-    }
-
-    /** true iff the scp has completed successfully; guaranteed to be set before {@link #isDone()} or {@link #block()} are satisfied */
-    public boolean isSuccessful() {
-        return successful;
-    }
-    
-
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/a4c0e5fd/core/src/main/java/brooklyn/util/task/ssh/SshTasks.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/util/task/ssh/SshTasks.java b/core/src/main/java/brooklyn/util/task/ssh/SshTasks.java
deleted file mode 100644
index 9f6fbb9..0000000
--- a/core/src/main/java/brooklyn/util/task/ssh/SshTasks.java
+++ /dev/null
@@ -1,236 +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.util.task.ssh;
-
-import java.util.Map;
-
-import javax.annotation.Nullable;
-
-import org.apache.brooklyn.api.entity.Entity;
-import org.apache.brooklyn.api.location.Location;
-import org.apache.brooklyn.api.management.ManagementContext;
-import org.apache.brooklyn.api.management.Task;
-import org.apache.brooklyn.api.management.TaskAdaptable;
-import org.apache.brooklyn.api.management.TaskFactory;
-import org.apache.brooklyn.api.management.TaskQueueingContext;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import brooklyn.config.ConfigKey;
-import brooklyn.config.ConfigUtils;
-import brooklyn.entity.basic.BrooklynTaskTags;
-import brooklyn.entity.basic.ConfigKeys;
-
-import org.apache.brooklyn.location.basic.AbstractLocation;
-import org.apache.brooklyn.location.basic.LocationInternal;
-import org.apache.brooklyn.location.basic.SshMachineLocation;
-
-import brooklyn.util.ResourceUtils;
-import brooklyn.util.config.ConfigBag;
-import brooklyn.util.internal.ssh.SshTool;
-import brooklyn.util.net.Urls;
-import brooklyn.util.ssh.BashCommands;
-import brooklyn.util.stream.Streams;
-import brooklyn.util.task.DynamicTasks;
-import brooklyn.util.task.Tasks;
-import brooklyn.util.task.ssh.internal.PlainSshExecTaskFactory;
-import brooklyn.util.task.system.ProcessTaskFactory;
-import brooklyn.util.task.system.ProcessTaskWrapper;
-import brooklyn.util.text.Identifiers;
-import brooklyn.util.text.Strings;
-
-import com.google.common.annotations.Beta;
-import com.google.common.base.Function;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.Maps;
-
-/**
- * Conveniences for generating {@link Task} instances to perform SSH activities on an {@link SshMachineLocation}.
- * <p>
- * To infer the {@link SshMachineLocation} and take properties from entities and global management context the
- * {@link SshEffectorTasks} should be preferred over this class.
- *  
- * @see SshEffectorTasks
- * @since 0.6.0
- */
-@Beta
-public class SshTasks {
-
-    private static final Logger log = LoggerFactory.getLogger(SshTasks.class);
-        
-    public static ProcessTaskFactory<Integer> newSshExecTaskFactory(SshMachineLocation machine, String ...commands) {
-        return newSshExecTaskFactory(machine, true, commands);
-    }
-    
-    public static ProcessTaskFactory<Integer> newSshExecTaskFactory(SshMachineLocation machine, final boolean useMachineConfig, String ...commands) {
-        return new PlainSshExecTaskFactory<Integer>(machine, commands) {
-            {
-                if (useMachineConfig)
-                    config.putIfAbsent(getSshFlags(machine));
-            }
-        };
-    }
-
-    public static SshPutTaskFactory newSshPutTaskFactory(SshMachineLocation machine, String remoteFile) {
-        return newSshPutTaskFactory(machine, true, remoteFile);
-    }
-    
-    public static SshPutTaskFactory newSshPutTaskFactory(SshMachineLocation machine, final boolean useMachineConfig, String remoteFile) {
-        return new SshPutTaskFactory(machine, remoteFile) {
-            {
-                if (useMachineConfig)
-                    config.putIfAbsent(getSshFlags(machine));
-            }
-        };
-    }
-
-    public static SshFetchTaskFactory newSshFetchTaskFactory(SshMachineLocation machine, String remoteFile) {
-        return newSshFetchTaskFactory(machine, true, remoteFile);
-    }
-    
-    public static SshFetchTaskFactory newSshFetchTaskFactory(SshMachineLocation machine, final boolean useMachineConfig, String remoteFile) {
-        return new SshFetchTaskFactory(machine, remoteFile) {
-            {
-                if (useMachineConfig)
-                    config.putIfAbsent(getSshFlags(machine));
-            }
-        };
-    }
-
-    private static Map<String, Object> getSshFlags(Location location) {
-        ConfigBag allConfig = ConfigBag.newInstance();
-        
-        if (location instanceof AbstractLocation) {
-            ManagementContext mgmt = ((AbstractLocation)location).getManagementContext();
-            if (mgmt!=null)
-                allConfig.putAll(mgmt.getConfig().getAllConfig());
-        }
-        
-        allConfig.putAll(((LocationInternal)location).config().getBag());
-        
-        Map<String, Object> result = Maps.newLinkedHashMap();
-        for (String keyS : allConfig.getAllConfig().keySet()) {
-            ConfigKey<?> key = ConfigKeys.newConfigKey(Object.class, keyS);
-            if (key.getName().startsWith(SshTool.BROOKLYN_CONFIG_KEY_PREFIX)) {
-                result.put(ConfigUtils.unprefixedKey(SshTool.BROOKLYN_CONFIG_KEY_PREFIX, key).getName(), allConfig.get(key));
-            }
-        }
-        return result;
-    }
-
-    @Beta
-    public static enum OnFailingTask { 
-        FAIL,
-        /** issues a warning, sometimes implemented as marking the task inessential and failing it if it appears
-         * we are in a dynamic {@link TaskQueueingContext};
-         * useful because this way the warning appears to the user;
-         * but note that the check is done against the calling thread so use with some care
-         * (and thus this enum is currently here rather then elsewhere) */
-        WARN_OR_IF_DYNAMIC_FAIL_MARKING_INESSENTIAL,
-        /** issues a warning in the log if the task fails, otherwise swallows it */
-        WARN_IN_LOG_ONLY, 
-        /** not even a warning if the task fails (the caller is expected to handle it as appropriate) */
-        IGNORE }
-    
-    public static ProcessTaskFactory<Boolean> dontRequireTtyForSudo(SshMachineLocation machine, final boolean failIfCantSudo) {
-        return dontRequireTtyForSudo(machine, failIfCantSudo ? OnFailingTask.FAIL : OnFailingTask.WARN_IN_LOG_ONLY);
-    }
-    /** creates a task which returns modifies sudoers to ensure non-tty access is permitted;
-     * also gives nice warnings if sudo is not permitted */
-    public static ProcessTaskFactory<Boolean> dontRequireTtyForSudo(SshMachineLocation machine, OnFailingTask onFailingTaskRequested) {
-        final OnFailingTask onFailingTask;
-        if (onFailingTaskRequested==OnFailingTask.WARN_OR_IF_DYNAMIC_FAIL_MARKING_INESSENTIAL) {
-            if (DynamicTasks.getTaskQueuingContext()!=null)
-                onFailingTask = onFailingTaskRequested;
-            else
-                onFailingTask = OnFailingTask.WARN_IN_LOG_ONLY;
-        } else {
-            onFailingTask = onFailingTaskRequested;
-        }
-        
-        final String id = Identifiers.makeRandomId(6);
-        return newSshExecTaskFactory(machine, 
-                BashCommands.dontRequireTtyForSudo(),
-                // strange quotes are to ensure we don't match against echoed stdin
-                BashCommands.sudo("echo \"sudo\"-is-working-"+id))
-            .summary("setting up sudo")
-            .configure(SshTool.PROP_ALLOCATE_PTY, true)
-            .allowingNonZeroExitCode()
-            .returning(new Function<ProcessTaskWrapper<?>,Boolean>() { public Boolean apply(ProcessTaskWrapper<?> task) {
-                if (task.getExitCode()==0 && task.getStdout().contains("sudo-is-working-"+id)) return true;
-                Entity entity = BrooklynTaskTags.getTargetOrContextEntity(Tasks.current());
-                
-                
-                if (onFailingTask!=OnFailingTask.IGNORE) {
-                    // TODO if in a queueing context can we mark this task inessential and throw?
-                    // that way user sees the message...
-                    String message = "Error setting up sudo for "+task.getMachine().getUser()+"@"+task.getMachine().getAddress().getHostName()+" "+
-                        " (exit code "+task.getExitCode()+(entity!=null ? ", entity "+entity : "")+")";
-                    DynamicTasks.queueIfPossible(Tasks.warning(message, null));
-                }
-                Streams.logStreamTail(log, "STDERR of sudo setup problem", Streams.byteArrayOfString(task.getStderr()), 1024);
-                
-                if (onFailingTask==OnFailingTask.WARN_OR_IF_DYNAMIC_FAIL_MARKING_INESSENTIAL) {
-                    Tasks.markInessential();
-                }
-                if (onFailingTask==OnFailingTask.FAIL || onFailingTask==OnFailingTask.WARN_OR_IF_DYNAMIC_FAIL_MARKING_INESSENTIAL) {
-                    throw new IllegalStateException("Passwordless sudo is required for "+task.getMachine().getUser()+"@"+task.getMachine().getAddress().getHostName()+
-                            (entity!=null ? " ("+entity+")" : ""));
-                }
-                return false; 
-            } });
-    }
-
-    /** Function for use in {@link ProcessTaskFactory#returning(Function)} which logs all information, optionally requires zero exit code, 
-     * and then returns stdout */
-    public static Function<ProcessTaskWrapper<?>, String> returningStdoutLoggingInfo(final Logger logger, final boolean requireZero) {
-        return new Function<ProcessTaskWrapper<?>, String>() {
-          public String apply(@Nullable ProcessTaskWrapper<?> input) {
-            if (logger!=null) logger.info(input+" COMMANDS:\n"+Strings.join(input.getCommands(),"\n"));
-            if (logger!=null) logger.info(input+" STDOUT:\n"+input.getStdout());
-            if (logger!=null) logger.info(input+" STDERR:\n"+input.getStderr());
-            if (requireZero && input.getExitCode()!=0) 
-                throw new IllegalStateException("non-zero exit code in "+input.getSummary()+": see log for more details!");
-            return input.getStdout();
-          }
-        };
-    }
-
-    /** task to install a file given a url, where the url is resolved remotely first then locally */
-    public static TaskFactory<?> installFromUrl(final SshMachineLocation location, final String url, final String destPath) {
-        return installFromUrl(ResourceUtils.create(SshTasks.class), ImmutableMap.<String,Object>of(), location, url, destPath);
-    }
-    /** task to install a file given a url, where the url is resolved remotely first then locally */
-    public static TaskFactory<?> installFromUrl(final ResourceUtils utils, final Map<String, ?> props, final SshMachineLocation location, final String url, final String destPath) {
-        return new TaskFactory<TaskAdaptable<?>>() {
-            @Override
-            public TaskAdaptable<?> newTask() {
-                return Tasks.<Void>builder().name("installing "+Urls.getBasename(url)).description("installing "+url+" to "+destPath).body(new Runnable() {
-                    @Override
-                    public void run() {
-                        int result = location.installTo(utils, props, url, destPath);
-                        if (result!=0) 
-                            throw new IllegalStateException("Failed to install '"+url+"' to '"+destPath+"' at "+location+": exit code "+result);
-                    }
-                }).build();
-            }
-        };
-    }
-    
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/a4c0e5fd/core/src/main/java/brooklyn/util/task/ssh/internal/AbstractSshExecTaskFactory.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/util/task/ssh/internal/AbstractSshExecTaskFactory.java b/core/src/main/java/brooklyn/util/task/ssh/internal/AbstractSshExecTaskFactory.java
deleted file mode 100644
index 86764f3..0000000
--- a/core/src/main/java/brooklyn/util/task/ssh/internal/AbstractSshExecTaskFactory.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 brooklyn.util.task.ssh.internal;
-
-import com.google.common.base.Preconditions;
-
-import org.apache.brooklyn.location.basic.SshMachineLocation;
-import brooklyn.util.config.ConfigBag;
-import brooklyn.util.task.system.ProcessTaskFactory;
-import brooklyn.util.task.system.ProcessTaskWrapper;
-import brooklyn.util.task.system.internal.AbstractProcessTaskFactory;
-
-// cannot be (cleanly) instantiated due to nested generic self-referential type; however trivial subclasses do allow it 
-public abstract class AbstractSshExecTaskFactory<T extends AbstractProcessTaskFactory<T,RET>,RET> extends AbstractProcessTaskFactory<T,RET> implements ProcessTaskFactory<RET> {
-    
-    /** constructor where machine will be added later */
-    public AbstractSshExecTaskFactory(String ...commands) {
-        super(commands);
-    }
-
-    /** convenience constructor to supply machine immediately */
-    public AbstractSshExecTaskFactory(SshMachineLocation machine, String ...commands) {
-        this(commands);
-        machine(machine);
-    }
-    
-    @Override
-    public ProcessTaskWrapper<RET> newTask() {
-        dirty = false;
-        return new ProcessTaskWrapper<RET>(this) {
-            protected void run(ConfigBag config) {
-                Preconditions.checkNotNull(getMachine(), "machine");
-                if (Boolean.FALSE.equals(this.runAsScript)) {
-                    this.exitCode = getMachine().execCommands(config.getAllConfig(), getSummary(), commands, shellEnvironment);
-                } else { // runScript = null or TRUE
-                    this.exitCode = getMachine().execScript(config.getAllConfig(), getSummary(), commands, shellEnvironment);
-                }
-            }
-            protected String taskTypeShortName() { return "SSH"; }
-        };
-    }
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/a4c0e5fd/core/src/main/java/brooklyn/util/task/ssh/internal/PlainSshExecTaskFactory.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/util/task/ssh/internal/PlainSshExecTaskFactory.java b/core/src/main/java/brooklyn/util/task/ssh/internal/PlainSshExecTaskFactory.java
deleted file mode 100644
index efc14db..0000000
--- a/core/src/main/java/brooklyn/util/task/ssh/internal/PlainSshExecTaskFactory.java
+++ /dev/null
@@ -1,71 +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.util.task.ssh.internal;
-
-import java.util.List;
-
-import org.apache.brooklyn.location.basic.SshMachineLocation;
-import brooklyn.util.task.system.ProcessTaskWrapper;
-
-import com.google.common.base.Function;
-
-/** the "Plain" class exists purely so we can massage return types for callers' convenience */
-public class PlainSshExecTaskFactory<RET> extends AbstractSshExecTaskFactory<PlainSshExecTaskFactory<RET>,RET> {
-    /** constructor where machine will be added later */
-    public PlainSshExecTaskFactory(String ...commands) {
-        super(commands);
-    }
-
-    /** convenience constructor to supply machine immediately */
-    public PlainSshExecTaskFactory(SshMachineLocation machine, String ...commands) {
-        this(commands);
-        machine(machine);
-    }
-
-    /** Constructor where machine will be added later */
-    public PlainSshExecTaskFactory(List<String> commands) {
-        this(commands.toArray(new String[commands.size()]));
-    }
-
-    /** Convenience constructor to supply machine immediately */
-    public PlainSshExecTaskFactory(SshMachineLocation machine, List<String> commands) {
-        this(machine, commands.toArray(new String[commands.size()]));
-    }
-
-    @Override
-    public <T2> PlainSshExecTaskFactory<T2> returning(ScriptReturnType type) {
-        return (PlainSshExecTaskFactory<T2>) super.<T2>returning(type);
-    }
-
-    @Override
-    public <RET2> PlainSshExecTaskFactory<RET2> returning(Function<ProcessTaskWrapper<?>, RET2> resultTransformation) {
-        return (PlainSshExecTaskFactory<RET2>) super.returning(resultTransformation);
-    }
-    
-    @Override
-    public PlainSshExecTaskFactory<Boolean> returningIsExitCodeZero() {
-        return (PlainSshExecTaskFactory<Boolean>) super.returningIsExitCodeZero();
-    }
-    
-    @Override
-    public PlainSshExecTaskFactory<String> requiringZeroAndReturningStdout() {
-        return (PlainSshExecTaskFactory<String>) super.requiringZeroAndReturningStdout();
-    }
-    
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/a4c0e5fd/core/src/main/java/brooklyn/util/task/system/ProcessTaskFactory.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/util/task/system/ProcessTaskFactory.java b/core/src/main/java/brooklyn/util/task/system/ProcessTaskFactory.java
deleted file mode 100644
index 407111c..0000000
--- a/core/src/main/java/brooklyn/util/task/system/ProcessTaskFactory.java
+++ /dev/null
@@ -1,65 +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.util.task.system;
-
-import java.util.Map;
-
-import org.apache.brooklyn.api.management.TaskFactory;
-
-import brooklyn.config.ConfigKey;
-import org.apache.brooklyn.location.basic.SshMachineLocation;
-import brooklyn.util.internal.ssh.SshTool;
-import brooklyn.util.task.system.ProcessTaskStub.ScriptReturnType;
-
-import com.google.common.annotations.Beta;
-import com.google.common.base.Function;
-
-public interface ProcessTaskFactory<T> extends TaskFactory<ProcessTaskWrapper<T>> {
-    public ProcessTaskFactory<T> machine(SshMachineLocation machine);
-    public ProcessTaskFactory<T> add(String ...commandsToAdd);
-    public ProcessTaskFactory<T> add(Iterable<String> commandsToAdd);
-    public ProcessTaskFactory<T> requiringExitCodeZero();
-    public ProcessTaskFactory<T> requiringExitCodeZero(String extraErrorMessage);
-    public ProcessTaskFactory<T> allowingNonZeroExitCode();
-    public ProcessTaskFactory<String> requiringZeroAndReturningStdout();
-    public ProcessTaskFactory<Boolean> returningIsExitCodeZero();
-    public <RET2> ProcessTaskFactory<RET2> returning(ScriptReturnType type);
-    public <RET2> ProcessTaskFactory<RET2> returning(Function<ProcessTaskWrapper<?>, RET2> resultTransformation);
-    public ProcessTaskFactory<T> runAsCommand();
-    public ProcessTaskFactory<T> runAsScript();
-    public ProcessTaskFactory<T> runAsRoot();
-    public ProcessTaskFactory<T> environmentVariable(String key, String val);
-    public ProcessTaskFactory<T> environmentVariables(Map<String,String> vars);
-    public ProcessTaskFactory<T> summary(String summary);
-    
-    /** allows setting config-key based properties for specific underlying tools */
-    @Beta
-    public <V> ProcessTaskFactory<T> configure(ConfigKey<V> key, V value);
-
-    /** allows setting config-key/flag based properties for specific underlying tools;
-     * but note that if any are prefixed with {@link SshTool#BROOKLYN_CONFIG_KEY_PREFIX}
-     * these should normally be filtered out */
-    @Beta
-    public ProcessTaskFactory<T> configure(Map<?,?> flags);
-
-    /** adds a listener which will be notified of (otherwise) successful completion,
-     * typically used to invalidate the result (ie throw exception, to promote a string in the output to an exception);
-     * invoked even if return code is zero, so a better error can be thrown */
-    public ProcessTaskFactory<T> addCompletionListener(Function<ProcessTaskWrapper<?>, Void> function);
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/a4c0e5fd/core/src/main/java/brooklyn/util/task/system/ProcessTaskStub.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/util/task/system/ProcessTaskStub.java b/core/src/main/java/brooklyn/util/task/system/ProcessTaskStub.java
deleted file mode 100644
index df37691..0000000
--- a/core/src/main/java/brooklyn/util/task/system/ProcessTaskStub.java
+++ /dev/null
@@ -1,101 +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.util.task.system;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.brooklyn.location.basic.SshMachineLocation;
-import brooklyn.util.collections.MutableMap;
-import brooklyn.util.config.ConfigBag;
-import brooklyn.util.text.Strings;
-
-import com.google.common.base.Function;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-
-public class ProcessTaskStub {
-    
-    protected final List<String> commands = new ArrayList<String>();
-    /** null for localhost */
-    protected SshMachineLocation machine;
-    
-    // config data
-    protected String summary;
-    protected final ConfigBag config = ConfigBag.newInstance();
-    
-    public static enum ScriptReturnType { CUSTOM, EXIT_CODE, STDOUT_STRING, STDOUT_BYTES, STDERR_STRING, STDERR_BYTES }
-    protected Function<ProcessTaskWrapper<?>, ?> returnResultTransformation = null;
-    protected ScriptReturnType returnType = ScriptReturnType.EXIT_CODE;
-    
-    protected Boolean runAsScript = null;
-    protected boolean runAsRoot = false;
-    protected Boolean requireExitCodeZero = null;
-    protected String extraErrorMessage = null;
-    protected Map<String,String> shellEnvironment = new MutableMap<String, String>();
-    protected final List<Function<ProcessTaskWrapper<?>, Void>> completionListeners = new ArrayList<Function<ProcessTaskWrapper<?>,Void>>();
-
-    public ProcessTaskStub() {}
-    
-    protected ProcessTaskStub(ProcessTaskStub source) {
-        commands.addAll(source.getCommands());
-        machine = source.getMachine();
-        summary = source.getSummary();
-        config.copy(source.getConfig());
-        returnResultTransformation = source.returnResultTransformation;
-        returnType = source.returnType;
-        runAsScript = source.runAsScript;
-        runAsRoot = source.runAsRoot;
-        requireExitCodeZero = source.requireExitCodeZero;
-        extraErrorMessage = source.extraErrorMessage;
-        shellEnvironment.putAll(source.getShellEnvironment());
-        completionListeners.addAll(source.getCompletionListeners());
-    }
-
-    public String getSummary() {
-        if (summary!=null) return summary;
-        return Strings.maxlen(Strings.join(commands, " ; "), 160);
-    }
-    
-    /** null for localhost */
-    public SshMachineLocation getMachine() {
-        return machine;
-    }
-    
-    public Map<String, String> getShellEnvironment() {
-        return ImmutableMap.copyOf(shellEnvironment);
-    }
- 
-    @Override
-    public String toString() {
-        return super.toString()+"["+getSummary()+"]";
-    }
-
-    public List<String> getCommands() {
-        return ImmutableList.copyOf(commands);
-    }
- 
-    public List<Function<ProcessTaskWrapper<?>, Void>> getCompletionListeners() {
-        return completionListeners;
-    }
-
-    protected ConfigBag getConfig() { return config; }
-    
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/a4c0e5fd/core/src/main/java/brooklyn/util/task/system/ProcessTaskWrapper.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/util/task/system/ProcessTaskWrapper.java b/core/src/main/java/brooklyn/util/task/system/ProcessTaskWrapper.java
deleted file mode 100644
index 5c18fdd..0000000
--- a/core/src/main/java/brooklyn/util/task/system/ProcessTaskWrapper.java
+++ /dev/null
@@ -1,187 +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.util.task.system;
-
-import java.io.ByteArrayOutputStream;
-import java.util.concurrent.Callable;
-
-import org.apache.brooklyn.api.management.Task;
-import org.apache.brooklyn.api.management.TaskWrapper;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import brooklyn.entity.basic.BrooklynTaskTags;
-import brooklyn.util.config.ConfigBag;
-import brooklyn.util.internal.ssh.ShellTool;
-import brooklyn.util.stream.Streams;
-import brooklyn.util.task.TaskBuilder;
-import brooklyn.util.task.Tasks;
-import brooklyn.util.task.system.internal.AbstractProcessTaskFactory;
-import brooklyn.util.text.Strings;
-
-import com.google.common.base.Function;
-
-/** Wraps a fully constructed process task, and allows callers to inspect status. 
- * Note that methods in here such as {@link #getStdout()} will return partially completed streams while the task is ongoing
- * (and exit code will be null). You can {@link #block()} or {@link #get()} as conveniences on the underlying {@link #getTask()}. */ 
-public abstract class ProcessTaskWrapper<RET> extends ProcessTaskStub implements TaskWrapper<RET> {
-
-    private static final Logger log = LoggerFactory.getLogger(ProcessTaskWrapper.class);
-    
-    private final Task<RET> task;
-
-    // execution details
-    protected ByteArrayOutputStream stdout = new ByteArrayOutputStream();
-    protected ByteArrayOutputStream stderr = new ByteArrayOutputStream();
-    protected Integer exitCode = null;
-    
-    @SuppressWarnings("unchecked")
-    protected ProcessTaskWrapper(AbstractProcessTaskFactory<?,RET> constructor) {
-        super(constructor);
-        TaskBuilder<Object> tb = constructor.constructCustomizedTaskBuilder();
-        if (stdout!=null) tb.tag(BrooklynTaskTags.tagForStreamSoft(BrooklynTaskTags.STREAM_STDOUT, stdout));
-        if (stderr!=null) tb.tag(BrooklynTaskTags.tagForStreamSoft(BrooklynTaskTags.STREAM_STDERR, stderr));
-        task = (Task<RET>) tb.body(new ProcessTaskInternalJob()).build();
-    }
-    
-    @Override
-    public Task<RET> asTask() {
-        return getTask();
-    }
-    
-    @Override
-    public Task<RET> getTask() {
-        return task;
-    }
-    
-    public Integer getExitCode() {
-        return exitCode;
-    }
-    
-    public byte[] getStdoutBytes() {
-        if (stdout==null) return null;
-        return stdout.toByteArray();
-    }
-    
-    public byte[] getStderrBytes() {
-        if (stderr==null) return null;
-        return stderr.toByteArray();
-    }
-    
-    public String getStdout() {
-        if (stdout==null) return null;
-        return stdout.toString();
-    }
-    
-    public String getStderr() {
-        if (stderr==null) return null;
-        return stderr.toString();
-    }
-
-    protected class ProcessTaskInternalJob implements Callable<Object> {
-        @Override
-        public Object call() throws Exception {
-            run( getConfigForRunning() );
-            
-            for (Function<ProcessTaskWrapper<?>, Void> listener: completionListeners) {
-                try {
-                    listener.apply(ProcessTaskWrapper.this);
-                } catch (Exception e) {
-                    logWithDetailsAndThrow("Error in "+taskTypeShortName()+" task "+getSummary()+": "+e, e);                    
-                }
-            }
-            
-            if (exitCode!=0 && !Boolean.FALSE.equals(requireExitCodeZero)) {
-                if (Boolean.TRUE.equals(requireExitCodeZero)) {
-                    logWithDetailsAndThrow(taskTypeShortName()+" task ended with exit code "+exitCode+" when 0 was required, in "+Tasks.current()+": "+getSummary(), null);
-                } else {
-                    // warn, but allow, on non-zero not explicitly allowed
-                    log.warn(taskTypeShortName()+" task ended with exit code "+exitCode+" when non-zero was not explicitly allowed (error may be thrown in future), in "
-                            +Tasks.current()+": "+getSummary());
-                }
-            }
-            switch (returnType) {
-            case CUSTOM: return returnResultTransformation.apply(ProcessTaskWrapper.this);
-            case STDOUT_STRING: return stdout.toString();
-            case STDOUT_BYTES: return stdout.toByteArray();
-            case STDERR_STRING: return stderr.toString();
-            case STDERR_BYTES: return stderr.toByteArray();
-            case EXIT_CODE: return exitCode;
-            }
-
-            throw new IllegalStateException("Unknown return type for "+taskTypeShortName()+" job "+getSummary()+": "+returnType);
-        }
-
-        protected void logWithDetailsAndThrow(String message, Throwable optionalCause) {
-            message = (extraErrorMessage!=null ? extraErrorMessage+": " : "") + message;
-            log.warn(message+" (throwing)");
-            logProblemDetails("STDERR", stderr, 1024);
-            logProblemDetails("STDOUT", stdout, 1024);
-            logProblemDetails("STDIN", Streams.byteArrayOfString(Strings.join(commands,"\n")), 4096);
-            if (optionalCause!=null) throw new IllegalStateException(message, optionalCause);
-            throw new IllegalStateException(message);
-        }
-        
-        protected void logProblemDetails(String streamName, ByteArrayOutputStream stream, int max) {
-            Streams.logStreamTail(log, streamName+" for problem in "+Tasks.current(), stream, max);
-        }
-
-    }
-    
-    @Override
-    public String toString() {
-        return super.toString()+"["+task+"]";
-    }
-
-    /** blocks and gets the result, throwing if there was an exception */
-    public RET get() {
-        return getTask().getUnchecked();
-    }
-    
-    /** blocks until the task completes; does not throw */
-    public ProcessTaskWrapper<RET> block() {
-        getTask().blockUntilEnded();
-        return this;
-    }
- 
-    /** true iff the process has completed (with or without failure) */
-    public boolean isDone() {
-        return getTask().isDone();
-    }
-
-    /** for overriding */
-    protected ConfigBag getConfigForRunning() {
-        ConfigBag config = ConfigBag.newInstanceCopying(ProcessTaskWrapper.this.config);
-        if (stdout!=null) config.put(ShellTool.PROP_OUT_STREAM, stdout);
-        if (stderr!=null) config.put(ShellTool.PROP_ERR_STREAM, stderr);
-        
-        if (!config.containsKey(ShellTool.PROP_NO_EXTRA_OUTPUT))
-            // by default no extra output (so things like cat, etc work as expected)
-            config.put(ShellTool.PROP_NO_EXTRA_OUTPUT, true);
-
-        if (runAsRoot)
-            config.put(ShellTool.PROP_RUN_AS_ROOT, true);
-        return config;
-    }
-
-    protected abstract void run(ConfigBag config);
-    
-    protected abstract String taskTypeShortName();
-    
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/a4c0e5fd/core/src/main/java/brooklyn/util/task/system/SystemTasks.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/util/task/system/SystemTasks.java b/core/src/main/java/brooklyn/util/task/system/SystemTasks.java
deleted file mode 100644
index 8553935..0000000
--- a/core/src/main/java/brooklyn/util/task/system/SystemTasks.java
+++ /dev/null
@@ -1,29 +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.util.task.system;
-
-import brooklyn.util.task.system.internal.SystemProcessTaskFactory.ConcreteSystemProcessTaskFactory;
-
-public class SystemTasks {
-
-    public static ProcessTaskFactory<Integer> exec(String ...commands) {
-        return new ConcreteSystemProcessTaskFactory<Integer>(commands);
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/a4c0e5fd/core/src/main/java/brooklyn/util/task/system/internal/AbstractProcessTaskFactory.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/util/task/system/internal/AbstractProcessTaskFactory.java b/core/src/main/java/brooklyn/util/task/system/internal/AbstractProcessTaskFactory.java
deleted file mode 100644
index e41a9a9..0000000
--- a/core/src/main/java/brooklyn/util/task/system/internal/AbstractProcessTaskFactory.java
+++ /dev/null
@@ -1,214 +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.util.task.system.internal;
-
-import java.util.Arrays;
-import java.util.Map;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import brooklyn.config.ConfigKey;
-import brooklyn.entity.basic.BrooklynTaskTags;
-import org.apache.brooklyn.location.basic.SshMachineLocation;
-import brooklyn.util.stream.Streams;
-import brooklyn.util.task.TaskBuilder;
-import brooklyn.util.task.system.ProcessTaskFactory;
-import brooklyn.util.task.system.ProcessTaskStub;
-import brooklyn.util.task.system.ProcessTaskWrapper;
-import brooklyn.util.text.Strings;
-
-import com.google.common.base.Function;
-import com.google.common.base.Preconditions;
-import com.google.common.collect.Iterables;
-
-public abstract class AbstractProcessTaskFactory<T extends AbstractProcessTaskFactory<T,RET>,RET> extends ProcessTaskStub implements ProcessTaskFactory<RET> {
-    
-    private static final Logger log = LoggerFactory.getLogger(AbstractProcessTaskFactory.class);
-    
-    protected boolean dirty = false;
-    
-    public AbstractProcessTaskFactory(String ...commands) {
-        this.commands.addAll(Arrays.asList(commands));
-    }
-
-    @SuppressWarnings("unchecked")
-    protected T self() { return (T)this; }
-    
-    protected void markDirty() {
-        dirty = true;
-    }
-    
-    @Override
-    public T add(String ...commandsToAdd) {
-        markDirty();
-        for (String commandToAdd: commandsToAdd) this.commands.add(commandToAdd);
-        return self();
-    }
-
-    @Override
-    public T add(Iterable<String> commandsToAdd) {
-        Iterables.addAll(this.commands, commandsToAdd);
-        return self();
-    }
-    
-    @Override
-    public T machine(SshMachineLocation machine) {
-        markDirty();
-        this.machine = machine;
-        return self();
-    }
-
-    @Override
-    public T requiringExitCodeZero() {
-        markDirty();
-        requireExitCodeZero = true;
-        return self();
-    }
-    
-    @Override
-    public T requiringExitCodeZero(String extraErrorMessage) {
-        markDirty();
-        requireExitCodeZero = true;
-        this.extraErrorMessage = extraErrorMessage;
-        return self();
-    }
-    
-    @Override
-    public T allowingNonZeroExitCode() {
-        markDirty();
-        requireExitCodeZero = false;
-        return self();
-    }
-
-    @Override
-    public ProcessTaskFactory<Boolean> returningIsExitCodeZero() {
-        if (requireExitCodeZero==null) allowingNonZeroExitCode();
-        return returning(new Function<ProcessTaskWrapper<?>,Boolean>() {
-            public Boolean apply(ProcessTaskWrapper<?> input) {
-                return input.getExitCode()==0;
-            }
-        });
-    }
-
-    @Override
-    public ProcessTaskFactory<String> requiringZeroAndReturningStdout() {
-        requiringExitCodeZero();
-        return this.<String>returning(ScriptReturnType.STDOUT_STRING);
-    }
-
-    @Override
-    @SuppressWarnings("unchecked")
-    public <RET2> ProcessTaskFactory<RET2> returning(ScriptReturnType type) {
-        markDirty();
-        returnType = Preconditions.checkNotNull(type);
-        return (ProcessTaskFactory<RET2>) self();
-    }
-
-    @Override
-    @SuppressWarnings("unchecked")
-    public <RET2> ProcessTaskFactory<RET2> returning(Function<ProcessTaskWrapper<?>, RET2> resultTransformation) {
-        markDirty();
-        returnType = ScriptReturnType.CUSTOM;
-        this.returnResultTransformation = resultTransformation;
-        return (ProcessTaskFactory<RET2>) self();
-    }
-    
-    @Override
-    public T runAsCommand() {
-        markDirty();
-        runAsScript = false;
-        return self();
-    }
-
-    @Override
-    public T runAsScript() {
-        markDirty();
-        runAsScript = true;
-        return self();
-    }
-
-    @Override
-    public T runAsRoot() {
-        markDirty();
-        runAsRoot = true;
-        return self();
-    }
-    
-    @Override
-    public T environmentVariable(String key, String val) {
-        markDirty();
-        shellEnvironment.put(key, val);
-        return self();
-    }
-
-    @Override
-    public T environmentVariables(Map<String,String> vars) {
-        if (vars!=null) {
-            markDirty();
-            shellEnvironment.putAll(vars);
-        }
-        return self();
-    }
-
-    /** creates the TaskBuilder which can be further customized; typically invoked by the initial {@link #newTask()} */
-    public TaskBuilder<Object> constructCustomizedTaskBuilder() {
-        TaskBuilder<Object> tb = TaskBuilder.builder().dynamic(false).name("ssh: "+getSummary());
-        
-        tb.tag(BrooklynTaskTags.tagForStream(BrooklynTaskTags.STREAM_STDIN, 
-                Streams.byteArrayOfString(Strings.join(commands, "\n"))));
-        tb.tag(BrooklynTaskTags.tagForEnvStream(BrooklynTaskTags.STREAM_ENV, shellEnvironment));
-        
-        return tb;
-    }
-    
-    @Override
-    public T summary(String summary) {
-        markDirty();
-        this.summary = summary;
-        return self();
-    }
-
-    @Override
-    public <V> T configure(ConfigKey<V> key, V value) {
-        config.configure(key, value);
-        return self();
-    }
-    
-    @Override
-    public T configure(Map<?, ?> flags) {
-        if (flags!=null)
-            config.putAll(flags);
-        return self();
-    }
- 
-    @Override
-    public T addCompletionListener(Function<ProcessTaskWrapper<?>, Void> listener) {
-        completionListeners.add(listener);
-        return self();
-    }
-
-    @Override
-    protected void finalize() throws Throwable {
-        // help let people know of API usage error
-        if (dirty)
-            log.warn("Task "+this+" was modified but modification was never used");
-        super.finalize();
-    }
-}