http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/cf2f7a93/utils/common/src/main/java/brooklyn/util/text/StringPredicates.java
----------------------------------------------------------------------
diff --git 
a/utils/common/src/main/java/brooklyn/util/text/StringPredicates.java 
b/utils/common/src/main/java/brooklyn/util/text/StringPredicates.java
deleted file mode 100644
index f83b139..0000000
--- a/utils/common/src/main/java/brooklyn/util/text/StringPredicates.java
+++ /dev/null
@@ -1,310 +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.text;
-
-import java.io.Serializable;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Set;
-
-import javax.annotation.Nullable;
-
-import brooklyn.util.collections.MutableSet;
-
-import com.google.common.base.Function;
-import com.google.common.base.Predicate;
-import com.google.common.base.Predicates;
-import com.google.common.collect.Iterables;
-import com.google.common.collect.Lists;
-
-public class StringPredicates {
-
-    /** predicate form of {@link Strings#isBlank(CharSequence)} */
-    public static <T extends CharSequence> Predicate<T> isBlank() {
-        return new IsBlank<T>();
-    }
-
-    private static final class IsBlank<T extends CharSequence> implements 
Predicate<T> {
-        @Override
-        public boolean apply(@Nullable CharSequence input) {
-            return Strings.isBlank(input);
-        }
-
-        @Override
-        public String toString() {
-            return "isBlank()";
-        }
-    }
-
-    /** @deprecated since 0.7.0 kept only to allow conversion of anonymous 
inner classes */
-    @SuppressWarnings("unused") @Deprecated 
-    private static Predicate<CharSequence> isBlankOld() {
-        return new Predicate<CharSequence>() {
-            @Override
-            public boolean apply(@Nullable CharSequence input) {
-                return Strings.isBlank(input);
-            }
-            @Override
-            public String toString() {
-                return "isBlank";
-            }
-        };
-    }
-
-
-    /** Tests if object is non-null and not a blank string.
-     * <p>
-     * Predicate form of {@link Strings#isNonBlank(CharSequence)} also 
accepting objects non-null, for convenience */
-    public static <T> Predicate<T> isNonBlank() {
-        return new IsNonBlank<T>();
-    }
-
-    private static final class IsNonBlank<T> implements Predicate<T> {
-        @Override
-        public boolean apply(@Nullable Object input) {
-            if (input==null) return false;
-            if (!(input instanceof CharSequence)) return true;
-            return Strings.isNonBlank((CharSequence)input);
-        }
-
-        @Override
-        public String toString() {
-            return "isNonBlank()";
-        }
-    }
-    
-    // -----------------
-    
-    public static <T extends CharSequence> Predicate<T> 
containsLiteralIgnoreCase(final String fragment) {
-        return new ContainsLiteralIgnoreCase<T>(fragment);
-    }
-
-    private static final class ContainsLiteralIgnoreCase<T extends 
CharSequence> implements Predicate<T> {
-        private final String fragment;
-
-        private ContainsLiteralIgnoreCase(String fragment) {
-            this.fragment = fragment;
-        }
-
-        @Override
-        public boolean apply(@Nullable CharSequence input) {
-            return Strings.containsLiteralIgnoreCase(input, fragment);
-        }
-
-        @Override
-        public String toString() {
-            return "containsLiteralCaseInsensitive("+fragment+")";
-        }
-    }
-
-    public static <T extends CharSequence> Predicate<T> containsLiteral(final 
String fragment) {
-        return new ContainsLiteral<T>(fragment);
-    }
-    
-    private static final class ContainsLiteral<T extends CharSequence> 
implements Predicate<T> {
-        private final String fragment;
-
-        private ContainsLiteral(String fragment) {
-            this.fragment = fragment;
-        }
-
-        @Override
-        public boolean apply(@Nullable CharSequence input) {
-            return Strings.containsLiteral(input, fragment);
-        }
-
-        @Override
-        public String toString() {
-            return "containsLiteral("+fragment+")";
-        }
-    }
-
-    /** @deprecated since 0.7.0 kept only to allow conversion of anonymous 
inner classes */
-    @SuppressWarnings("unused") @Deprecated 
-    private static Predicate<CharSequence> 
containsLiteralCaseInsensitiveOld(final String fragment) {
-        return new Predicate<CharSequence>() {
-            @Override
-            public boolean apply(@Nullable CharSequence input) {
-                return Strings.containsLiteralIgnoreCase(input, fragment);
-            }
-            @Override
-            public String toString() {
-                return "containsLiteralCaseInsensitive("+fragment+")";
-            }
-        };
-    }
-
-    /** @deprecated since 0.7.0 kept only to allow conversion of anonymous 
inner classes */
-    @SuppressWarnings("unused") @Deprecated 
-    private static Predicate<CharSequence> containsLiteralOld(final String 
fragment) {
-        return new Predicate<CharSequence>() {
-            @Override
-            public boolean apply(@Nullable CharSequence input) {
-                return Strings.containsLiteral(input, fragment);
-            }
-            @Override
-            public String toString() {
-                return "containsLiteral("+fragment+")";
-            }
-        };
-    }
-    
-    // -----------------
-    
-    public static <T extends CharSequence> Predicate<T> 
containsAllLiterals(final String... fragments) {
-        List<Predicate<CharSequence>> fragmentPredicates = 
Lists.newArrayList();
-        for (String fragment : fragments) {
-            fragmentPredicates.add(containsLiteral(fragment));
-        }
-        return Predicates.and(fragmentPredicates);
-    }
-
-    /** @deprecated since 0.7.0 kept only to allow conversion of anonymous 
inner classes */
-    @SuppressWarnings("unused") @Deprecated 
-    private static Predicate<CharSequence> containsAllLiteralsOld(final 
String... fragments) {
-        return Predicates.and(Iterables.transform(Arrays.asList(fragments), 
new Function<String,Predicate<CharSequence>>() {
-            @Override
-            public Predicate<CharSequence> apply(String input) {
-                return containsLiteral(input);
-            }
-        }));
-    }
-    
-    // -----------------
-
-    public static Predicate<CharSequence> containsRegex(final String regex) {
-        // "Pattern" ... what a bad name :)
-        return Predicates.containsPattern(regex);
-    }
-
-    // -----------------
-    
-    public static <T extends CharSequence> Predicate<T> startsWith(final 
String prefix) {
-        return new StartsWith<T>(prefix);
-    }
-
-    private static final class StartsWith<T extends CharSequence> implements 
Predicate<T> {
-        private final String prefix;
-        private StartsWith(String prefix) {
-            this.prefix = prefix;
-        }
-        @Override
-        public boolean apply(CharSequence input) {
-            return (input != null) && input.toString().startsWith(prefix);
-        }
-        @Override
-        public String toString() {
-            return "startsWith("+prefix+")";
-        }
-    }
-
-    /** @deprecated since 0.7.0 kept only to allow conversion of anonymous 
inner classes */
-    @SuppressWarnings("unused") @Deprecated 
-    private static Predicate<CharSequence> startsWithOld(final String prefix) {
-        return new Predicate<CharSequence>() {
-            @Override
-            public boolean apply(CharSequence input) {
-                return (input != null) && input.toString().startsWith(prefix);
-            }
-        };
-    }
-
-    // -----------------
-    
-    /** true if the object *is* a {@link CharSequence} starting with the given 
prefix */
-    public static Predicate<Object> isStringStartingWith(final String prefix) {
-        return 
Predicates.<Object>and(Predicates.instanceOf(CharSequence.class),
-            Predicates.compose(startsWith(prefix), 
StringFunctions.toStringFunction()));
-    }
-
-    /** @deprecated since 0.7.0 kept only to allow conversion of anonymous 
inner classes */
-    @SuppressWarnings("unused") @Deprecated 
-    private static Predicate<Object> isStringStartingWithOld(final String 
prefix) {
-        return new Predicate<Object>() {
-            @Override
-            public boolean apply(Object input) {
-                return (input instanceof CharSequence) && 
input.toString().startsWith(prefix);
-            }
-        };
-    }
-
-    // ---------------
-    
-    public static <T> Predicate<T> equalToAny(Iterable<T> vals) {
-        return new EqualToAny<T>(vals);
-    }
-
-    private static class EqualToAny<T> implements Predicate<T>, Serializable {
-        private static final long serialVersionUID = 6209304291945204422L;
-        private final Set<T> vals;
-        
-        public EqualToAny(Iterable<? extends T> vals) {
-            this.vals = MutableSet.copyOf(vals); // so allows nulls
-        }
-        @Override
-        public boolean apply(T input) {
-            return vals.contains(input);
-        }
-        @Override
-        public String toString() {
-            return "equalToAny("+vals+")";
-        }
-    }
-
-    // -----------
-    
-    public static <T extends CharSequence> Predicate<T> matchesRegex(final 
String regex) {
-        return new MatchesRegex<T>(regex);
-    }
-
-    protected static class MatchesRegex<T extends CharSequence> implements 
Predicate<T> {
-        protected final String regex;
-        protected MatchesRegex(String regex) {
-            this.regex = regex;
-        }
-        @Override
-        public boolean apply(CharSequence input) {
-            return (input != null) && input.toString().matches(regex);
-        }
-        @Override
-        public String toString() {
-            return "matchesRegex("+regex+")";
-        }
-    }
-    
-    public static <T extends CharSequence> Predicate<T> matchesGlob(final 
String glob) {
-        return new MatchesGlob<T>(glob);
-    }
-
-    protected static class MatchesGlob<T extends CharSequence> implements 
Predicate<T> {
-        protected final String glob;
-        protected MatchesGlob(String glob) {
-            this.glob = glob;
-        }
-        @Override
-        public boolean apply(CharSequence input) {
-            return (input != null) && WildcardGlobs.isGlobMatched(glob, 
input.toString());
-        }
-        @Override
-        public String toString() {
-            return "matchesGlob("+glob+")";
-        }
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/cf2f7a93/utils/common/src/main/java/brooklyn/util/text/StringShortener.java
----------------------------------------------------------------------
diff --git a/utils/common/src/main/java/brooklyn/util/text/StringShortener.java 
b/utils/common/src/main/java/brooklyn/util/text/StringShortener.java
deleted file mode 100644
index 816007a..0000000
--- a/utils/common/src/main/java/brooklyn/util/text/StringShortener.java
+++ /dev/null
@@ -1,150 +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.text;
-
-import java.util.ArrayList;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-
-/** utility which takes a bunch of segments and applies shortening rules to 
them */
-public class StringShortener {
-
-    protected Map<String,String> wordsByIdInOrder = new 
LinkedHashMap<String,String>();
-    protected String separator = null;
-    
-    protected interface ShorteningRule {
-        /** returns the new list, with the relevant items in the list replaced 
*/
-        public int apply(LinkedHashMap<String, String> words, int maxlen, int 
length);
-    }
-    
-    protected class TruncationRule implements ShorteningRule {
-        public TruncationRule(String id, int len) {
-            this.id = id;
-            this.len = len;
-        }
-        String id;
-        int len;
-        
-        public int apply(LinkedHashMap<String, String> words, int maxlen, int 
length) {
-            String v = words.get(id);
-            if (v!=null && v.length()>len) {
-                int charsToRemove = v.length() - len;
-                if (length-charsToRemove < maxlen) charsToRemove = 
length-maxlen;
-                words.put(id, v.substring(0, v.length() - charsToRemove));
-                length -= charsToRemove;
-                if (charsToRemove==v.length() && separator!=null && length>0)
-                    length -= separator.length();
-            }
-            return length;
-        }
-    }
-    
-    protected class RemovalRule implements ShorteningRule {
-        public RemovalRule(String id) {
-            this.id = id;
-        }
-        String id;
-        
-        public int apply(LinkedHashMap<String, String> words, int maxlen, int 
length) {
-            String v = words.get(id);
-            if (v!=null) {
-                words.remove(id);
-                length -= v.length();
-                if (separator!=null && length>0)
-                    length -= separator.length();
-            }
-            return length;
-        }
-    }
-    
-    private List<ShorteningRule> rules = new 
ArrayList<StringShortener.ShorteningRule>();
-    
-
-    public StringShortener separator(String separator) {
-        this.separator = separator;
-        return this;
-    }
-
-    public StringShortener append(String id, String text) {
-        String old = wordsByIdInOrder.put(id, text);
-        if (old!=null) {
-            throw new IllegalStateException("Cannot append with id '"+id+"' 
when id already present");
-        }
-        // TODO expose a replace or update
-        return this;
-    }
-
-    public StringShortener truncate(String id, int len) {
-        String v = wordsByIdInOrder.get(id);
-        if (v!=null && v.length()>len) {
-            wordsByIdInOrder.put(id, v.substring(0, len));
-        }
-        return this;
-    }
-
-    public StringShortener canTruncate(String id, int len) {
-        rules.add(new TruncationRule(id, len));
-        return this;
-    }
-
-    public StringShortener canRemove(String id) {
-        rules.add(new RemovalRule(id));
-        return this;
-    }
-
-    public String getStringOfMaxLength(int maxlen) {
-        LinkedHashMap<String, String> words = new 
LinkedHashMap<String,String>();
-        words.putAll(wordsByIdInOrder);
-        int length = 0;
-        for (String w: words.values()) {
-            if (!Strings.isBlank(w)) {
-                length += w.length();
-                if (separator!=null)
-                    length += separator.length();
-            }
-        }
-        if (separator!=null && length>0)
-            // remove trailing separator if one had been added
-            length -= separator.length();
-        
-        List<ShorteningRule> rulesLeft = new ArrayList<ShorteningRule>();
-        rulesLeft.addAll(rules);
-        
-        while (length > maxlen && !rulesLeft.isEmpty()) {
-            ShorteningRule r = rulesLeft.remove(0);
-            length = r.apply(words, maxlen, length);
-        }
-        
-        StringBuilder sb = new StringBuilder();
-        for (String w: words.values()) {
-            if (!Strings.isBlank(w)) {
-                if (separator!=null && sb.length()>0)
-                    sb.append(separator);
-                sb.append(w);
-            }
-        }
-        
-        String result = sb.toString();
-        if (result.length() > maxlen) result = result.substring(0, maxlen);
-        
-        return result;
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/cf2f7a93/utils/common/src/main/java/brooklyn/util/text/Strings.java
----------------------------------------------------------------------
diff --git a/utils/common/src/main/java/brooklyn/util/text/Strings.java 
b/utils/common/src/main/java/brooklyn/util/text/Strings.java
deleted file mode 100644
index 5aa2089..0000000
--- a/utils/common/src/main/java/brooklyn/util/text/Strings.java
+++ /dev/null
@@ -1,945 +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.text;
-
-import java.text.DecimalFormat;
-import java.text.DecimalFormatSymbols;
-import java.text.NumberFormat;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-import java.util.StringTokenizer;
-
-import javax.annotation.Nullable;
-
-import brooklyn.util.collections.MutableList;
-import brooklyn.util.collections.MutableMap;
-import brooklyn.util.guava.Maybe;
-import brooklyn.util.time.Time;
-
-import com.google.common.base.CharMatcher;
-import com.google.common.base.Functions;
-import com.google.common.base.Joiner;
-import com.google.common.base.Preconditions;
-import com.google.common.base.Predicate;
-import com.google.common.base.Supplier;
-import com.google.common.base.Suppliers;
-import com.google.common.collect.Ordering;
-
-public class Strings {
-
-    /** The empty {@link String}. */
-    public static final String EMPTY = "";
-
-    /**
-     * Checks if the given string is null or is an empty string.
-     * Useful for pre-String.isEmpty.  And useful for StringBuilder etc.
-     *
-     * @param s the String to check
-     * @return true if empty or null, false otherwise.
-     *
-     * @see #isNonEmpty(CharSequence)
-     * @see #isBlank(CharSequence)
-     * @see #isNonBlank(CharSequence)
-     */
-    public static boolean isEmpty(CharSequence s) {
-        // Note guava has com.google.common.base.Strings.isNullOrEmpty(String),
-        // but that is just for String rather than CharSequence
-        return s == null || s.length()==0;
-    }
-
-    /**
-     * Checks if the given string is empty or only consists of whitespace.
-     *
-     * @param s the String to check
-     * @return true if blank, empty or null, false otherwise.
-     *
-     * @see #isEmpty(CharSequence)
-     * @see #isNonEmpty(CharSequence)
-     * @see #isNonBlank(CharSequence)
-     */
-    public static boolean isBlank(CharSequence s) {
-        return isEmpty(s) || CharMatcher.WHITESPACE.matchesAllOf(s);
-    }
-
-    /**
-     * The inverse of {@link #isEmpty(CharSequence)}.
-     *
-     * @param s the String to check
-     * @return true if non empty, false otherwise.
-     *
-     * @see #isEmpty(CharSequence)
-     * @see #isBlank(CharSequence)
-     * @see #isNonBlank(CharSequence)
-     */
-    public static boolean isNonEmpty(CharSequence s) {
-        return !isEmpty(s);
-    }
-
-    /**
-     * The inverse of {@link #isBlank(CharSequence)}.
-     *
-     * @param s the String to check
-     * @return true if non blank, false otherwise.
-     *
-     * @see #isEmpty(CharSequence)
-     * @see #isNonEmpty(CharSequence)
-     * @see #isBlank(CharSequence)
-     */
-    public static boolean isNonBlank(CharSequence s) {
-        return !isBlank(s);
-    }
-
-    /** @return a {@link Maybe} object which is absent if the argument {@link 
#isBlank(CharSequence)} */
-    public static <T extends CharSequence> Maybe<T> maybeNonBlank(T s) {
-        if (isNonBlank(s)) return Maybe.of(s);
-        return Maybe.absent();
-    }
-
-    /** throws IllegalArgument if string not empty; cf. guava 
Preconditions.checkXxxx */
-    public static void checkNonEmpty(CharSequence s) {
-        if (s==null) throw new IllegalArgumentException("String must not be 
null");
-        if (s.length()==0) throw new IllegalArgumentException("String must not 
be empty");
-    }
-    /** throws IllegalArgument if string not empty; cf. guava 
Preconditions.checkXxxx */
-    public static void checkNonEmpty(CharSequence s, String message) {
-        if (isEmpty(s)) throw new IllegalArgumentException(message);
-    }
-
-    /**
-     * Removes suffix from the end of the string. Returns string if it does 
not end with suffix.
-     */
-    public static String removeFromEnd(String string, String suffix) {
-        if (isEmpty(string)) {
-            return string;
-        } else if (!isEmpty(suffix) && string.endsWith(suffix)) {
-            return string.substring(0, string.length() - suffix.length());
-        } else {
-            return string;
-        }
-    }
-
-    /** removes the first suffix in the list which is present at the end of 
string
-     * and returns that string; ignores subsequent suffixes if a matching one 
is found;
-     * returns the original string if no suffixes are at the end
-     * @deprecated since 0.7.0 use {@link #removeFromEnd(String, String)} or 
{@link #removeAllFromEnd(String, String...)}
-     */
-    @Deprecated
-    public static String removeFromEnd(String string, String ...suffixes) {
-        if (isEmpty(string)) return string;
-        for (String suffix : suffixes)
-            if (suffix!=null && string.endsWith(suffix)) return 
string.substring(0, string.length() - suffix.length());
-        return string;
-    }
-
-    /**
-     * As removeFromEnd, but repeats until all such suffixes are gone
-     */
-    public static String removeAllFromEnd(String string, String... suffixes) {
-        if (isEmpty(string)) return string;
-        int index = string.length();
-        boolean anotherLoopNeeded = true;
-        while (anotherLoopNeeded) {
-            if (isEmpty(string)) return string;
-            anotherLoopNeeded = false;
-            for (String suffix : suffixes)
-                if (!isEmpty(suffix) && string.startsWith(suffix, index - 
suffix.length())) {
-                    index -= suffix.length();
-                    anotherLoopNeeded = true;
-                    break;
-                }
-        }
-        return string.substring(0, index);
-    }
-
-    /**
-     * Removes prefix from the beginning of string. Returns string if it does 
not begin with prefix.
-     */
-    public static String removeFromStart(String string, String prefix) {
-        if (isEmpty(string)) {
-            return string;
-        } else if (!isEmpty(prefix) && string.startsWith(prefix)) {
-            return string.substring(prefix.length());
-        } else {
-            return string;
-        }
-    }
-
-    /** removes the first prefix in the list which is present at the start of 
string
-     * and returns that string; ignores subsequent prefixes if a matching one 
is found;
-     * returns the original string if no prefixes match
-     * @deprecated since 0.7.0 use {@link #removeFromStart(String, String)}
-     */
-    @Deprecated
-    public static String removeFromStart(String string, String ...prefixes) {
-        if (isEmpty(string)) return string;
-        for (String prefix : prefixes)
-            if (prefix!=null && string.startsWith(prefix)) return 
string.substring(prefix.length());
-        return string;
-    }
-
-    /**
-     * As {@link #removeFromStart(String, String)}, repeating until all such 
prefixes are gone.
-     */
-    public static String removeAllFromStart(String string, String... prefixes) 
{
-        int index = 0;
-        boolean anotherLoopNeeded = true;
-        while (anotherLoopNeeded) {
-            if (isEmpty(string)) return string;
-            anotherLoopNeeded = false;
-            for (String prefix : prefixes) {
-                if (!isEmpty(prefix) && string.startsWith(prefix, index)) {
-                    index += prefix.length();
-                    anotherLoopNeeded = true;
-                    break;
-                }
-            }
-        }
-        return string.substring(index);
-    }
-
-    /** convenience for {@link com.google.common.base.Joiner} */
-    public static String join(Iterable<? extends Object> list, String 
separator) {
-        if (list==null) return null;
-        boolean app = false;
-        StringBuilder out = new StringBuilder();
-        for (Object s: list) {
-            if (app) out.append(separator);
-            out.append(s);
-            app = true;
-        }
-        return out.toString();
-    }
-    /** convenience for {@link com.google.common.base.Joiner} */
-    public static String join(Object[] list, String separator) {
-        boolean app = false;
-        StringBuilder out = new StringBuilder();
-        for (Object s: list) {
-            if (app) out.append(separator);
-            out.append(s);
-            app = true;
-        }
-        return out.toString();
-    }
-
-    /** convenience for joining lines together */
-    public static String lines(String ...lines) {
-        return Joiner.on("\n").join(Arrays.asList(lines));
-    }
-
-    /** NON-REGEX - replaces all key->value entries from the replacement map 
in source (non-regex) */
-    @SuppressWarnings("rawtypes")
-    public static String replaceAll(String source, Map replacements) {
-        for (Object rr: replacements.entrySet()) {
-            Map.Entry r = (Map.Entry)rr;
-            source = replaceAllNonRegex(source, ""+r.getKey(), 
""+r.getValue());
-        }
-        return source;
-    }
-
-    /** NON-REGEX replaceAll - see the better, explicitly named {@link 
#replaceAllNonRegex(String, String, String)}. */
-    public static String replaceAll(String source, String pattern, String 
replacement) {
-        return replaceAllNonRegex(source, pattern, replacement);
-    }
-
-    /** 
-     * Replaces all instances in source, of the given pattern, with the given 
replacement
-     * (not interpreting any arguments as regular expressions).
-     * <p>
-     * This is actually the same as the very ambiguous {@link 
String#replace(CharSequence, CharSequence)},
-     * which does replace all, but not using regex like the similarly 
ambiguous {@link String#replaceAll(String, String)} as.
-     * Alternatively see {@link #replaceAllRegex(String, String, String)}.
-     */
-    public static String replaceAllNonRegex(String source, String pattern, 
String replacement) {
-        if (source==null) return source;
-        StringBuilder result = new StringBuilder(source.length());
-        for (int i=0; i<source.length(); ) {
-            if (source.substring(i).startsWith(pattern)) {
-                result.append(replacement);
-                i += pattern.length();
-            } else {
-                result.append(source.charAt(i));
-                i++;
-            }
-        }
-        return result.toString();
-    }
-
-    /** REGEX replacement -- explicit method name for reabaility, doing same 
as {@link String#replaceAll(String, String)}. */
-    public static String replaceAllRegex(String source, String pattern, String 
replacement) {
-        return source.replaceAll(pattern, replacement);
-    }
-
-    /** Valid non alphanumeric characters for filenames. */
-    public static final String VALID_NON_ALPHANUM_FILE_CHARS = "-_.";
-
-    /**
-     * Returns a valid filename based on the input.
-     *
-     * A valid filename starts with the first alphanumeric character, then 
include
-     * all alphanumeric characters plus those in {@link 
#VALID_NON_ALPHANUM_FILE_CHARS},
-     * with any runs of invalid characters being replaced by {@literal _}.
-     *
-     * @throws NullPointerException if the input string is null.
-     * @throws IllegalArgumentException if the input string is blank.
-     */
-    public static String makeValidFilename(String s) {
-        Preconditions.checkNotNull(s, "Cannot make valid filename from null 
string");
-        Preconditions.checkArgument(isNonBlank(s), "Cannot make valid filename 
from blank string");
-        return 
CharMatcher.anyOf(VALID_NON_ALPHANUM_FILE_CHARS).or(CharMatcher.JAVA_LETTER_OR_DIGIT)
-                .negate()
-                .trimAndCollapseFrom(s, '_');
-    }
-
-    /**
-     * A {@link CharMatcher} that matches valid Java identifier characters.
-     *
-     * @see Character#isJavaIdentifierPart(char)
-     */
-    public static final CharMatcher IS_JAVA_IDENTIFIER_PART = 
CharMatcher.forPredicate(new Predicate<Character>() {
-        @Override
-        public boolean apply(@Nullable Character input) {
-            return input != null && Character.isJavaIdentifierPart(input);
-        }
-    });
-
-    /**
-     * Returns a valid Java identifier name based on the input.
-     *
-     * Removes certain characterss (like apostrophe), replaces one or more 
invalid
-     * characterss with {@literal _}, and prepends {@literal _} if the first 
character
-     * is only valid as an identifier part (not start).
-     * <p>
-     * The result is usually unique to s, though this isn't guaranteed, for 
example if
-     * all characters are invalid. For a unique identifier use {@link 
#makeValidUniqueJavaName(String)}.
-     *
-     * @see #makeValidUniqueJavaName(String)
-     */
-    public static String makeValidJavaName(String s) {
-        if (s==null) return "__null";
-        if (s.length()==0) return "__empty";
-        String name = 
IS_JAVA_IDENTIFIER_PART.negate().collapseFrom(CharMatcher.is('\'').removeFrom(s),
 '_');
-        if (!Character.isJavaIdentifierStart(s.charAt(0))) return "_" + name;
-        return name;
-    }
-
-    /**
-     * Returns a unique valid java identifier name based on the input.
-     *
-     * Translated as per {@link #makeValidJavaName(String)} but with {@link 
String#hashCode()}
-     * appended where necessary to guarantee uniqueness.
-     *
-     * @see #makeValidJavaName(String)
-     */
-    public static String makeValidUniqueJavaName(String s) {
-        String name = makeValidJavaName(s);
-        if (isEmpty(s) || IS_JAVA_IDENTIFIER_PART.matchesAllOf(s) || 
CharMatcher.is('\'').matchesNoneOf(s)) {
-            return name;
-        } else {
-            return name + "_" + s.hashCode();
-        }
-    }
-
-    /** @see {@link Identifiers#makeRandomId(int)} */
-    public static String makeRandomId(int l) {
-        return Identifiers.makeRandomId(l);
-    }
-
-    /** pads the string with 0's at the left up to len; no padding if i longer 
than len */
-    public static String makeZeroPaddedString(int i, int len) {
-        return makePaddedString(""+i, len, "0", "");
-    }
-
-    /** pads the string with "pad" at the left up to len; no padding if base 
longer than len */
-    public static String makePaddedString(String base, int len, String 
left_pad, String right_pad) {
-        String s = ""+(base==null ? "" : base);
-        while (s.length()<len) s=left_pad+s+right_pad;
-        return s;
-    }
-
-    public static void trimAll(String[] s) {
-        for (int i=0; i<s.length; i++)
-            s[i] = (s[i]==null ? "" : s[i].trim());
-    }
-
-    /** creates a string from a real number, with specified accuracy (more iff 
it comes for free, ie integer-part);
-     * switches to E notation if needed to fit within maxlen; can be padded 
left up too (not useful)
-     * @param x number to use
-     * @param maxlen maximum length for the numeric string, if possible (-1 to 
suppress)
-     * @param prec number of digits accuracy desired (more kept for integers)
-     * @param leftPadLen will add spaces at left if necessary to make string 
this long (-1 to suppress) [probably not usef]
-     * @return such a string
-     */
-    public static String makeRealString(double x, int maxlen, int prec, int 
leftPadLen) {
-        return makeRealString(x, maxlen, prec, leftPadLen, 0.00000000001, 
true);
-    }
-    /** creates a string from a real number, with specified accuracy (more iff 
it comes for free, ie integer-part);
-     * switches to E notation if needed to fit within maxlen; can be padded 
left up too (not useful)
-     * @param x number to use
-     * @param maxlen maximum length for the numeric string, if possible (-1 to 
suppress)
-     * @param prec number of digits accuracy desired (more kept for integers)
-     * @param leftPadLen will add spaces at left if necessary to make string 
this long (-1 to suppress) [probably not usef]
-     * @param skipDecimalThreshhold if positive it will not add a decimal part 
if the fractional part is less than this threshhold
-     *    (but for a value 3.00001 it would show zeroes, e.g. with 3 precision 
and positive threshhold <= 0.00001 it would show 3.00);
-     *    if zero or negative then decimal digits are always shown
-     * @param useEForSmallNumbers whether to use E notation for numbers near 
zero (e.g. 0.001)
-     * @return such a string
-     */
-    public static String makeRealString(double x, int maxlen, int prec, int 
leftPadLen, double skipDecimalThreshhold, boolean useEForSmallNumbers) {
-        if (x<0) return "-"+makeRealString(-x, maxlen, prec, leftPadLen);
-        NumberFormat df = DecimalFormat.getInstance();
-        //df.setMaximumFractionDigits(maxlen);
-        df.setMinimumFractionDigits(0);
-        //df.setMaximumIntegerDigits(prec);
-        df.setMinimumIntegerDigits(1);
-        df.setGroupingUsed(false);
-        String s;
-        if (x==0) {
-            if (skipDecimalThreshhold>0 || prec<=1) s="0";
-            else {
-                s="0.0";
-                while (s.length()<prec+1) s+="0";
-            }
-        } else {
-//            long bits= Double.doubleToLongBits(x);
-//            int s = ((bits >> 63) == 0) ? 1 : -1;
-//            int e = (int)((bits >> 52) & 0x7ffL);
-//            long m = (e == 0) ?
-//            (bits & 0xfffffffffffffL) << 1 :
-//            (bits & 0xfffffffffffffL) | 0x10000000000000L;
-//            //s*m*2^(e-1075);
-            int log = (int)Math.floor(Math.log10(x));
-            int numFractionDigits = (log>=prec ? 0 : prec-log-1);
-            if (numFractionDigits>0) { //need decimal digits
-                if (skipDecimalThreshhold>0) {
-                    int checkFractionDigits = 0;
-                    double multiplier = 1;
-                    while (checkFractionDigits < numFractionDigits) {
-                        if (Math.abs(x - 
Math.rint(x*multiplier)/multiplier)<skipDecimalThreshhold)
-                            break;
-                        checkFractionDigits++;
-                        multiplier*=10;
-                    }
-                    numFractionDigits = checkFractionDigits;
-                }
-                df.setMinimumFractionDigits(numFractionDigits);
-                df.setMaximumFractionDigits(numFractionDigits);
-            } else {
-                //x = Math.rint(x);
-                df.setMaximumFractionDigits(0);
-            }
-            s = df.format(x);
-            if (maxlen>0 && s.length()>maxlen) {
-                //too long:
-                double signif = x/Math.pow(10,log);
-                if (s.indexOf(getDefaultDecimalSeparator())>=0) {
-                    //have a decimal point; either we are very small 0.000001
-                    //or prec is larger than maxlen
-                    if (Math.abs(x)<1 && useEForSmallNumbers) {
-                        //very small-- use alternate notation
-                        s = makeRealString(signif, -1, prec, -1) + "E"+log;
-                    } else {
-                        //leave it alone, user error or E not wanted
-                    }
-                } else {
-                    //no decimal point, integer part is too large, use alt 
notation
-                    s = makeRealString(signif, -1, prec, -1) + "E"+log;
-                }
-            }
-        }
-        if (leftPadLen>s.length())
-            return makePaddedString(s, leftPadLen, " ", "");
-        else
-            return s;
-    }
-
-    /** creates a string from a real number, with specified accuracy (more iff 
it comes for free, ie integer-part);
-     * switches to E notation if needed to fit within maxlen; can be padded 
left up too (not useful)
-     * @param x number to use
-     * @param maxlen maximum length for the numeric string, if possible (-1 to 
suppress)
-     * @param prec number of digits accuracy desired (more kept for integers)
-     * @param leftPadLen will add spaces at left if necessary to make string 
this long (-1 to suppress) [probably not usef]
-     * @return such a string
-     */
-    public static String makeRealStringNearZero(double x, int maxlen, int 
prec, int leftPadLen) {
-        if (Math.abs(x)<0.0000000001) x=0;
-        NumberFormat df = DecimalFormat.getInstance();
-        //df.setMaximumFractionDigits(maxlen);
-        df.setMinimumFractionDigits(0);
-        //df.setMaximumIntegerDigits(prec);
-        df.setMinimumIntegerDigits(1);
-        df.setGroupingUsed(false);
-        String s;
-        if (x==0) {
-            if (prec<=1) s="0";
-            else {
-                s="0.0";
-                while (s.length()<prec+1) s+="0";
-            }
-        } else {
-//            long bits= Double.doubleToLongBits(x);
-//            int s = ((bits >> 63) == 0) ? 1 : -1;
-//            int e = (int)((bits >> 52) & 0x7ffL);
-//            long m = (e == 0) ?
-//            (bits & 0xfffffffffffffL) << 1 :
-//            (bits & 0xfffffffffffffL) | 0x10000000000000L;
-//            //s*m*2^(e-1075);
-            int log = (int)Math.floor(Math.log10(x));
-            int scale = (log>=prec ? 0 : prec-log-1);
-            if (scale>0) { //need decimal digits
-                double scale10 = Math.pow(10, scale);
-                x = Math.rint(x*scale10)/scale10;
-                df.setMinimumFractionDigits(scale);
-                df.setMaximumFractionDigits(scale);
-            } else {
-                //x = Math.rint(x);
-                df.setMaximumFractionDigits(0);
-            }
-            s = df.format(x);
-            if (maxlen>0 && s.length()>maxlen) {
-                //too long:
-                double signif = x/Math.pow(10,log);
-                if (s.indexOf('.')>=0) {
-                    //have a decimal point; either we are very small 0.000001
-                    //or prec is larger than maxlen
-                    if (Math.abs(x)<1) {
-                        //very small-- use alternate notation
-                        s = makeRealString(signif, -1, prec, -1) + "E"+log;
-                    } else {
-                        //leave it alone, user error
-                    }
-                } else {
-                    //no decimal point, integer part is too large, use alt 
notation
-                    s = makeRealString(signif, -1, prec, -1) + "E"+log;
-                }
-            }
-        }
-        if (leftPadLen>s.length())
-            return makePaddedString(s, leftPadLen, " ", "");
-        else
-            return s;
-    }
-
-    /** returns the first word (whitespace delimited text), or null if there 
is none (input null or all whitespace) */
-    public static String getFirstWord(String s) {
-        if (s==null) return null;
-        int start = 0;
-        while (start<s.length()) {
-            if (!Character.isWhitespace(s.charAt(start)))
-                break;
-            start++;
-        }
-        int end = start;
-        if (end >= s.length())
-            return null;
-        while (end<s.length()) {
-            if (Character.isWhitespace(s.charAt(end)))
-                break;
-            end++;
-        }
-        return s.substring(start, end);
-    }
-
-    /** returns the last word (whitespace delimited text), or null if there is 
none (input null or all whitespace) */
-    public static String getLastWord(String s) {
-        if (s==null) return null;
-        int end = s.length()-1;
-        while (end >= 0) {
-            if (!Character.isWhitespace(s.charAt(end)))
-                break;
-            end--;
-        }
-        int start = end;
-        if (start < 0)
-            return null;
-        while (start >= 0) {
-            if (Character.isWhitespace(s.charAt(start)))
-                break;
-            start--;
-        }
-        return s.substring(start+1, end+1);
-    }
-
-    /** returns the first word after the given phrase, or null if no such 
phrase;
-     * if the character immediately after the phrase is not whitespace, the 
non-whitespace
-     * sequence starting with that character will be returned */
-    public static String getFirstWordAfter(String context, String phrase) {
-        if (context==null || phrase==null) return null;
-        int index = context.indexOf(phrase);
-        if (index<0) return null;
-        return getFirstWord(context.substring(index + phrase.length()));
-    }
-
-   /**
-    * searches in context for the given phrase, and returns the 
<b>untrimmed</b> remainder of the first line
-    * on which the phrase is found
-    */
-    public static String getRemainderOfLineAfter(String context, String 
phrase) {
-        if (context == null || phrase == null) return null;
-        int index = context.indexOf(phrase);
-        if (index < 0) return null;
-        int lineEndIndex = context.indexOf("\n", index);
-        if (lineEndIndex <= 0) {
-            return context.substring(index + phrase.length());
-        } else {
-            return context.substring(index + phrase.length(), lineEndIndex);
-        }
-    }
-
-    /** @deprecated use {@link Time#makeTimeStringRounded(long)} */
-    @Deprecated
-    public static String makeTimeString(long utcMillis) {
-        return Time.makeTimeStringRounded(utcMillis);
-    }
-
-    /** returns e.g. { "prefix01", ..., "prefix96" };
-     * see more functional NumericRangeGlobExpander for "prefix{01-96}"
-     */
-    public static String[] makeArray(String prefix, int count) {
-        String[] result = new String[count];
-        int len = (""+count).length();
-        for (int i=1; i<=count; i++)
-            result[i-1] = prefix + makePaddedString("", len, "0", ""+i);
-        return result;
-    }
-
-    public static String[] combineArrays(String[] ...arrays) {
-        int totalLen = 0;
-        for (String[] array : arrays) {
-            if (array!=null) totalLen += array.length;
-        }
-        String[] result = new String[totalLen];
-        int i=0;
-        for (String[] array : arrays) {
-            if (array!=null) for (String s : array) {
-                result[i++] = s;
-            }
-        }
-        return result;
-    }
-
-    public static String toInitialCapOnly(String value) {
-        if (value==null || value.length()==0) return value;
-        return value.substring(0, 1).toUpperCase(Locale.ENGLISH) + 
value.substring(1).toLowerCase(Locale.ENGLISH);
-    }
-
-    public static String reverse(String name) {
-        return new StringBuffer(name).reverse().toString();
-    }
-
-    public static boolean isLowerCase(String s) {
-        return s.toLowerCase().equals(s);
-    }
-
-    public static String makeRepeated(char c, int length) {
-        StringBuilder result = new StringBuilder(length);
-        for (int i = 0; i < length; i++) {
-            result.append(c);
-        }
-        return result.toString();
-    }
-
-    public static String trim(String s) {
-        if (s==null) return null;
-        return s.trim();
-    }
-
-    public static String trimEnd(String s) {
-        if (s==null) return null;
-        return ("a"+s).trim().substring(1);
-    }
-
-    /** returns up to maxlen characters from the start of s */
-    public static String maxlen(String s, int maxlen) {
-        return maxlenWithEllipsis(s, maxlen, "");
-    }
-
-    /** as {@link #maxlenWithEllipsis(String, int, String) with "..." as the 
ellipsis */
-    public static String maxlenWithEllipsis(String s, int maxlen) {
-        return maxlenWithEllipsis(s, maxlen, "...");
-    }
-    /** as {@link #maxlenWithEllipsis(String, int) but replacing the last few 
chars with the given ellipsis */
-    public static String maxlenWithEllipsis(String s, int maxlen, String 
ellipsis) {
-        if (s==null) return null;
-        if (ellipsis==null) ellipsis="";
-        if (s.length()<=maxlen) return s;
-        return s.substring(0, Math.max(maxlen-ellipsis.length(), 0))+ellipsis;
-    }
-
-    /** returns toString of the object if it is not null, otherwise null */
-    public static String toString(Object o) {
-        return toStringWithValueForNull(o, null);
-    }
-
-    /** returns toString of the object if it is not null, otherwise the given 
value */
-    public static String toStringWithValueForNull(Object o, String 
valueIfNull) {
-        if (o==null) return valueIfNull;
-        return o.toString();
-    }
-
-    public static boolean containsLiteralIgnoreCase(CharSequence input, 
CharSequence fragment) {
-        if (input==null) return false;
-        if (isEmpty(fragment)) return true;
-        int lastValidStartPos = input.length()-fragment.length();
-        char f0u = Character.toUpperCase(fragment.charAt(0));
-        char f0l = Character.toLowerCase(fragment.charAt(0));
-        i: for (int i=0; i<=lastValidStartPos; i++) {
-            char ii = input.charAt(i);
-            if (ii==f0l || ii==f0u) {
-                for (int j=1; j<fragment.length(); j++) {
-                    if 
(Character.toLowerCase(input.charAt(i+j))!=Character.toLowerCase(fragment.charAt(j)))
-                        continue i;
-                }
-                return true;
-            }
-        }
-        return false;
-    }
-
-    public static boolean containsLiteral(CharSequence input, CharSequence 
fragment) {
-        if (input==null) return false;
-        if (isEmpty(fragment)) return true;
-        int lastValidStartPos = input.length()-fragment.length();
-        char f0 = fragment.charAt(0);
-        i: for (int i=0; i<=lastValidStartPos; i++) {
-            char ii = input.charAt(i);
-            if (ii==f0) {
-                for (int j=1; j<fragment.length(); j++) {
-                    if (input.charAt(i+j)!=fragment.charAt(j))
-                        continue i;
-                }
-                return true;
-            }
-        }
-        return false;
-    }
-
-    /** Returns a size string using metric suffixes from {@link 
ByteSizeStrings#metric()}, e.g. 23.5MB */
-    public static String makeSizeString(long sizeInBytes) {
-        return ByteSizeStrings.metric().makeSizeString(sizeInBytes);
-    }
-
-    /** Returns a size string using ISO suffixes from {@link 
ByteSizeStrings#iso()}, e.g. 23.5MiB */
-    public static String makeISOSizeString(long sizeInBytes) {
-        return ByteSizeStrings.iso().makeSizeString(sizeInBytes);
-    }
-
-    /** Returns a size string using Java suffixes from {@link 
ByteSizeStrings#java()}, e.g. 23m */
-    public static String makeJavaSizeString(long sizeInBytes) {
-        return ByteSizeStrings.java().makeSizeString(sizeInBytes);
-    }
-
-    /** returns a configurable shortener */
-    public static StringShortener shortener() {
-        return new StringShortener();
-    }
-
-    public static Supplier<String> toStringSupplier(Object src) {
-        return Suppliers.compose(Functions.toStringFunction(), 
Suppliers.ofInstance(src));
-    }
-
-    /** wraps a call to {@link String#format(String, Object...)} in a 
toString, i.e. using %s syntax,
-     * useful for places where we want deferred evaluation
-     * (e.g. as message to {@link Preconditions} to skip concatenation when 
not needed) */
-    public static FormattedString format(String pattern, Object... args) {
-        return new FormattedString(pattern, args);
-    }
-
-    /** returns "s" if the argument is not 1, empty string otherwise; useful 
when constructing plurals */
-    public static String s(int count) {
-        return count==1 ? "" : "s";
-    }
-    /** as {@link #s(int)} based on size of argument */
-    public static String s(@Nullable Map<?,?> x) {
-        return s(x==null ? 0 : x.size());
-    }
-    /** as {@link #s(int)} based on size of argument */
-    public static String s(Iterable<?> x) {
-        if (x==null) return s(0);
-        return s(x.iterator());
-    }
-    /** as {@link #s(int)} based on size of argument */
-    public static String s(Iterator<?> x) {
-        int count = 0;
-        if (x==null || !x.hasNext()) {}
-        else {
-            x.next(); count++;
-            if (x.hasNext()) count++;
-        }
-        return s(count);
-    }
-
-    /** returns "ies" if the argument is not 1, "y" otherwise; useful when 
constructing plurals */
-    public static String ies(int count) {
-        return count==1 ? "y" : "ies";
-    }
-    /** as {@link #ies(int)} based on size of argument */
-    public static String ies(@Nullable Map<?,?> x) {
-        return ies(x==null ? 0 : x.size());
-    }
-    /** as {@link #ies(int)} based on size of argument */
-    public static String ies(Iterable<?> x) {
-        if (x==null) return ies(0);
-        return ies(x.iterator());
-    }
-    /** as {@link #ies(int)} based on size of argument */
-    public static String ies(Iterator<?> x) {
-        int count = 0;
-        if (x==null || !x.hasNext()) {}
-        else {
-            x.next(); count++;
-            if (x.hasNext()) count++;
-        }
-        return ies(count);
-    }
-
-    /** converts a map of any objects to a map of strings, using the tostring, 
and returning "null" for nulls 
-     * @deprecated since 0.7.0 use {@link #toStringMap(Map, String)} to remove 
ambiguity about how to handle null */
-    // NB previously the javadoc here was wrong, said it returned null not 
"null"
-    @Deprecated
-    public static Map<String, String> toStringMap(Map<?,?> map) {
-        return toStringMap(map, "null");
-    }
-    /** converts a map of any objects to a map of strings, using {@link 
Object#toString()},
-     * with the second argument used where a value (or key) is null */
-    public static Map<String, String> toStringMap(Map<?,?> map, String 
valueIfNull) {
-        if (map==null) return null;
-        Map<String,String> result = MutableMap.<String, String>of();
-        for (Map.Entry<?,?> e: map.entrySet()) {
-            result.put(toStringWithValueForNull(e.getKey(), valueIfNull), 
toStringWithValueForNull(e.getValue(), valueIfNull));
-        }
-        return result;
-    }
-    
-    /** converts a list of any objects to a list of strings, using {@link 
Object#toString()},
-     * with the second argument used where an entry is null */
-    public static List<String> toStringList(List<?> list, String valueIfNull) {
-        if (list==null) return null;
-        List<String> result = MutableList.of();
-        for (Object v: list) result.add(toStringWithValueForNull(v, 
valueIfNull));
-        return result;
-    }
-
-    /** returns base repeated count times */
-    public static String repeat(String base, int count) {
-        if (base==null) return null;
-        StringBuilder result = new StringBuilder();
-        for (int i=0; i<count; i++)
-            result.append(base);
-        return result.toString();
-    }
-
-    /** returns comparator which compares based on length, with shorter ones 
first (and null before that);
-     * in event of a tie, it uses the toString order */
-    public static Ordering<String> lengthComparator() {
-        return 
Ordering.<Integer>natural().onResultOf(StringFunctions.length()).compound(Ordering.<String>natural()).nullsFirst();
-    }
-
-    public static boolean isMultiLine(String s) {
-        if (s==null) return false;
-        if (s.indexOf('\n')>=0 || s.indexOf('\r')>=0) return true;
-        return false;
-    }
-    public static String getFirstLine(String s) {
-        int idx = s.indexOf('\n');
-        if (idx==-1) return s;
-        return s.substring(0, idx);
-    }
-
-    /** looks for first section of text in following the prefix and, if 
present, before the suffix;
-     * null if the prefix is not present in the string, and everything after 
the prefix if suffix is not present in the string;
-     * if either prefix or suffix is null, it is treated as the start/end of 
the string */
-    public static String getFragmentBetween(String input, String prefix, 
String suffix) {
-        if (input==null) return null;
-        int index;
-        if (prefix!=null) {
-            index = input.indexOf(prefix);
-            if (index==-1) return null;
-            input = input.substring(index + prefix.length());
-        }
-        if (suffix!=null) {
-            index = input.indexOf(suffix);
-            if (index>=0) input = input.substring(0, index);
-        }
-        return input;
-    }
-
-    public static int getWordCount(String phrase, boolean respectQuotes) {
-        if (phrase==null) return 0;
-        phrase = phrase.trim();
-        if (respectQuotes)
-            return new QuotedStringTokenizer(phrase).remainderAsList().size();
-        else
-            return Collections.list(new StringTokenizer(phrase)).size();
-    }
-
-    public static char getDecimalSeparator(Locale locale) {
-        DecimalFormatSymbols dfs = new DecimalFormatSymbols(locale);
-        return dfs.getDecimalSeparator();
-    }
-
-    public static char getDefaultDecimalSeparator() {
-        return getDecimalSeparator(Locale.getDefault());
-    }
-
-    /** replaces each sequence of whitespace in the first string with the 
replacement in the second string */
-    public static String collapseWhitespace(String x, String 
whitespaceReplacement) {
-        if (x==null) return null;
-        return replaceAllRegex(x, "\\s+", whitespaceReplacement);
-    }
-
-    public static String toLowerCase(String value) {
-        if (value==null || value.length()==0) return value;
-        return value.toLowerCase(Locale.ENGLISH);
-    }
-
-    /**
-     * @return null if var is null or empty string, otherwise return var
-     */
-    public static String emptyToNull(String var) {
-        if (isNonEmpty(var)) {
-            return var;
-        } else {
-            return null;
-        }
-    }
-    
-    /** Returns canonicalized string from the given object, made "unique" by:
-     * <li> putting sets into the toString order
-     * <li> appending a hash code if it's longer than the max (and the max is 
bigger than 0) */
-    public static String toUniqueString(Object x, int optionalMax) {
-        if (x instanceof Iterable && !(x instanceof List)) {
-            // unsorted collections should have a canonical order imposed
-            MutableList<String> result = MutableList.of();
-            for (Object xi: (Iterable<?>)x) {
-                result.add(toUniqueString(xi, optionalMax));
-            }
-            Collections.sort(result);
-            x = result.toString();
-        }
-        if (x==null) return "{null}";
-        String xs = x.toString();
-        if (xs.length()<=optionalMax || optionalMax<=0) return xs;
-        return maxlenWithEllipsis(xs, 
optionalMax-8)+"/"+Integer.toHexString(xs.hashCode());
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/cf2f7a93/utils/common/src/main/java/brooklyn/util/text/WildcardGlobs.java
----------------------------------------------------------------------
diff --git a/utils/common/src/main/java/brooklyn/util/text/WildcardGlobs.java 
b/utils/common/src/main/java/brooklyn/util/text/WildcardGlobs.java
deleted file mode 100644
index e26848b..0000000
--- a/utils/common/src/main/java/brooklyn/util/text/WildcardGlobs.java
+++ /dev/null
@@ -1,382 +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.text;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import com.google.common.base.Throwables;
-
-public class WildcardGlobs {
-
-    /** returns true iff the target matches the given pattern,
-     * under simplified bash rules -- viz permitting * and ? and comma 
delimited patterns inside curly braces 
-     * @throws InvalidPatternException */
-    public static boolean isGlobMatched(String globPattern, String targetText) 
throws InvalidPatternException {
-        List<String> patterns = getGlobsAfterBraceExpansion(globPattern);      
 
-        for (String p : patterns) {
-            if (isNoBraceGlobMatched(p, targetText))
-                return true;
-        }
-        return false;
-    }
-
-    /** whether a glob-ish string without braces (e.g. containing just ? and * 
chars) matches;
-     * can be used directly, also used implicitly by isGlobMatched after glob 
expansion */
-    public static boolean isNoBraceGlobMatched(String globPattern, String 
target) {
-        int pi=0, ti=0;
-        while (pi<globPattern.length() && ti<target.length()) {
-            char pc = globPattern.charAt(pi);
-            char tc = target.charAt(pi);
-            if (pc=='?') {
-                pi++; ti++;
-                continue;
-            }
-            if (pc!='*') {
-                if (pc!=tc) return false;
-                pi++; ti++;
-                continue;
-            }
-            //match 0 or more chars
-            String prest = globPattern.substring(pi+1);
-            while (ti<=target.length()) {
-                if (isNoBraceGlobMatched(prest, target.substring(ti)))
-                    return true;
-                ti++;
-            }
-            return false;
-        }
-        while (pi<globPattern.length() && globPattern.charAt(pi)=='*')
-            pi++;
-        return (pi==globPattern.length() && ti==target.length());
-    }   
-
-    /** returns a list with no curly braces in any entries,
-     * and guaranteeing order such that any {..,X,..,Y,..} will result in X 
being before Y in the resulting list;
-     * e.g. given a{,b,c} gives a ab and ac; no special treatment of numeric 
ranges, quotes, or parentheses 
-     * (see SpecialistGlobExpander for that) */
-    public static List<String> getGlobsAfterBraceExpansion(String pattern) 
throws InvalidPatternException {
-        return getGlobsAfterBraceExpansion(pattern, false, 
PhraseTreatment.NOT_A_SPECIAL_CHAR, PhraseTreatment.NOT_A_SPECIAL_CHAR);
-    }
-
-    /** if a string contains a demarcated phrase, e.g. between open and close 
parentheses, or inside unescaped quotes
-     * this argument determines how that phrase is treated with regards to 
brace expansion */
-    public enum PhraseTreatment {
-        /** the region is treated like any other region */
-        NOT_A_SPECIAL_CHAR, 
-        /** the interior will be expanded if there is a {x,y} expression 
_entirely_ inside the phrase, but otherwise commas inside it will be ignored;
-         * it will be an error if there is a { char inside the phrase, or if 
the phrase is not internally well-formed with regards to the phrase characters,
-         * (e.g. if quotes are interior expandable and parens are anything but 
not_a_special_char (e.g. interior expandable or interior not expandable) 
-         * then any expression inside a quoted phrase must have matching 
parentheses) */
-        INTERIOR_EXPANDABLE, 
-        /** the interior will not be expanded at all, not if there's a comma 
inside, and not even if there is a {x,y} expression entirely inside; the braces 
will be left;
-         * interior of parenthetical phrases must have matching parentheses 
(to determine the right end parenthesis),
-         * apart from parentheses inside any quoted phrases when quotes are 
interior_not_expandable which will be ignored;
-         * quotes inside not_expandable paren phrases will be ignored */
-        INTERIOR_NOT_EXPANDABLE 
-    };
-
-    protected static class ExpressionToExpand {
-        String resultSoFar;
-        String todo;
-        String operatorStack;
-        public ExpressionToExpand(String resultSoFar, String todo, String 
operatorStack) {
-            super();
-            this.resultSoFar = resultSoFar;
-            this.todo = todo;
-            this.operatorStack = operatorStack;
-        }
-        @Override
-        public String toString() {
-            return 
"ExpressionToExpand["+todo+":"+resultSoFar+"/"+operatorStack+"]";
-        }
-    }
-    /** returns a list with no curly braces in any entries; e.g. given a{,b} 
gives a and ab; 
-     * quotes and parentheses are kept, but their contents may be excluded 
from expansion or otherwise treated specially as per the flag.
-     * with allowNumericRanges, "{1-3}" is permitted for {1,2,3}. */
-    public static List<String> getGlobsAfterBraceExpansion(String pattern, 
boolean allowNumericRanges, PhraseTreatment quoteTreatment, PhraseTreatment 
parenthesesTreatment) throws InvalidPatternException {
-        List<ExpressionToExpand> patterns = new 
ArrayList<ExpressionToExpand>();
-        List<String> result = new ArrayList<String>();
-        patterns.add(new ExpressionToExpand("", pattern, ""));
-        while (!patterns.isEmpty()) {
-            ExpressionToExpand cs = patterns.remove(0);
-            StringBuffer resultSoFar = new StringBuffer(cs.resultSoFar);
-            String operatorStack = cs.operatorStack;
-            boolean inQuote = operatorStack.contains("\"");
-            boolean expanded = false;
-            for (int i=0; i<cs.todo.length(); i++) {
-                assert !expanded;
-                char c = cs.todo.charAt(i);
-                boolean inParen = operatorStack.contains("(") &&
-                    (!inQuote || 
operatorStack.lastIndexOf('\"')<operatorStack.lastIndexOf('('));
-                if (inQuote && !(inParen && 
parenthesesTreatment.equals(PhraseTreatment.INTERIOR_NOT_EXPANDABLE))) {
-                    if (c=='"') {
-                        if (i>0 && cs.todo.charAt(i-1)=='\\') {
-                            //this escaped quote, keep
-                            resultSoFar.append(c);
-                            continue;
-                        }
-                        //unquote
-                        resultSoFar.append(c);
-                        inQuote = false;
-                        if 
(operatorStack.charAt(operatorStack.length()-1)!='\"')
-                            throw new InvalidPatternException("Quoted string 
contents not valid, after parsing "+resultSoFar);
-                        operatorStack = operatorStack.substring(0, 
operatorStack.length()-1);
-                        continue;
-                    }
-                    if 
(quoteTreatment.equals(PhraseTreatment.INTERIOR_NOT_EXPANDABLE)) {
-                        resultSoFar.append(c);
-                        continue;
-                    }
-                    //interior is expandable, continue parsing as usual below
-                }
-                if (inParen) {
-                    if (c==')') {
-                        //unparen
-                        resultSoFar.append(c);
-                        if 
(operatorStack.charAt(operatorStack.length()-1)!='(')
-                            throw new InvalidPatternException("Parenthetical 
contents not valid, after parsing "+resultSoFar);
-                        operatorStack = operatorStack.substring(0, 
operatorStack.length()-1);
-                        continue;
-                    }
-                    if 
(parenthesesTreatment.equals(PhraseTreatment.INTERIOR_NOT_EXPANDABLE)) {
-                        resultSoFar.append(c);
-                        if (c=='(')
-                            operatorStack+="(";
-                        continue;
-                    }
-                    //interior is expandable, continue parsing as usual below
-                }
-
-                if (c=='"' && 
!quoteTreatment.equals(PhraseTreatment.NOT_A_SPECIAL_CHAR)) {
-                    resultSoFar.append(c);
-                    inQuote = true;
-                    operatorStack += "\"";
-                    continue;
-                }
-                if (c=='(' && 
!parenthesesTreatment.equals(PhraseTreatment.NOT_A_SPECIAL_CHAR)) {
-                    resultSoFar.append(c);
-                    operatorStack += "(";
-                    continue;
-                }
-
-                if (c!='{') {
-                    resultSoFar.append(c);
-                    continue;
-                }
-
-                //brace.. we will need to expand
-                expanded = true;
-                String operatorStackBeforeExpansion = operatorStack;
-                int braceStartIndex = i;
-                int tokenStartIndex = i+1;
-
-                //find matching close brace
-                List<String> tokens = new ArrayList<String>();
-                operatorStack += "{";
-                while (true) {
-                    if (++i>=cs.todo.length()) {
-                        throw new InvalidPatternException("Curly brace not 
closed, parsing '"+cs.todo.substring(braceStartIndex)+"' after "+resultSoFar);
-                    }
-                    c = cs.todo.charAt(i);
-                    inParen = operatorStack.contains("(") &&
-                        (!inQuote || 
operatorStack.lastIndexOf('\"')<operatorStack.lastIndexOf('('));
-                    if (inQuote && !(inParen && 
parenthesesTreatment.equals(PhraseTreatment.INTERIOR_NOT_EXPANDABLE))) {
-                        if (c=='"') {
-                            if (i>0 && cs.todo.charAt(i-1)=='\\') {
-                                //this is escaped quote, doesn't affect status
-                                continue;
-                            }
-                            //unquote
-                            inQuote = false;
-                            if 
(operatorStack.charAt(operatorStack.length()-1)!='\"')
-                                throw new InvalidPatternException("Quoted 
string contents not valid, after parsing 
"+resultSoFar+cs.todo.substring(braceStartIndex, i));
-                            operatorStack = operatorStack.substring(0, 
operatorStack.length()-1);
-                            continue;
-                        }
-                        if 
(quoteTreatment.equals(PhraseTreatment.INTERIOR_NOT_EXPANDABLE)) {
-                            continue;
-                        }
-                        //interior is expandable, continue parsing as usual 
below
-                    }
-                    if (inParen) {
-                        if (c==')') {
-                            //unparen
-                            if 
(operatorStack.charAt(operatorStack.length()-1)!='(')
-                                throw new 
InvalidPatternException("Parenthetical contents not valid, after parsing 
"+resultSoFar+cs.todo.substring(braceStartIndex, i));
-                            operatorStack = operatorStack.substring(0, 
operatorStack.length()-1);
-                            continue;
-                        }
-                        if 
(parenthesesTreatment.equals(PhraseTreatment.INTERIOR_NOT_EXPANDABLE)) {
-                            if (c=='(')
-                                operatorStack+="(";
-                            continue;
-                        }
-                        //interior is expandable, continue parsing as usual 
below
-                    }
-
-                    if (c=='"' && 
!quoteTreatment.equals(PhraseTreatment.NOT_A_SPECIAL_CHAR)) {
-                        inQuote = true;
-                        operatorStack += "\"";
-                        continue;
-                    }
-                    if (c=='(' && 
!parenthesesTreatment.equals(PhraseTreatment.NOT_A_SPECIAL_CHAR)) {
-                        operatorStack += "(";
-                        continue;
-                    }
-
-                    if (c=='}') {
-                        if 
(operatorStack.charAt(operatorStack.length()-1)!='{')
-                            throw new InvalidPatternException("Brace contents 
not valid, mismatched operators "+operatorStack+" after parsing 
"+resultSoFar+cs.todo.substring(braceStartIndex, i));
-                        operatorStack = operatorStack.substring(0, 
operatorStack.length()-1);
-                        if 
(operatorStack.equals(operatorStackBeforeExpansion)) {
-                            tokens.add(cs.todo.substring(tokenStartIndex, i));
-                            break;
-                        }
-                        continue;
-                    }
-
-                    if (c==',') {
-                        if 
(operatorStack.length()==operatorStackBeforeExpansion.length()+1) {
-                            tokens.add(cs.todo.substring(tokenStartIndex, i));
-                            tokenStartIndex = i+1;
-                            continue;
-                        }
-                        continue;
-                    }
-
-                    if (c=='{') {
-                        operatorStack += c;
-                        continue;
-                    }
-
-                    //any other char is irrelevant
-                    continue;
-                }
-
-                assert operatorStack.equals(operatorStackBeforeExpansion);
-                assert cs.todo.charAt(i)=='}';
-                assert !tokens.isEmpty();
-
-                String suffix = cs.todo.substring(i+1);
-
-                List<ExpressionToExpand> newPatterns = new 
ArrayList<ExpressionToExpand>();
-                for (String token : tokens) {
-                    //System.out.println("adding: "+pre+token+post);
-                    if (allowNumericRanges && 
token.matches("\\s*[0-9]+\\s*-\\s*[0-9]+\\s*")) {
-                        int dashIndex = token.indexOf('-');
-                        String startS = token.substring(0, dashIndex).trim();
-                        String endS = token.substring(dashIndex+1).trim();
-
-                        int start = Integer.parseInt(startS);
-                        int end = Integer.parseInt(endS);
-
-                        if (startS.startsWith("-")) 
startS=startS.substring(1).trim();
-                        if (endS.startsWith("-")) 
endS=endS.substring(1).trim();
-                        int minLen = Math.min(startS.length(), endS.length());
-
-                        for (int ti=start; ti<=end; ti++) {
-                            //partial support for negative numbers, but of 
course they cannot (yet) be specified in the regex above so it is moot
-                            String tokenI = ""+Math.abs(ti);
-                            while (tokenI.length()<minLen) tokenI = "0"+tokenI;
-                            if (ti<0) tokenI = "-"+tokenI;
-                            newPatterns.add(new 
ExpressionToExpand(resultSoFar.toString(), tokenI+suffix, 
operatorStackBeforeExpansion));                              
-                        }
-                    } else {
-                        newPatterns.add(new 
ExpressionToExpand(resultSoFar.toString(), token+suffix, 
operatorStackBeforeExpansion));
-                    }
-                }
-                // insert new patterns at the start, so we continue to expand 
them next
-                patterns.addAll(0, newPatterns);
-                
-                break;
-            }
-            if (!expanded) {
-                if (operatorStack.length()>0) {
-                    throw new InvalidPatternException("Unclosed operators 
"+operatorStack+" parsing "+resultSoFar);
-                }
-                result.add(resultSoFar.toString());
-            }
-        }
-        assert !result.isEmpty();
-        return result;
-    }
-
-    public static class InvalidPatternException extends RuntimeException {
-        private static final long serialVersionUID = -1969068264338310749L;
-        public InvalidPatternException(String msg) {
-            super(msg);
-        }
-    }
-
-    
-    /** expands globs as per #getGlobsAfterBraceExpansion, 
-     * but also handles numeric ranges, 
-     * and optionally allows customized treatment of quoted regions and/or 
parentheses.
-     * <p>
-     * simple example:  machine-{0-3}-{a,b} returns 8 values,
-     * machine-0-a machine-0-b machine-1-a ... machine-3-b; 
-     * NB leading zeroes are meaningful, so {00-03} expands as 00, 01, 02, 03
-     * <p>
-     * quote INTERIOR_NOT_EXPANDABLE example: a{b,"c,d"} return ab ac,d
-     * <p>
-     * for more detail on special treatment of quote and parentheses see 
PhraseTreatment and WildcardGlobsTest 
-     */
-    public static class SpecialistGlobExpander {
-
-        private boolean expandNumericRanges;
-        private PhraseTreatment quoteTreatment;
-        private PhraseTreatment parenthesesTreatment;
-
-        public SpecialistGlobExpander(boolean expandNumericRanges, 
PhraseTreatment quoteTreatment, PhraseTreatment parenthesesTreatment) {
-            this.expandNumericRanges = expandNumericRanges;
-            this.quoteTreatment = quoteTreatment;
-            this.parenthesesTreatment = parenthesesTreatment;
-        }
-        /** expands glob, including custom syntax for numeric part */ 
-        public List<String> expand(String glob) throws InvalidPatternException 
{
-            return getGlobsAfterBraceExpansion(glob, expandNumericRanges, 
quoteTreatment, parenthesesTreatment);
-        }
-        
-        /** returns true iff the target matches the given pattern,
-         * under simplified bash rules -- viz permitting * and ? and comma 
delimited patterns inside curly braces,
-         * as well as things like {1,2,5-10} (and also {01,02,05-10} to keep 
leading 0)
-         * @throws InvalidPatternException */
-        public boolean isGlobMatchedNumeric(String globPattern, String 
targetText) throws InvalidPatternException {
-            List<String> patterns = expand(globPattern);        
-            for (String p : patterns) {
-                if (isNoBraceGlobMatched(p, targetText))
-                    return true;
-            }
-            return false;
-        }
-
-        /** expands glob, including custom syntax for numeric part, but to an 
array, and re-throwing the checked exception as a runtime exception */
-        public String[] expandToArrayUnchecked(String glob) {
-            try {
-                return expand(glob).toArray(new String[0]);
-            } catch (InvalidPatternException e) {
-                throw Throwables.propagate(e);
-            }
-        }
-
-        
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/cf2f7a93/utils/common/src/main/java/brooklyn/util/time/CountdownTimer.java
----------------------------------------------------------------------
diff --git a/utils/common/src/main/java/brooklyn/util/time/CountdownTimer.java 
b/utils/common/src/main/java/brooklyn/util/time/CountdownTimer.java
deleted file mode 100644
index 0a5aaec..0000000
--- a/utils/common/src/main/java/brooklyn/util/time/CountdownTimer.java
+++ /dev/null
@@ -1,119 +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.time;
-
-import java.util.concurrent.TimeUnit;
-
-import brooklyn.util.exceptions.Exceptions;
-
-import com.google.common.base.Stopwatch;
-
-public class CountdownTimer {
-
-    Stopwatch stopwatch = Stopwatch.createUnstarted();
-    Duration limit;
-    
-    private CountdownTimer(Duration limit) {
-        this.limit = limit;
-    }
-    
-    /** starts the timer, either initially or if {@link #pause()}d; no-op if 
already running */
-    public synchronized CountdownTimer start() {
-        if (!stopwatch.isRunning()) stopwatch.start();
-        return this;
-    }
-
-    /** pauses the timer, if running; no-op if not running */
-    public synchronized CountdownTimer pause() {
-        if (stopwatch.isRunning()) stopwatch.stop();
-        return this;
-    }
-
-    /** returns underlying stopwatch, which caller can inspect for more 
details or modify */
-    public Stopwatch getStopwatch() {
-        return stopwatch;
-    }
-    
-    /** how much total time this timer should run for */
-    public Duration getLimit() {
-        return limit;
-    }
-
-    /** return how long the timer has been running (longer than limit if 
{@link #isExpired()}) */
-    public Duration getDurationElapsed() {
-        return Duration.nanos(stopwatch.elapsed(TimeUnit.NANOSECONDS));
-    }
-    
-    /** returns how much time is left (negative if {@link #isExpired()}) */
-    public Duration getDurationRemaining() {
-        return Duration.millis(limit.toMilliseconds() - 
stopwatch.elapsed(TimeUnit.MILLISECONDS));
-    }
-
-    /** true iff the timer has been running for the duration specified at 
creation time */
-    public boolean isExpired() {
-        return stopwatch.elapsed(TimeUnit.MILLISECONDS) > 
limit.toMilliseconds();
-    }
-    
-    /** true iff timer is running (even if it is expired) */
-    public boolean isRunning() {
-        return stopwatch.isRunning();
-    }
-    
-    // --- constructor methods
-    
-    public static CountdownTimer newInstanceStarted(Duration duration) {
-        return new CountdownTimer(duration).start();
-    }
-
-    public static CountdownTimer newInstancePaused(Duration duration) {
-        return new CountdownTimer(duration).pause();
-    }
-
-    /** block (on this object) until completed 
-     * @throws InterruptedException */
-    public synchronized void waitForExpiry() throws InterruptedException {
-        while (waitOnForExpiry(this)) {};
-    }
-
-    /** as {@link #waitForExpiry()} but catches and wraps InterruptedException 
as unchecked RuntimeInterruptedExcedption */
-    public synchronized void waitForExpiryUnchecked() {
-        waitOnForExpiryUnchecked(this);
-    }
-
-    /** block on the given argument until the timer is completed or the object 
receives a notified;
-     * callers must be synchronized on the waitTarget
-     * @return true if the object is notified (or receives a spurious wake), 
false if the duration is expired 
-     * @throws InterruptedException */
-    public boolean waitOnForExpiry(Object waitTarget) throws 
InterruptedException {
-        Duration remainder = getDurationRemaining();
-        if (remainder.toMilliseconds() <= 0) 
-            return false;
-        waitTarget.wait(remainder.toMilliseconds());
-        return true;
-    }
-    /** as {@link #waitOnForExpiry(Object)} but catches and wraps 
InterruptedException as unchecked RuntimeInterruptedExcedption */
-    public boolean waitOnForExpiryUnchecked(Object waitTarget) {
-        try {
-            return waitOnForExpiry(waitTarget);
-        } catch (InterruptedException e) {
-            throw Exceptions.propagate(e);
-        }        
-    }
-    
-}

Reply via email to