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/18 17:03:31 UTC

[22/64] [abbrv] incubator-brooklyn git commit: BROOKLYN-162 - apply org.apache package prefix to utils-common

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/cf2f7a93/utils/common/src/main/java/brooklyn/util/ssh/BashCommands.java
----------------------------------------------------------------------
diff --git a/utils/common/src/main/java/brooklyn/util/ssh/BashCommands.java b/utils/common/src/main/java/brooklyn/util/ssh/BashCommands.java
deleted file mode 100644
index 570551d..0000000
--- a/utils/common/src/main/java/brooklyn/util/ssh/BashCommands.java
+++ /dev/null
@@ -1,712 +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.ssh;
-
-import static com.google.common.base.Preconditions.checkArgument;
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import static java.lang.String.format;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-
-import brooklyn.util.collections.MutableMap;
-import brooklyn.util.text.Identifiers;
-import brooklyn.util.text.StringEscapes.BashStringEscapes;
-import brooklyn.util.text.Strings;
-import brooklyn.util.time.Duration;
-
-import com.google.common.annotations.Beta;
-import com.google.common.base.Joiner;
-import com.google.common.base.Preconditions;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.Lists;
-
-public class BashCommands {
-
-    /**
-     * Returns a string for checking whether the given executable is available,
-     * and installing it if necessary.
-     * <p/>
-     * Uses {@link #installPackage} and accepts the same flags e.g. for apt, yum, rpm.
-     */
-    public static String installExecutable(Map<?,?> flags, String executable) {
-        return onlyIfExecutableMissing(executable, installPackage(flags, executable));
-    }
-
-    public static String installExecutable(String executable) {
-        return installExecutable(MutableMap.of(), executable);
-    }
-
-    /**
-     * Returns a command with all output redirected to /dev/null
-     */
-    public static String quiet(String command) {
-        return format("(%s > /dev/null 2>&1)", command);
-    }
-
-    /**
-     * Returns a command that always exits successfully
-     */
-    public static String ok(String command) {
-        return String.format("(%s || true)", command);
-    }
-
-    /**
-     * Returns a command for safely running as root, using {@code sudo}.
-     * <p/>
-     * Ensuring non-blocking if password not set by using 
-     * {@code -n} which means to exit if password required
-     * (this is unsupported in Ubuntu 8 but all modern OS's seem okay with this!),
-     * and (perhaps unnecessarily ?)
-     * {@code -S} which reads from stdin (routed to {@code /dev/null}, it was claimed here previously, though I'm not sure?).
-     * <p/>
-     * Also specify {@code -E} to pass the parent environment in.
-     * <p/> 
-     * If already root, simply runs the command, wrapped in brackets in case it is backgrounded.
-     * <p/>
-     * The command is not quoted or escaped in any ways. 
-     * If you are doing privileged redirect you may need to pass e.g. "bash -c 'echo hi > file'".
-     * <p/>
-     * If null is supplied, it is returned (sometimes used to indicate no command desired).
-     */
-    public static String sudo(String command) {
-        if (command.startsWith("( ") || command.endsWith(" &"))
-            return sudoNew(command);
-        else
-            return sudoOld(command);
-    }
-
-    // TODO would like to move away from sudoOld -- but needs extensive testing!
-    
-    private static String sudoOld(String command) {
-        if (command==null) return null;
-        // some OS's (which?) fail if you try running sudo when you're already root (dumb but true)
-        return format("( if test \"$UID\" -eq 0; then ( %s ); else sudo -E -n -S -- %s; fi )", command, command);
-    }
-    private static String sudoNew(String command) {
-        if (command==null) return null;
-        // on some OS's e.g. Centos 6.5 in SL, sudo -- X tries to run X as a literal argument;
-        // in particular "( echo foo && echo bar )" fails when passed as an argument in that way,
-        // but works if passed to bash -c;
-        // but others e.g. OS X fail if you say  sudo -- bash -c "( echo foo )"   ... not liking the parentheses
-        // piping to sudo bash seems the most reliable way
-        return "( if test \"$UID\" -eq 0; then ( "+command+" ); else "
-                + "echo " + BashStringEscapes.wrapBash(command) + " | "
-                + "sudo -E -n -S -s -- bash"
-                + " ; fi )";
-    }
-
-    /** sudo to a given user and run the indicated command;
-     * @deprecated since 0.7.0 semantics of this are fiddly, e.g. whether user gets their environment */
-    @Beta
-    public static String sudoAsUser(String user, String command) {
-        return sudoAsUserOld(user, command);
-    }
-    
-    private static String sudoAsUserOld(String user, String command) {
-        if (command == null) return null;
-        return format("{ sudo -E -n -u %s -s -- %s ; }", user, command);
-    }
-    // TODO would like to move away from sudoOld -- but needs extensive testing!
-//    private static String sudoAsUserNew(String user, String command) {
-//        if (command == null) return null;
-//          // no -E, run with permissions of this user
-//          // FIXME still doesn't always work e.g. doesn't have path of user 
-//          // (Alex says: can't find any combinations which work reliably)
-//        return "{ sudo -n -S -i -u "+user+" -- "+BashStringEscapes.wrapBash(command)+" ; }";
-//    }
-
-    public static String addSbinPathCommand() {
-        return "export PATH=$PATH:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin";
-    }
-
-    /** executes a command, then as user tees the output to the given file. 
-     * useful e.g. for appending to a file which is only writable by root or a priveleged user. */
-    public static String executeCommandThenAsUserTeeOutputToFile(String commandWhoseOutputToWrite, String user, String file) {
-        return format("{ %s | sudo -E -n -u %s -s -- tee -a %s ; }",
-                commandWhoseOutputToWrite, user, file);
-    }
-
-    /** some machines require a tty for sudo; brooklyn by default does not use a tty
-     * (so that it can get separate error+stdout streams); you can enable a tty as an
-     * option to every ssh command, or you can do it once and 
-     * modify the machine so that a tty is not subsequently required.
-     * <p>
-     * this command must be run with allocatePTY set as a flag to ssh.  see SshTasks.dontRequireTtyForSudo which sets that up. 
-     * <p>
-     * (having a tty for sudo seems like another case of imaginary security which is just irritating.
-     * like water restrictions at airport security.) */
-    public static String dontRequireTtyForSudo() {
-        return ifFileExistsElse0("/etc/sudoers", sudo("sed -i.brooklyn.bak 's/.*requiretty.*/#brooklyn-removed-require-tty/' /etc/sudoers"));
-    }
-
-    /** generates ~/.ssh/id_rsa if that file does not exist */
-    public static String generateKeyInDotSshIdRsaIfNotThere() {
-        return "[ -f ~/.ssh/id_rsa ] || ( mkdir -p ~/.ssh ; chmod 700 ~/.ssh ; ssh-keygen -t rsa -N '' -f ~/.ssh/id_rsa )";
-    }
-    
-    // TODO a builder would be better than these ifBlahExistsElseBlah methods!
-    // (ideally formatting better also; though maybe SshTasks would be better?)
-    
-    /**
-     * Returns a command that runs only if the specified file (or link or directory) exists;
-     * if the command runs and fails that exit is preserved (but if the file does not exist exit code is zero).
-     * Executed as  { { not-file-exists && ok ; } || command ; }  for portability.
-     * ("if [ ... ] ; then xxx ; else xxx ; fi" syntax is not quite as portable, I seem to recall (not sure, Alex Aug 2013).) 
-     */
-    public static String ifFileExistsElse0(String path, String command) {
-        return alternativesGroup(
-                chainGroup(format("test ! -e %s", path), "true"),
-                command);
-    }
-    /** as {@link #ifFileExistsElse0(String, String)} but returns non-zero if the test fails (also returns non-zero if the command fails,
-     * so you can't tell the difference :( -- we need if ; then ; else ; fi semantics for that I think, but not sure how portable that is) */
-    public static String ifFileExistsElse1(String path, String command) {
-        return chainGroup(format("test -e %s", path), command);
-    }
-
-    /**
-     * Returns a command that runs only if the specified executable exists on the path (using `which`).
-     * if the command runs and fails that exit is preserved (but if the executable is not on the path exit code is zero).
-     * @see #ifFileExistsElse0(String, String) for implementation discussion, using <code>{ { test -z `which executable` && true ; } || command ; } 
-     */
-    public static String ifExecutableElse0(String executable, String command) {
-        return alternativesGroup(
-                chainGroup(format("test -z `which %s`", executable), "true"),
-                command);
-    }
-
-    /** as {@link #ifExecutableElse0(String, String)} but returns 1 if the test fails (also returns non-zero if the command fails) */
-    public static String ifExecutableElse1(String executable, String command) {
-        return chainGroup(format("which %s", executable), command);
-    }
-
-    /**
-     * Returns a command which
-     * executes <code>statement</code> only if <code>command</code> is NOT found in <code>$PATH</code>
-     *
-     * @param command
-     * @param statement
-     * @return command
-     */
-    public static String ifNotExecutable(String command, String statement) {
-        return String.format("{ { test ! -z `which %s`; } || { %s; } }", command, statement);
-    }
-
-    /**
-     * Returns a command that runs only if the specified executable exists on the path (using `which`).
-     * if the command runs and fails that exit is preserved (but if the executable is not on the path exit code is zero).
-     * @see #ifFileExistsElse0(String, String) for implementation discussion, using <code>{ { test -z `which executable` && true ; } || command ; }
-     */
-    public static String onlyIfExecutableMissing(String executable, String command) {
-        return alternativesGroup(format("which %s", executable), command);
-    }
-
-    public static String ifExecutableElse(String command, String ifTrue, String otherwise) {
-        return com.google.common.base.Joiner.on('\n').join(
-                ifExecutableElse(command, ImmutableList.<String>of(ifTrue), ImmutableList.<String>of(otherwise)));
-    }
-
-    public static ImmutableList<String> ifExecutableElse(String command, List<String> ifTrue, List<String> otherwise) {
-        return ImmutableList.<String>builder()
-                .add(String.format("if test -z `which %s`; then", command))
-                .addAll(ifTrue)
-                .add("else")
-                .addAll(otherwise)
-                .add("fi")
-                .build();
-    }
-
-    /**
-     * Returns a sequence of chained commands that runs until one of them fails (i.e. joined by '&&')
-     * This currently runs as a subshell (so exits are swallowed) but behaviour may be changed imminently. 
-     * (Use {@link #chainGroup(Collection)} or {@link #chainSubshell(Collection)} to be clear.)
-     */
-    public static String chain(Collection<String> commands) {
-        return "( " + Strings.join(commands, " && ") + " )";
-    }
-
-    /** Convenience for {@link #chain(Collection)} */
-    public static String chain(String ...commands) {
-        return "( " + Strings.join(commands, " && ") + " )";
-    }
-
-    /** As {@link #chain(Collection)}, but explicitly using { } grouping characters
-     * to ensure exits are propagated. */
-    public static String chainGroup(Collection<String> commands) {
-        // spaces required around curly braces
-        return "{ " + Strings.join(commands, " && ") + " ; }";
-    }
-
-    /** As {@link #chainGroup(Collection)} */
-    public static String chainGroup(String ...commands) {
-        return "{ " + Strings.join(commands, " && ") + " ; }";
-    }
-
-    /** As {@link #chain(Collection)}, but explicitly using ( ) grouping characters
-     * to ensure exits are caught. */
-    public static String chainSubshell(Collection<String> commands) {
-        // the spaces are not required, but it might be possible that a (( expr )) is interpreted differently
-        // (won't hurt to have the spaces in any case!) 
-        return "( " + Strings.join(commands, " && ") + " )";
-    }
-
-    /** As {@link #chainSubshell(Collection)} */
-    public static String chainSubshell(String ...commands) {
-        return "( " + Strings.join(commands, " && ") + "  )";
-    }
-
-    /**
-     * Returns a sequence of chained commands that runs until one of them succeeds (i.e. joined by '||').
-     * This currently runs as a subshell (so exits are swallowed) but behaviour may be changed imminently. 
-     * (Use {@link #alternativesGroup(Collection)} or {@link #alternativesSubshell(Collection)} to be clear.)
-     */
-    public static String alternatives(Collection<String> commands) {
-        return "( " + Strings.join(commands, " || ") + " )";
-    }
-
-    /** As {@link #alternatives(Collection)} */
-    public static String alternatives(String ...commands) {
-        return "( " + Strings.join(commands, " || ") + " )";
-    }
-
-    /** As {@link #alternatives(Collection)}, but explicitly using { } grouping characters
-     * to ensure exits are propagated. */
-    public static String alternativesGroup(Collection<String> commands) {
-        // spaces required around curly braces
-        return "{ " + Strings.join(commands, " || ") + " ; }";
-    }
-
-    /** As {@link #alternativesGroup(Collection)} */
-    public static String alternativesGroup(String ...commands) {
-        return "{ " + Strings.join(commands, " || ") + " ; }";
-    }
-
-    /** As {@link #alternatives(Collection)}, but explicitly using ( ) grouping characters
-     * to ensure exits are caught. */
-    public static String alternativesSubshell(Collection<String> commands) {
-        // the spaces are not required, but it might be possible that a (( expr )) is interpreted differently
-        // (won't hurt to have the spaces in any case!) 
-        return "( " + Strings.join(commands, " || ") + " )";
-    }
-
-    /** As {@link #alternativesSubshell(Collection)} */
-    public static String alternativesSubshell(String ...commands) {
-        return "( " + Strings.join(commands, " || ") + "  )";
-    }
-
-    /** returns the pattern formatted with the given arg if the arg is not null, otherwise returns null */
-    public static String formatIfNotNull(String pattern, Object arg) {
-        if (arg==null) return null;
-        return format(pattern, arg);
-    }
-    
-    public static String installPackage(String packageDefaultName) {
-        return installPackage(MutableMap.of(), packageDefaultName);
-    }
-    /**
-     * Returns a command for installing the given package.
-     * <p>
-     * Warns, but does not fail or return non-zero if it ultimately fails.
-     * <p>
-     * Flags can contain common overrides for {@code apt}, {@code yum}, {@code port} and {@code brew}
-     * as the package names can be different for each of those. Setting the default package name to
-     * {@literal null} will use only the overridden package manager values. The {@code onlyifmissing} flag
-     * adds a check for an executable, and only attempts to install packages if it is not found.
-     * <pre>
-     * installPackage(ImmutableMap.of("yum", "openssl-devel", "apt", "openssl libssl-dev zlib1g-dev"), "libssl-devel");
-     * installPackage(ImmutableMap.of("apt", "libaio1"), null);
-     * installPackage(ImmutableMap.of("onlyifmissing", "curl"), "curl");
-     * </pre>
-     */
-    public static String installPackage(Map<?,?> flags, String packageDefaultName) {
-        return installPackageOr(flags, packageDefaultName, null);
-    }
-    public static String installPackageOrFail(Map<?,?> flags, String packageDefaultName) {
-        return installPackageOr(flags, packageDefaultName, "exit 9");
-    }
-    public static String installPackageOr(Map<?,?> flags, String packageDefaultName, String optionalCommandToRunIfNone) {
-        String ifMissing = (String) flags.get("onlyifmissing");
-        String zypperInstall = formatIfNotNull("zypper --non-interactive --no-gpg-checks install %s", getFlag(flags, "zypper", packageDefaultName));
-        String aptInstall = formatIfNotNull("apt-get install -y --allow-unauthenticated %s", getFlag(flags, "apt", packageDefaultName));
-        String yumInstall = formatIfNotNull("yum -y --nogpgcheck install %s", getFlag(flags, "yum", packageDefaultName));
-        String brewInstall = formatIfNotNull("brew install %s", getFlag(flags, "brew", packageDefaultName));
-        String portInstall = formatIfNotNull("port install %s", getFlag(flags, "port", packageDefaultName));
-
-        List<String> commands = new LinkedList<String>();
-        if (ifMissing != null)
-            commands.add(format("which %s", ifMissing));
-        if (zypperInstall != null)
-            commands.add(ifExecutableElse1("zypper",
-                    chainGroup(
-                            "echo zypper exists, doing refresh",
-                            ok(sudo("zypper --non-interactive --no-gpg-checks refresh")),
-                            sudo(zypperInstall))));
-        if (aptInstall != null)
-            commands.add(ifExecutableElse1("apt-get",
-                    chainGroup(
-                        "echo apt-get exists, doing update",
-                        "export DEBIAN_FRONTEND=noninteractive",
-                        ok(sudo("apt-get update")), 
-                        sudo(aptInstall))));
-        if (yumInstall != null)
-            commands.add(ifExecutableElse1("yum", 
-                    chainGroup(
-                        "echo yum exists, doing update",
-                        ok(sudo("yum check-update")),
-                        ok(sudo("yum -y install epel-release")),
-                        sudo(yumInstall))));
-        if (brewInstall != null)
-            commands.add(ifExecutableElse1("brew", brewInstall));
-        if (portInstall != null)
-            commands.add(ifExecutableElse1("port", sudo(portInstall)));
-
-        String lastCommand = ok(warn("WARNING: no known/successful package manager to install " +
-                (packageDefaultName!=null ? packageDefaultName : flags.toString()) +
-                ", may fail subsequently"));
-        if (optionalCommandToRunIfNone != null)
-            lastCommand = chain(lastCommand, optionalCommandToRunIfNone);
-        commands.add(lastCommand);
-        
-        return alternatives(commands);
-    }
-    
-    public static String warn(String message) {
-        return "( echo "+BashStringEscapes.wrapBash(message)+" | tee /dev/stderr )";
-    }
-
-    /** returns a command which logs a message to stdout and stderr then exits with the given error code */
-    public static String fail(String message, int code) {
-        return chainGroup(warn(message), "exit "+code);
-    }
-
-    /** requires the command to have a non-zero exit code; e.g.
-     * <code>require("which foo", "Command foo must be found", 1)</code> */
-    public static String require(String command, String failureMessage, int exitCode) {
-        return alternativesGroup(command, fail(failureMessage, exitCode));
-    }
-
-    /** as {@link #require(String, String, int)} but returning the original exit code */
-    public static String require(String command, String failureMessage) {
-        return alternativesGroup(command, chainGroup("EXIT_CODE=$?", warn(failureMessage), "exit $EXIT_CODE"));
-    }
-
-    /** requires the test to pass, as valid bash `test` arguments; e.g.
-     * <code>requireTest("-f /etc/hosts", "Hosts file must exist", 1)</code> */
-    public static String requireTest(String test, String failureMessage, int exitCode) {
-        return require("test "+test, failureMessage, exitCode);
-    }
-
-    /** as {@link #requireTest(String, String, int)} but returning the original exit code */
-    public static String requireTest(String test, String failureMessage) {
-        return require("test "+test, failureMessage);
-    }
-
-    /** fails with nice error if the given file does not exist */
-    public static String requireFile(String file) {
-        return requireTest("-f "+BashStringEscapes.wrapBash(file), "The required file \""+file+"\" does not exist");
-    }
-
-    /** fails with nice error if the given file does not exist */
-    public static String requireExecutable(String command) {
-        return require("which "+BashStringEscapes.wrapBash(command), "The required executable \""+command+"\" does not exist");
-    }
-
-    public static String waitForFileContents(String file, String desiredContent, Duration timeout, boolean failOnTimeout) {
-        long secs = Math.max(timeout.toSeconds(), 1);
-        
-        List<String> commands = ImmutableList.of(
-                "for i in {1.."+secs+"}; do",
-                "    grep '"+desiredContent+"' "+file+" && result=0 || result=$?",
-                "    [ \"$result\" == 0 ] && break",
-                "    sleep 1",
-                "done",
-                "if test \"$result\" -ne 0; then",
-                "    "+ (failOnTimeout ?
-                            "echo \"Couldn't find "+desiredContent+" in "+file+"; aborting\" && exit 1" :
-                            "echo \"Couldn't find "+desiredContent+" in "+file+"; continuing\""),
-                "fi");
-        return Joiner.on("\n").join(commands);
-    }
-
-    public static String waitForPortFree(int port, Duration timeout, boolean failOnTimeout) {
-        long secs = Math.max(timeout.toSeconds(), 1);
-
-        // TODO How platform-dependent are the args + output format of netstat?
-        // TODO Not using sudo as wrapping either netstat call or sudo(alternativesGroup(...)) fails; parentheses too confusing!
-        String netstatCommand = alternativesGroup(
-                "sudo netstat -antp --tcp", // for Centos
-                "sudo netstat -antp TCP"); // for OS X 
-        
-        // number could appear in an IP address or as a port; look for white space at end, and dot or colon before
-        String grepCommand = "grep -E '(:|\\.)"+port+"($|\\s)' > /dev/null";
-        
-        List<String> commands = ImmutableList.of(
-                "for i in {1.."+secs+"}; do",
-                "    "+BashCommands.requireExecutable("netstat"),
-                "    "+alternativesGroup(
-                        chainGroup("which awk", "AWK_EXEC=awk"), 
-                        chainGroup("which gawk", "AWK_EXEC=gawk"), 
-                        chainGroup("which /usr/bin/awk", "AWK_EXEC=/usr/bin/awk"), 
-                        chainGroup("echo \"No awk to determine if Port "+port+" still in use; aborting\"", "exit 1")),
-                "    "+netstatCommand+" | $AWK_EXEC '{print $4}' | "+grepCommand+" && result=0 || result=$?",
-                "    [ \"$result\" != 0 ] && break",
-                "    sleep 1",
-                "done",
-                "if test \"$result\" -eq 0; then",
-                "    "+ (failOnTimeout ?
-                            "echo \"Port "+port+" still in use (according to netstat); aborting\" && exit 1" :
-                            "echo \"Port "+port+" still in use (according to netstat); continuing\""),
-                "fi");
-        return Joiner.on("\n").join(commands);
-    }
-
-    public static String unzip(String file, String targetDir) {
-        return "unzip " + file + (Strings.isNonBlank(targetDir) ? " -d "+targetDir : "");
-    }
-
-    public static final String INSTALL_TAR = installExecutable("tar");
-    public static final String INSTALL_CURL = installExecutable("curl");
-    public static final String INSTALL_WGET = installExecutable("wget");
-    public static final String INSTALL_ZIP = installExecutable("zip");
-    public static final String INSTALL_UNZIP = alternatives(installExecutable("unzip"), installExecutable("zip"));
-    public static final String INSTALL_SYSSTAT = installPackage(ImmutableMap.of("onlyifmissing", "iostat"), "sysstat");
-
-    /**
-     * Returns commands to download the URL, saving as the given file. Will try each URL in turn until one is successful
-     * (see `curl -f` documentation).
-     */
-    public static List<String> commandsToDownloadUrlsAs(List<String> urls, String saveAs) {
-        return Arrays.asList(INSTALL_CURL, 
-                require(simpleDownloadUrlAs(urls, saveAs), "Could not retrieve "+saveAs+". Tried: " + Joiner.on(", ").join(urls), 9));
-    }
-    public static String commandToDownloadUrlsAs(List<String> urls, String saveAs) {
-        return chain(INSTALL_CURL, 
-                require(simpleDownloadUrlAs(urls, saveAs), "Could not retrieve "+saveAs+". Tried: " + Joiner.on(", ").join(urls), 9));
-    }
-    public static String commandToDownloadUrlAs(String url, String saveAs) {
-        return chain(INSTALL_CURL, 
-                require(simpleDownloadUrlAs(Arrays.asList(url), saveAs), "Could not retrieve "+saveAs+" from " + url, 9));
-    }
-
-    /**
-     * Returns command to download the URL, sending the output to stdout --
-     * suitable for redirect by appending " | tar xvf".
-     * Will try each URL in turn until one is successful
-     */
-    public static String downloadToStdout(List<String> urls) {
-        return chain(
-                INSTALL_CURL + " > /dev/null", 
-                require(simpleDownloadUrlAs(urls, null), 
-                        "Could not retrieve file. Tried: " + Joiner.on(", ").join(urls), 9));
-    }
-    
-    /** as {@link #downloadToStdout(List)} but varargs for convenience */
-    public static String downloadToStdout(String ...urls) {
-        return downloadToStdout(Arrays.asList(urls));
-    }
-
-    /**
-     * Same as {@link downloadUrlAs(List, String)}, except does not install curl, and does not exit on failure,
-     * and if saveAs is null it downloads it so stdout.
-     */
-    public static String simpleDownloadUrlAs(List<String> urls, String saveAs) {
-        return simpleDownloadUrlAs(urls, null, null, saveAs);
-    }
-
-    public static String simpleDownloadUrlAs(List<String> urls, String user, String password, String saveAs) {
-        if (urls.isEmpty()) throw new IllegalArgumentException("No URLs supplied to download "+saveAs);
-        
-        List<String> commands = new ArrayList<String>();
-        for (String url : urls) {
-            String command = "curl -f -L -k --retry 10 --keepalive-time 30 --speed-time 30 ";
-            if (user!=null && password!=null) {
-               command = command + format("-u %s:%s ", user, password);
-            }
-            command = command + format("\"%s\"", url);
-            if (saveAs!=null) {
-                command = command + format(" -o %s", saveAs);
-            }
-            commands.add(command);
-        }
-        return alternatives(commands);
-    }
-
-    private static Object getFlag(Map<?,?> flags, String flagName, Object defaultValue) {
-        Object found = flags.get(flagName);
-        return found == null ? defaultValue : found;
-    }
-
-    /**
-     * Install a particular Java runtime, fails if not possible.
-     * <p>
-     * <em><strong>Note</strong> Java 8 is not yet supported on SUSE</em>
-     *
-     * @return The command to install the given Java runtime.
-     * @see #installJava6OrFail()
-     * @see #installJava7Or6OrFail()
-     * @see #installJavaLatestOrFail()
-     */
-    public static String installJava(int version) {
-        Preconditions.checkArgument(version == 6 || version == 7 || version == 8, "Supported Java versions are 6, 7, or 8");
-        return installPackageOr(MutableMap.of("apt", "openjdk-" + version + "-jdk","yum", "java-1." + version + ".0-openjdk-devel"), null,
-                ifExecutableElse1("zypper", chainGroup(
-                        ok(sudo("zypper --non-interactive addrepo http://download.opensuse.org/repositories/Java:/openjdk6:/Factory/SLE_11_SP3 java_sles_11")),
-                        ok(sudo("zypper --non-interactive addrepo http://download.opensuse.org/repositories/Java:/openjdk6:/Factory/openSUSE_11.4 java_suse_11")),
-                        ok(sudo("zypper --non-interactive addrepo http://download.opensuse.org/repositories/Java:/openjdk6:/Factory/openSUSE_12.3 java_suse_12")),
-                        ok(sudo("zypper --non-interactive addrepo http://download.opensuse.org/repositories/Java:/openjdk6:/Factory/openSUSE_13.1 java_suse_13")),
-                        alternatives(installPackageOrFail(MutableMap.of("zypper", "java-1_" + version + "_0-openjdk-devel"), null),
-                                installPackageOrFail(MutableMap.of("zypper", "java-1_" + version + "_0-ibm"), null)))));
-    }
-
-    public static String installJava6() {
-        return installJava(6);
-    }
-    public static String installJava7() {
-        return installJava(7);
-    }
-    public static String installJava8() {
-        return installJava(8);
-    }
-
-    public static String installJava6IfPossible() {
-        return ok(installJava6());
-    }
-    public static String installJava7IfPossible() {
-        return ok(installJava7());
-    }
-    public static String installJava8IfPossible() {
-        return ok(installJava8());
-    }
-
-    public static String installJava6OrFail() {
-        return alternatives(installJava6(), fail("java 6 install failed", 9));
-    }
-    public static String installJava7OrFail() {
-        return alternatives(installJava7(), fail("java 7 install failed", 9));
-    }
-    public static String installJava7Or6OrFail() {
-        return alternatives(installJava7(), installJava6(), fail("java install failed", 9));
-    }
-    public static String installJavaLatestOrFail() {
-        return alternatives(installJava8(), installJava7(), installJava6(), fail("java latest install failed", 9));
-    }
-
-    public static String installJavaLatestOrWarn() {
-        return alternatives(installJava8(), installJava7(), installJava6(), warn("java latest install failed, entity may subsequently fail"));
-    }
-
-    /** cats the given text to the given command, using bash << multi-line input syntax */
-    public static String pipeTextTo(String text, String command) {
-        String id = Identifiers.makeRandomId(8);
-        return "cat << EOF_"+id+" | "+command+"\n"
-                +text
-                +"\n"+"EOF_"+id+"\n";
-    }
-
-    public static String prependToEtcHosts(String ip, String... hostnames) {
-        String tempFileId = "bak"+Identifiers.makeRandomId(4);
-        return sudo(String.format("sed -i."+tempFileId+" -e '1i\\\n%s %s' /etc/hosts", ip, Joiner.on(" ").join(hostnames)));
-    }
-    
-    public static String appendToEtcHosts(String ip, String... hostnames) {
-        // Using sed rather than `echo ... >> /etc/hosts` because when embedded inside sudo, 
-        // the redirect doesn't get executed by sudo.
-        String tempFileId = "bak"+Identifiers.makeRandomId(4);
-        return sudo(String.format("sed -i."+tempFileId+" -e '$a\\\n%s %s' /etc/hosts", ip, Joiner.on(" ").join(hostnames)));
-    }
-
-    /**
-     * Sets the hostname, splitting the given hostname if it contains a dot to include the unqualified and fully qualified names.
-     *  
-     * @see {@link #setHostname(String, String)}
-     */
-    @Beta
-    public static List<String> setHostname(String newHostname) {
-        // See http://www.dns-sd.org/trailingdotsindomainnames.html.
-        // If we are given "abcd." then let's pass that as-is to setHostname("abcd.", null)
-        
-        if (newHostname.indexOf(".") > 0) {
-            String hostPart = newHostname.substring(0, newHostname.indexOf("."));
-            String domainPart = newHostname.substring(hostPart.length()+1);
-            return setHostname(hostPart, domainPart);
-        } else {
-            return setHostname(newHostname, null);
-        }
-    }
-    
-    /**
-     * Sets the hostname to {@code hostPart + "." + domainPart}, or if domainPart is null/empty then {code hostPart}.
-     * 
-     * @param hostPart
-     * @param domainPart
-     * @return
-     */
-    @Beta
-    public static List<String> setHostname(String hostPart, String domainPart) {
-        // See:
-        // - http://www.rackspace.com/knowledge_center/article/centos-hostname-change
-        // - https://wiki.debian.org/HowTo/ChangeHostname
-        // - http://askubuntu.com/questions/9540/how-do-i-change-the-computer-name
-        //
-        // We prepend in /etc/hosts, to ensure the right fqn appears first.
-        //    e.g. comment in http://askubuntu.com/questions/158957/how-to-set-the-fully-qualified-domain-name-in-12-04
-        //    says "It's important to note that the first domain in /etc/hosts should be your FQDN. "
-        //
-        // TODO Should we run `sudo service hostname restart` or `sudo /etc/init.d/hostname restart`?
-        //      I don't think we need to because we've run `sudo hostname <newname>`
-        //
-        // TODO What if /etc/sysconfig/network doesn't have a line for HOSTNAME=...?
-        //
-        // TODO What about hostPart ending in "." - see http://www.dns-sd.org/trailingdotsindomainnames.html
-        //      for what that means in DNS. However, hostname is not the same as the DNS name (hostnames 
-        //      predate the invention of DNS! - although frequently the DNS name has the same first portion 
-        //      as the hostname) so the link you gave is not relevant. However despite searching Google and 
-        //      man pages I [Ricard] am unable to find a reference which clearly states what characters are 
-        //      relevant in a hostname. I think it's safest to assume that the hostname is just [a-z,0-9,-] 
-        //      and no dots at all.
-        
-        checkNotNull(hostPart, "hostPart");
-        checkArgument(!hostPart.contains("."), "hostPart '%s' must not contain '.'", hostPart);
-
-        String tempFileId = "bak"+Identifiers.makeRandomId(4);
-        
-        List<String> allhostnames = Lists.newArrayList();
-        String fqdn = hostPart;
-        if (Strings.isNonBlank(domainPart)) {
-            fqdn = hostPart+"."+domainPart;
-            allhostnames.add(fqdn);
-        }
-        allhostnames.add(hostPart);
-        allhostnames.add("localhost");
-        
-        return ImmutableList.of(
-                sudo("sed -i."+tempFileId+" -e 's/^127.0.0.1/# Replaced by Brooklyn\\\n#127.0.0.1/' /etc/hosts"),
-                prependToEtcHosts("127.0.0.1", allhostnames.toArray(new String[allhostnames.size()])),
-                ifFileExistsElse0("/etc/sysconfig/network", sudo("sed -i."+tempFileId+" -e 's/^HOSTNAME=.*$/HOSTNAME="+hostPart+"/' /etc/sysconfig/network")),
-                ifFileExistsElse0("/etc/hostname", sudo("sed -i."+tempFileId+" -e 's/^[a-zA-Z_0-9].*$/"+hostPart+"/' /etc/hostname")),
-                sudo("hostname "+hostPart));
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/cf2f7a93/utils/common/src/main/java/brooklyn/util/ssh/IptablesCommands.java
----------------------------------------------------------------------
diff --git a/utils/common/src/main/java/brooklyn/util/ssh/IptablesCommands.java b/utils/common/src/main/java/brooklyn/util/ssh/IptablesCommands.java
deleted file mode 100644
index c0e8213..0000000
--- a/utils/common/src/main/java/brooklyn/util/ssh/IptablesCommands.java
+++ /dev/null
@@ -1,261 +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.ssh;
-
-import static brooklyn.util.ssh.BashCommands.alternatives;
-import static brooklyn.util.ssh.BashCommands.chain;
-import static brooklyn.util.ssh.BashCommands.installPackage;
-import static brooklyn.util.ssh.BashCommands.sudo;
-
-import com.google.common.annotations.Beta;
-import com.google.common.base.Optional;
-
-public class IptablesCommands {
-
-    public enum Chain {
-        INPUT, FORWARD, OUTPUT
-    }
-
-    public enum Policy {
-        ACCEPT, REJECT, DROP, LOG
-    }
-
-    /*** @deprecated since 0.7; use {@link brooklyn.util.net.Protocol} */
-    @Deprecated
-    public enum Protocol {
-        TCP("tcp"), UDP("udp"), ALL("all");
-
-        final String protocol;
-
-        private Protocol(String protocol) {
-            this.protocol = protocol;
-        }
-
-        @Override
-        public String toString() {
-            return protocol;
-        }
-
-        brooklyn.util.net.Protocol convert() {
-            switch (this) {
-                case TCP: return brooklyn.util.net.Protocol.TCP;
-                case UDP: return brooklyn.util.net.Protocol.UDP;
-                case ALL: return brooklyn.util.net.Protocol.ALL;
-                default: throw new IllegalStateException("Unexpected protocol "+this);
-            }
-        }
-    }
-
-    @Beta // implementation not portable across distros
-    public static String iptablesService(String cmd) {
-        return sudo(alternatives(
-                BashCommands.ifExecutableElse1("service", "service iptables " + cmd),
-                "/sbin/service iptables " + cmd));
-    }
-
-    @Beta // implementation not portable across distros
-    public static String iptablesServiceStop() {
-        return iptablesService("stop");
-    }
-
-    @Beta // implementation not portable across distros
-    public static String iptablesServiceStart() {
-        return iptablesService("start");
-    }
-
-    @Beta // implementation not portable across distros
-    public static String iptablesServiceRestart() {
-        return iptablesService("restart");
-    }
-
-    @Beta // implementation not portable across distros
-    public static String iptablesServiceStatus() {
-        return iptablesService("status");
-    }
-
-    @Beta // implementation not portable across distros
-    public static String firewalldService(String cmd) {
-        return sudo(alternatives(
-                BashCommands.ifExecutableElse1("systemctl", "systemctl " + cmd + " firewalld"),
-                "/usr/bin/systemctl " + cmd + " firewalld"));
-    }
-
-    @Beta // implementation not portable across distros
-    public static String firewalldServiceStop() {
-        return firewalldService("stop");
-    }
-
-    @Beta // implementation not portable across distros
-    public static String firewalldServiceStart() {
-        return firewalldService("start");
-    }
-
-    @Beta // implementation not portable across distros
-    public static String firewalldServiceRestart() {
-        return firewalldService("restart");
-    }
-
-    @Beta // implementation not portable across distros
-    public static String firewalldServiceStatus() {
-        return firewalldService("status");
-    }
-
-    @Beta // implementation not portable across distros
-    public static String firewalldServiceIsActive() {
-        return firewalldService("is-active");
-    }
-
-    /**
-     * Returns the command that saves iptables rules on file.
-     *
-     * @return Returns the command that saves iptables rules on file.
-     *
-     */
-    public static String saveIptablesRules() {
-        return alternatives(sudo("service iptables save"),
-                            chain(installPackage("iptables-persistent"), sudo("/etc/init.d/iptables-persistent save")));
-    }
-
-    /**
-     * Returns the command that cleans up iptables rules.
-     *
-     * @return Returns the command that cleans up iptables rules.
-     */
-    public static String cleanUpIptablesRules() {
-       return sudo("/sbin/iptables -F");
-    }
-
-    /**
-     * Returns the iptables rules.
-     *
-     * @return Returns the command that list all the iptables rules.
-     */
-    public static String listIptablesRule() {
-       return sudo("/sbin/iptables -L -v -n");
-    }
-
-    /**
-     * Returns the command that inserts a rule on top of the iptables' rules to all interfaces.
-     *
-     * @return Returns the command that inserts a rule on top of the iptables'
-     *         rules.
-     */
-    public static String insertIptablesRule(Chain chain, brooklyn.util.net.Protocol protocol, int port, Policy policy) {
-        return addIptablesRule("-I", chain, Optional.<String> absent(), protocol, port, policy);
-    }
-
-    /** @deprecated since 0.7.0; use {@link #insertIptablesRule(Chain, brooklyn.util.net.Protocol, int, Policy)} */
-    @Deprecated
-    public static String insertIptablesRule(Chain chain, Protocol protocol, int port, Policy policy) {
-        return insertIptablesRule(chain, protocol.convert(), port, policy);
-    }
-
-    /**
-     * Returns the command that inserts a rule on top of the iptables' rules.
-     *
-     * @return Returns the command that inserts a rule on top of the iptables'
-     *         rules.
-     */
-    public static String insertIptablesRule(Chain chain, String networkInterface, brooklyn.util.net.Protocol protocol, int port, Policy policy) {
-        return addIptablesRule("-I", chain, Optional.of(networkInterface), protocol, port, policy);
-    }
-
-    /** @deprecated since 0.7.0; use {@link #insertIptablesRule(Chain, String, brooklyn.util.net.Protocol, int, Policy)} */
-    @Deprecated
-    public static String insertIptablesRule(Chain chain, String networkInterface, Protocol protocol, int port, Policy policy) {
-        return insertIptablesRule(chain, networkInterface, protocol.convert(), port, policy);
-    }
-
-    /**
-     * Returns the command that appends a rule to iptables to all interfaces.
-     *
-     * @return Returns the command that appends a rule to iptables.
-     */
-    public static String appendIptablesRule(Chain chain, brooklyn.util.net.Protocol protocol, int port, Policy policy) {
-        return addIptablesRule("-A", chain, Optional.<String> absent(), protocol, port, policy);
-    }
-
-    /** @deprecated since 0.7.0; use {@link #appendIptablesRule(Chain, brooklyn.util.net.Protocol, int, Policy)} */
-    @Deprecated
-    public static String appendIptablesRule(Chain chain, Protocol protocol, int port, Policy policy) {
-        return appendIptablesRule(chain, protocol.convert(), port, policy);
-    }
-
-    /**
-     * Returns the command that appends a rule to iptables.
-     *
-     * @return Returns the command that appends a rule to iptables.
-     */
-    public static String appendIptablesRule(Chain chain, String networkInterface, brooklyn.util.net.Protocol protocol, int port, Policy policy) {
-        return addIptablesRule("-A", chain, Optional.of(networkInterface), protocol, port, policy);
-    }
-
-    /** @deprecated since 0.7.0; use {@link #appendIptablesRule(Chain, String, brooklyn.util.net.Protocol, int, Policy)} */
-    @Deprecated
-    public static String appendIptablesRule(Chain chain, String networkInterface, Protocol protocol, int port, Policy policy) {
-        return appendIptablesRule(chain, networkInterface, protocol.convert(), port, policy);
-    }
-
-    /**
-     * Returns the command that creates a rule to iptables.
-     *
-     * @return Returns the command that creates a rule for iptables.
-     */
-    public static String addIptablesRule(String direction, Chain chain, Optional<String> networkInterface, brooklyn.util.net.Protocol protocol, int port, Policy policy) {
-        String addIptablesRule;
-        if(networkInterface.isPresent()) {
-           addIptablesRule = String.format("/sbin/iptables %s %s -i %s -p %s --dport %d -j %s", direction, chain, networkInterface.get(), protocol, port, policy);
-        } else {
-           addIptablesRule = String.format("/sbin/iptables %s %s -p %s --dport %d -j %s", direction, chain, protocol, port, policy);
-        }
-        return sudo(addIptablesRule);
-    }
-
-    /** @deprecated since 0.7.0; use {@link #addIptablesRule(String, Chain, Optional, brooklyn.util.net.Protocol, int, Policy)} */
-    @Deprecated
-    public static String addIptablesRule(String direction, Chain chain, Optional<String> networkInterface, Protocol protocol, int port, Policy policy) {
-        return addIptablesRule(direction, chain, networkInterface, protocol.convert(), port, policy);
-    }
-
-    /**
-     * Returns the command that adds firewalld direct rule.
-     *
-     * @return Returns the command that adds firewalld direct rule.
-     */
-    public static String addFirewalldRule(Chain chain, brooklyn.util.net.Protocol protocol, int port, Policy policy) {
-        return addFirewalldRule(chain, Optional.<String>absent(), protocol, port, policy);
-    }
-    
-    /**
-     * Returns the command that adds firewalld direct rule.
-     *
-     * @return Returns the command that adds firewalld direct rule.
-     */
-    public static String addFirewalldRule(Chain chain, Optional<String> networkInterface, brooklyn.util.net.Protocol protocol, int port, Policy policy) {
-        String command = new String("/usr/bin/firewall-cmd");
-        String commandPermanent = new String("/usr/bin/firewall-cmd --permanent");
-        
-        String interfaceParameter = String.format("%s", networkInterface.isPresent() ? " -i " + networkInterface.get() : "");
-        
-        String commandParameters = String.format(" --direct --add-rule ipv4 filter %s 0 %s -p %s --dport %d -j %s", 
-                                                                chain, interfaceParameter,  protocol, port, policy);
-        
-        return sudo(chain(command + commandParameters, commandPermanent + commandParameters));
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/cf2f7a93/utils/common/src/main/java/brooklyn/util/stream/DelegatingPrintStream.java
----------------------------------------------------------------------
diff --git a/utils/common/src/main/java/brooklyn/util/stream/DelegatingPrintStream.java b/utils/common/src/main/java/brooklyn/util/stream/DelegatingPrintStream.java
deleted file mode 100644
index a8a65c7..0000000
--- a/utils/common/src/main/java/brooklyn/util/stream/DelegatingPrintStream.java
+++ /dev/null
@@ -1,174 +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.stream;
-
-import java.io.IOException;
-import java.io.PrintStream;
-import java.util.Locale;
-
-/** PrintStream which simply delegates to the implementation of getDelegate() */
-public abstract class DelegatingPrintStream extends PrintStream {
-    
-    public DelegatingPrintStream() {
-        super(new IllegalOutputStream());
-    }
-    
-    protected abstract PrintStream getDelegate();
-
-    public int hashCode() {
-        return getDelegate().hashCode();
-    }
-
-    public void write(byte[] b) throws IOException {
-        getDelegate().write(b);
-    }
-
-    public boolean equals(Object obj) {
-        return getDelegate().equals(obj);
-    }
-
-    public String toString() {
-        return getDelegate().toString();
-    }
-
-    public void flush() {
-        getDelegate().flush();
-    }
-
-    public void close() {
-        getDelegate().close();
-    }
-
-    public boolean checkError() {
-        return getDelegate().checkError();
-    }
-
-    public void write(int b) {
-        getDelegate().write(b);
-    }
-
-    public void write(byte[] buf, int off, int len) {
-        getDelegate().write(buf, off, len);
-    }
-
-    public void print(boolean b) {
-        getDelegate().print(b);
-    }
-
-    public void print(char c) {
-        getDelegate().print(c);
-    }
-
-    public void print(int i) {
-        getDelegate().print(i);
-    }
-
-    public void print(long l) {
-        getDelegate().print(l);
-    }
-
-    public void print(float f) {
-        getDelegate().print(f);
-    }
-
-    public void print(double d) {
-        getDelegate().print(d);
-    }
-
-    public void print(char[] s) {
-        getDelegate().print(s);
-    }
-
-    public void print(String s) {
-        getDelegate().print(s);
-    }
-
-    public void print(Object obj) {
-        getDelegate().print(obj);
-    }
-
-    public void println() {
-        getDelegate().println();
-    }
-
-    public void println(boolean x) {
-        getDelegate().println(x);
-    }
-
-    public void println(char x) {
-        getDelegate().println(x);
-    }
-
-    public void println(int x) {
-        getDelegate().println(x);
-    }
-
-    public void println(long x) {
-        getDelegate().println(x);
-    }
-
-    public void println(float x) {
-        getDelegate().println(x);
-    }
-
-    public void println(double x) {
-        getDelegate().println(x);
-    }
-
-    public void println(char[] x) {
-        getDelegate().println(x);
-    }
-
-    public void println(String x) {
-        getDelegate().println(x);
-    }
-
-    public void println(Object x) {
-        getDelegate().println(x);
-    }
-
-    public PrintStream printf(String format, Object... args) {
-        return getDelegate().printf(format, args);
-    }
-
-    public PrintStream printf(Locale l, String format, Object... args) {
-        return getDelegate().printf(l, format, args);
-    }
-
-    public PrintStream format(String format, Object... args) {
-        return getDelegate().format(format, args);
-    }
-
-    public PrintStream format(Locale l, String format, Object... args) {
-        return getDelegate().format(l, format, args);
-    }
-
-    public PrintStream append(CharSequence csq) {
-        return getDelegate().append(csq);
-    }
-
-    public PrintStream append(CharSequence csq, int start, int end) {
-        return getDelegate().append(csq, start, end);
-    }
-
-    public PrintStream append(char c) {
-        return getDelegate().append(c);
-    }
-    
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/cf2f7a93/utils/common/src/main/java/brooklyn/util/stream/IllegalOutputStream.java
----------------------------------------------------------------------
diff --git a/utils/common/src/main/java/brooklyn/util/stream/IllegalOutputStream.java b/utils/common/src/main/java/brooklyn/util/stream/IllegalOutputStream.java
deleted file mode 100644
index 827090a..0000000
--- a/utils/common/src/main/java/brooklyn/util/stream/IllegalOutputStream.java
+++ /dev/null
@@ -1,31 +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.stream;
-
-import java.io.OutputStream;
-
-/** output stream which throws if anyone tries to write to it */
-public class IllegalOutputStream extends OutputStream {
-    @Override public void write(int b) {
-        throw new IllegalStateException("should not write to this output stream");
-    }
-    @Override public void write(byte[] b, int off, int len) {
-        throw new IllegalStateException("should not write to this output stream");
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/cf2f7a93/utils/common/src/main/java/brooklyn/util/stream/InputStreamSupplier.java
----------------------------------------------------------------------
diff --git a/utils/common/src/main/java/brooklyn/util/stream/InputStreamSupplier.java b/utils/common/src/main/java/brooklyn/util/stream/InputStreamSupplier.java
deleted file mode 100644
index d295e72..0000000
--- a/utils/common/src/main/java/brooklyn/util/stream/InputStreamSupplier.java
+++ /dev/null
@@ -1,49 +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.stream;
-
-import java.io.IOException;
-import java.io.InputStream;
-
-import com.google.common.io.InputSupplier;
-
-public class InputStreamSupplier implements InputSupplier<InputStream> {
-
-    private final InputStream target;
-
-    /** @deprecated since 0.7.0; use {@link InputStreamSupplier#of(InputStream)} instead */
-    @Deprecated
-    public InputStreamSupplier(InputStream target) {
-        this.target = target;
-    }
-
-    @Override
-    public InputStream getInput() throws IOException {
-        return target;
-    }
-
-    public static InputStreamSupplier of(InputStream target) {
-        return new InputStreamSupplier(target);
-    }
-
-    public static InputStreamSupplier fromString(String input) {
-        return new InputStreamSupplier(Streams.newInputStreamWithContents(input));
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/cf2f7a93/utils/common/src/main/java/brooklyn/util/stream/KnownSizeInputStream.java
----------------------------------------------------------------------
diff --git a/utils/common/src/main/java/brooklyn/util/stream/KnownSizeInputStream.java b/utils/common/src/main/java/brooklyn/util/stream/KnownSizeInputStream.java
deleted file mode 100644
index 8919af2..0000000
--- a/utils/common/src/main/java/brooklyn/util/stream/KnownSizeInputStream.java
+++ /dev/null
@@ -1,113 +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.stream;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-
-/** an input stream, whose size we know */
-public class KnownSizeInputStream extends InputStream {
-
-    public static KnownSizeInputStream of(String contents) {
-        return of(contents.getBytes());
-    }
-
-    public static KnownSizeInputStream of(byte[] contents) {
-        return new KnownSizeInputStream(new ByteArrayInputStream(contents), contents.length);
-    }
-
-    private final long length;
-    private final InputStream target;
-    
-    public KnownSizeInputStream(InputStream target, long length) {
-        this.target = checkNotNull(target, "target");
-        this.length = length;
-    }
-    
-    public long length() {
-        return length;
-    }
-    
-    public InputStream getTarget() {
-        return target;
-    }
-
-    @Override
-    public int read() throws IOException {
-        return target.read();
-    }
-
-    @Override
-    public int hashCode() {
-        return target.hashCode();
-    }
-
-    @Override
-    public int read(byte[] b) throws IOException {
-        return target.read(b);
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        return target.equals(obj);
-    }
-
-    @Override
-    public int read(byte[] b, int off, int len) throws IOException {
-        return target.read(b, off, len);
-    }
-
-    @Override
-    public long skip(long n) throws IOException {
-        return target.skip(n);
-    }
-
-    @Override
-    public int available() throws IOException {
-        return target.available();
-    }
-
-    @Override
-    public String toString() {
-        return target.toString();
-    }
-
-    @Override
-    public void close() throws IOException {
-        target.close();
-    }
-
-    @Override
-    public void mark(int readlimit) {
-        target.mark(readlimit);
-    }
-
-    @Override
-    public void reset() throws IOException {
-        target.reset();
-    }
-
-    @Override
-    public boolean markSupported() {
-        return target.markSupported();
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/cf2f7a93/utils/common/src/main/java/brooklyn/util/stream/ReaderInputStream.java
----------------------------------------------------------------------
diff --git a/utils/common/src/main/java/brooklyn/util/stream/ReaderInputStream.java b/utils/common/src/main/java/brooklyn/util/stream/ReaderInputStream.java
deleted file mode 100644
index a3d5fab..0000000
--- a/utils/common/src/main/java/brooklyn/util/stream/ReaderInputStream.java
+++ /dev/null
@@ -1,202 +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.stream;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.Reader;
-
-public class ReaderInputStream extends InputStream {
-
-    /** Source Reader */
-    private Reader in;
-
-    private String encoding = System.getProperty("file.encoding");
-
-    private byte[] slack;
-
-    private int begin;
-
-    /**
-     * Construct a <{@link ReaderInputStream}
-     * for the specified {@link Reader}.
-     *
-     * @param reader   {@link Reader}; must not be {@code null}.
-     */
-    public ReaderInputStream(Reader reader) {
-        in = reader;
-    }
-
-    /**
-     * Construct a {@link ReaderInputStream}
-     * for the specified {@link Reader},
-     * with the specified encoding.
-     *
-     * @param reader     non-null {@link Reader}.
-     * @param encoding   non-null {@link String} encoding.
-     */
-    public ReaderInputStream(Reader reader, String encoding) {
-        this(reader);
-        if (encoding == null) {
-            throw new IllegalArgumentException("encoding must not be null");
-        } else {
-            this.encoding = encoding;
-        }
-    }
-
-    /**
-     * Reads from the {@link Reader}, returning the same value.
-     *
-     * @return the value of the next character in the {@link Reader}.
-     *
-     * @exception IOException if the original {@link Reader} fails to be read
-     */
-    public synchronized int read() throws IOException {
-        if (in == null) {
-            throw new IOException("Stream Closed");
-        }
-
-        byte result;
-        if (slack != null && begin < slack.length) {
-            result = slack[begin];
-            if (++begin == slack.length) {
-                slack = null;
-            }
-        } else {
-            byte[] buf = new byte[1];
-            if (read(buf, 0, 1) <= 0) {
-                result = -1;
-            }
-            result = buf[0];
-        }
-
-        if (result < -1) {
-            result += 256;
-        }
-
-        return result;
-    }
-
-    /**
-     * Reads from the {@link Reader} into a byte array
-     *
-     * @param b  the byte array to read into
-     * @param off the offset in the byte array
-     * @param len the length in the byte array to fill
-     * @return the actual number read into the byte array, -1 at
-     *         the end of the stream
-     * @exception IOException if an error occurs
-     */
-    public synchronized int read(byte[] b, int off, int len)
-        throws IOException {
-        if (in == null) {
-            throw new IOException("Stream Closed");
-        }
-
-        while (slack == null) {
-            char[] buf = new char[len]; // might read too much
-            int n = in.read(buf);
-            if (n == -1) {
-                return -1;
-            }
-            if (n > 0) {
-                slack = new String(buf, 0, n).getBytes(encoding);
-                begin = 0;
-            }
-        }
-
-        if (len > slack.length - begin) {
-            len = slack.length - begin;
-        }
-
-        System.arraycopy(slack, begin, b, off, len);
-
-        if ((begin += len) >= slack.length) {
-            slack = null;
-        }
-
-        return len;
-    }
-
-    /**
-     * Marks the read limit of the StringReader.
-     *
-     * @param limit the maximum limit of bytes that can be read before the
-     *              mark position becomes invalid
-     */
-    public synchronized void mark(final int limit) {
-        try {
-            in.mark(limit);
-        } catch (IOException ioe) {
-            throw new RuntimeException(ioe.getMessage());
-        }
-    }
-
-
-    /**
-     * @return   the current number of bytes ready for reading
-     * @exception IOException if an error occurs
-     */
-    public synchronized int available() throws IOException {
-        if (in == null) {
-            throw new IOException("Stream Closed");
-        }
-        if (slack != null) {
-            return slack.length - begin;
-        }
-        if (in.ready()) {
-            return 1;
-        } else {
-            return 0;
-        }
-    }
-
-    /**
-     * @return false - mark is not supported
-     */
-    public boolean markSupported () {
-        return false;   // would be imprecise
-    }
-
-    /**
-     * Resets the StringReader.
-     *
-     * @exception IOException if the StringReader fails to be reset
-     */
-    public synchronized void reset() throws IOException {
-        if (in == null) {
-            throw new IOException("Stream Closed");
-        }
-        slack = null;
-        in.reset();
-    }
-
-    /**
-     * Closes the Stringreader.
-     *
-     * @exception IOException if the original StringReader fails to be closed
-     */
-    public synchronized void close() throws IOException {
-        if (in != null) {
-            in.close();
-            slack = null;
-            in = null;
-        }
-    }
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/cf2f7a93/utils/common/src/main/java/brooklyn/util/stream/StreamGobbler.java
----------------------------------------------------------------------
diff --git a/utils/common/src/main/java/brooklyn/util/stream/StreamGobbler.java b/utils/common/src/main/java/brooklyn/util/stream/StreamGobbler.java
deleted file mode 100644
index 7d5f9fe..0000000
--- a/utils/common/src/main/java/brooklyn/util/stream/StreamGobbler.java
+++ /dev/null
@@ -1,137 +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.stream;
-
-import java.io.Closeable;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.io.PrintStream;
-import java.util.concurrent.atomic.AtomicBoolean;
-
-import org.slf4j.Logger;
-
-public class StreamGobbler extends Thread implements Closeable {
-    
-    protected final InputStream stream;
-    protected final PrintStream out;
-    protected final Logger log;
-    private final AtomicBoolean running = new AtomicBoolean(true);
-    
-    public StreamGobbler(InputStream stream, OutputStream out, Logger log) {
-        this(stream, out != null ? new PrintStream(out) : null, log);
-    }
-
-    public StreamGobbler(InputStream stream, PrintStream out, Logger log) {
-        this.stream = stream;
-        this.out = out;
-        this.log = log;
-    }
-    
-    @Override
-    public void close() {
-        running.set(false);
-        interrupt();
-    }
-
-    /**
-     * @deprecate Use close() instead.
-     */
-    @Deprecated
-    public void shutdown() {
-        close();
-    }
-
-    String logPrefix = "";
-    String printPrefix = "";
-    public StreamGobbler setPrefix(String prefix) {
-        setLogPrefix(prefix);
-        setPrintPrefix(prefix);
-        return this;
-    }
-    public StreamGobbler setPrintPrefix(String prefix) {
-        printPrefix = prefix;
-        return this;
-    }
-    public StreamGobbler setLogPrefix(String prefix) {
-        logPrefix = prefix;
-        return this;
-    }    
-    
-    @Override
-    public void run() {
-        int c = -1;
-        try {
-            while (running.get() && (c=stream.read())>=0) {
-                onChar(c);
-            }
-            onClose();
-        } catch (IOException e) {
-            onClose();
-            //TODO parametrise log level, for this error, and for normal messages
-            if (log!=null && log.isTraceEnabled()) log.trace(logPrefix+"exception reading from stream ("+e+")");
-        }
-    }
-    
-    private final StringBuilder lineSoFar = new StringBuilder(16);
-    public void onChar(int c) {
-        if (c=='\n' || c=='\r') {
-            if (lineSoFar.length()>0)
-                //suppress blank lines, so that we can treat either newline char as a line separator
-                //(eg to show curl updates frequently)
-                onLine(lineSoFar.toString());
-            lineSoFar.setLength(0);
-        } else {
-            lineSoFar.append((char)c);
-        }
-    }
-    
-    public void onLine(String line) {
-        //right trim, in case there is \r or other funnies
-        while (line.length()>0 && Character.isWhitespace(line.charAt(line.length()-1)))
-            line = line.substring(0, line.length()-1);
-        //right trim, in case there is \r or other funnies
-        while (line.length()>0 && (line.charAt(0)=='\n' || line.charAt(0)=='\r'))
-            line = line.substring(1);
-        if (!line.isEmpty()) {
-            if (out!=null) out.println(printPrefix+line);
-            if (log!=null && log.isDebugEnabled()) log.debug(logPrefix+line);
-        }
-    }
-    
-    public void onClose() {
-        onLine(lineSoFar.toString());
-        if (out!=null) out.flush();
-        lineSoFar.setLength(0);
-        finished = true;
-        synchronized (this) { notifyAll(); }
-    }
-    
-    private volatile boolean finished = false;
-
-    /** convenience -- equivalent to calling join() */
-    public void blockUntilFinished() throws InterruptedException {
-        synchronized (this) { while (!finished) wait(); }
-    }
-
-    /** convenience -- similar to !Thread.isAlive() */
-    public boolean isFinished() {
-        return finished;
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/cf2f7a93/utils/common/src/main/java/brooklyn/util/stream/Streams.java
----------------------------------------------------------------------
diff --git a/utils/common/src/main/java/brooklyn/util/stream/Streams.java b/utils/common/src/main/java/brooklyn/util/stream/Streams.java
deleted file mode 100644
index d7f0a7d..0000000
--- a/utils/common/src/main/java/brooklyn/util/stream/Streams.java
+++ /dev/null
@@ -1,177 +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.stream;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import java.io.ByteArrayOutputStream;
-import java.io.Closeable;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.OutputStream;
-import java.io.Reader;
-import java.io.StringReader;
-import java.io.Writer;
-import java.nio.charset.Charset;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import brooklyn.util.exceptions.Exceptions;
-
-import com.google.common.annotations.Beta;
-import com.google.common.base.Charsets;
-import com.google.common.base.Function;
-import com.google.common.base.Preconditions;
-import com.google.common.base.Supplier;
-import com.google.common.io.ByteStreams;
-import com.google.common.io.CharStreams;
-
-/**
- * Methods to manage byte and character streams.
- *
- * @see com.google.common.io.ByteStreams
- * @see com.google.common.io.CharStreams
- */
-public class Streams {
-
-    private static final Logger log = LoggerFactory.getLogger(Streams.class);
-
-    /** drop-in non-deprecated replacement for {@link Closeable}'s deprecated closeQuiety;
-     * we may wish to review usages, particularly as we drop support for java 1.6,
-     * but until then use this instead of the deprecated method */
-    @Beta
-    public static void closeQuietly(Closeable x) {
-        try {
-            if (x!=null)
-                x.close();
-        } catch (Exception e) {
-            if (log.isDebugEnabled())
-                log.debug("Error closing (ignored) "+x+": "+e);
-        }
-    }
-
-    /** @deprecated since 0.7.0 use {@link #newInputStreamWithContents(String)} */ @Deprecated
-    public static InputStream fromString(String contents) {
-        return newInputStreamWithContents(contents);
-    }
-    
-    public static InputStream newInputStreamWithContents(String contents) {
-        byte[] bytes = checkNotNull(contents, "contents").getBytes(Charsets.UTF_8);
-        return KnownSizeInputStream.of(bytes);
-    }
-
-    public static Reader newReaderWithContents(String contents) {
-        return new StringReader(contents);
-    }
-    
-    public static Reader reader(InputStream stream) {
-        return new InputStreamReader(stream);
-    }
-    
-    public static Reader reader(InputStream stream, Charset charset) {
-        return new InputStreamReader(stream, charset);
-    }
-
-    /** reads the input stream fully, returning a byte array; throws unchecked exception on failure;
-     *  to get a string, use <code>readFully(reader(is))</code> or <code>readFullyString(is)</code> */
-    public static byte[] readFully(InputStream is) {
-        try {
-            return ByteStreams.toByteArray(is);
-        } catch (IOException ioe) {
-            throw Exceptions.propagate(ioe);
-        }
-    }
-
-    public static String readFullyString(InputStream is) {
-        return readFully(reader(is));
-    }
-    
-    public static String readFully(Reader is) {
-        try {
-            return CharStreams.toString(is);
-        } catch (IOException ioe) {
-            throw Exceptions.propagate(ioe);
-        }
-    }
-
-    public static void copy(InputStream input, OutputStream output) {
-        try {
-            ByteStreams.copy(input, output);
-            output.flush();
-        } catch (IOException ioe) {
-            throw Exceptions.propagate(ioe);
-        }
-    }
-
-    public static void copy(Reader input, Writer output) {
-        try {
-            CharStreams.copy(input, output);
-            output.flush();
-        } catch (IOException ioe) {
-            throw Exceptions.propagate(ioe);
-        }
-    }
-
-    public static Supplier<Integer> sizeSupplier(final ByteArrayOutputStream src) {
-        Preconditions.checkNotNull(src);
-        return new Supplier<Integer>() {
-            @Override
-            public Integer get() {
-                return src.size();
-            }
-        };
-    }
-
-    public static Function<ByteArrayOutputStream,Integer> sizeFunction() {
-        return new Function<ByteArrayOutputStream,Integer>() {
-            @Override
-            public Integer apply(ByteArrayOutputStream input) {
-                return input.size();
-            }
-        };
-    }
-
-    public static ByteArrayOutputStream byteArrayOfString(String in) {
-        return byteArray(in.getBytes(Charsets.UTF_8));
-    }
-
-    public static ByteArrayOutputStream byteArray(byte[] in) {
-        ByteArrayOutputStream stream = new ByteArrayOutputStream();
-        try {
-            stream.write(in);
-        } catch (IOException e) {
-            throw Exceptions.propagate(e);
-        }
-        return stream;
-    }
-
-    public static boolean logStreamTail(Logger log, String message, ByteArrayOutputStream stream, int max) {
-        if (stream!=null && stream.size()>0) {
-            String streamS = stream.toString();
-            if (max>=0 && streamS.length()>max)
-                streamS = "... "+streamS.substring(streamS.length()-max);
-            log.info(message+":\n"+streamS);
-            return true;
-        }
-        return false;
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/cf2f7a93/utils/common/src/main/java/brooklyn/util/stream/ThreadLocalPrintStream.java
----------------------------------------------------------------------
diff --git a/utils/common/src/main/java/brooklyn/util/stream/ThreadLocalPrintStream.java b/utils/common/src/main/java/brooklyn/util/stream/ThreadLocalPrintStream.java
deleted file mode 100644
index 408aad8..0000000
--- a/utils/common/src/main/java/brooklyn/util/stream/ThreadLocalPrintStream.java
+++ /dev/null
@@ -1,137 +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.stream;
-
-import java.io.ByteArrayOutputStream;
-import java.io.OutputStream;
-import java.io.PrintStream;
-
-import org.apache.commons.io.output.TeeOutputStream;
-
-public class ThreadLocalPrintStream extends DelegatingPrintStream {
-
-    protected PrintStream defaultPrintStream;
-    protected final ThreadLocal<PrintStream> customStream = new ThreadLocal<PrintStream>();
-    
-    public ThreadLocalPrintStream(PrintStream defaultPrintStream) {
-        this.defaultPrintStream = defaultPrintStream;
-    }
-    
-    @Override
-    public PrintStream getDelegate() {
-        PrintStream delegate = customStream.get();
-        if (delegate!=null) return delegate;
-        return defaultPrintStream;
-    }
-
-    /** sets the PrintStream that callers from this thread should see;
-     * returns any previously custom PrintStream for this thread */
-    public PrintStream setThreadLocalPrintStream(OutputStream stream) {
-        PrintStream old = customStream.get();
-        if (!(stream instanceof PrintStream))
-            stream = new PrintStream(stream);
-        customStream.set((PrintStream)stream);
-        return old;
-    }
-
-    public PrintStream clearThreadLocalPrintStream() {
-        PrintStream old = customStream.get();
-        customStream.remove();
-        if (old!=null) old.flush();
-        return old;
-    }
-    
-    /** creates a capturing context which eats the output to this stream, blocking the original target */
-    public OutputCapturingContext capture() {
-        return new OutputCapturingContext(this);
-    }
-    
-    /** creates a capturing context which sees the output to this stream, without interrupting the original target */
-    public OutputCapturingContext captureTee() {
-        ByteArrayOutputStream out = new ByteArrayOutputStream();
-        PrintStream toRestore = setThreadLocalPrintStream(new TeeOutputStream(getDelegate(), out));
-        return new OutputCapturingContext(this, out, toRestore);
-    }
-    
-    public static class OutputCapturingContext {
-        protected final ThreadLocalPrintStream stream;
-        protected final ByteArrayOutputStream out;
-        protected final OutputStream streamToRestore;
-        protected boolean finished = false;
-        /** constructor which installs a ByteArrayOutputStream to this stream */
-        public OutputCapturingContext(ThreadLocalPrintStream stream) {
-            this.stream = stream;
-            this.out = new ByteArrayOutputStream();
-            this.streamToRestore = stream.setThreadLocalPrintStream(out);
-        }
-        /** constructor for a capturing context which is already installed */
-        public OutputCapturingContext(ThreadLocalPrintStream stream, ByteArrayOutputStream capturingStream, OutputStream optionalStreamToRestore) {
-            this.stream = stream;
-            this.out = capturingStream;
-            this.streamToRestore = optionalStreamToRestore;
-        }
-        public String getOutputSoFar() {
-            return out.toString();
-        }
-        public String end() {
-            if (streamToRestore!=null)
-                stream.setThreadLocalPrintStream(streamToRestore);
-            else
-                stream.clearThreadLocalPrintStream();
-            finished = true;
-            return out.toString();
-        }
-        public boolean isActive() {
-            return !finished;
-        }
-        public ByteArrayOutputStream getOutputStream() {
-            return out;
-        }
-        @Override
-        public String toString() {
-            return getOutputSoFar();
-        }
-        public boolean isEmpty() {
-            return out.size()==0;
-        }
-    }
-    
-    /** installs a thread local print stream to System.out if one is not already set;
-     * caller may then #capture and #captureTee on it.
-     * @return the ThreadLocalPrintStream which System.out is using */
-    public synchronized static ThreadLocalPrintStream stdout() {
-        PrintStream oldOut = System.out;
-        if (oldOut instanceof ThreadLocalPrintStream) return (ThreadLocalPrintStream)oldOut;
-        ThreadLocalPrintStream newOut = new ThreadLocalPrintStream(System.out);
-        System.setOut(newOut);
-        return newOut;
-    }
-
-    /** installs a thread local print stream to System.err if one is not already set;
-     * caller may then #capture and #captureTee on it.
-     * @return the ThreadLocalPrintStream which System.err is using */
-    public synchronized static ThreadLocalPrintStream stderr() {
-        PrintStream oldErr = System.err;
-        if (oldErr instanceof ThreadLocalPrintStream) return (ThreadLocalPrintStream)oldErr;
-        ThreadLocalPrintStream newErr = new ThreadLocalPrintStream(System.err);
-        System.setErr(newErr);
-        return newErr;
-    }
-
-}