This closes #1158
diff --git a/brooklyn-server/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogYamlTemplateTest.java b/brooklyn-server/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogYamlTemplateTest.java
index 165fd49..a759fed 100644
--- a/brooklyn-server/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogYamlTemplateTest.java
+++ b/brooklyn-server/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogYamlTemplateTest.java
@@ -41,12 +41,13 @@
 import org.apache.brooklyn.test.Asserts;
 import org.apache.brooklyn.test.support.TestResourceUnavailableException;
 import org.apache.brooklyn.util.osgi.OsgiTestResources;
-import org.python.google.common.collect.Iterables;
 import org.testng.Assert;
 import org.testng.TestListenerAdapter;
 import org.testng.TestNG;
 import org.testng.annotations.Test;
 
+import com.google.common.collect.Iterables;
+
 
 public class CatalogYamlTemplateTest extends AbstractYamlTest {
     
diff --git a/brooklyn-server/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsLocation.java b/brooklyn-server/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsLocation.java
index 20897d9..05972a2 100644
--- a/brooklyn-server/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsLocation.java
+++ b/brooklyn-server/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsLocation.java
@@ -862,7 +862,7 @@
                         String scriptContent = ResourceUtils.create(this).getResourceAsString(setupScriptItem);
                         String script = TemplateProcessor.processTemplateContents(scriptContent, getManagementContext(), substitutions);
                         if (windows) {
-                            ((WinRmMachineLocation)machineLocation).executeScript(ImmutableList.copyOf((script.replace("\r", "").split("\n"))));
+                            ((WinRmMachineLocation)machineLocation).executeCommand(ImmutableList.copyOf((script.replace("\r", "").split("\n"))));
                         } else {
                             ((SshMachineLocation)machineLocation).execCommands("Customizing node " + this, ImmutableList.of(script));
                         }
@@ -2664,7 +2664,7 @@
                 public Boolean call() {
                     for (Map.Entry<WinRmMachineLocation, LoginCredentials> entry : machinesToTry.entrySet()) {
                         WinRmMachineLocation machine = entry.getKey();
-                        WinRmToolResponse response = machine.executeScript(
+                        WinRmToolResponse response = machine.executeCommand(
                                 ImmutableMap.of(WinRmTool.PROP_EXEC_TRIES.getName(), 1),
                                 ImmutableList.of("echo testing"));
                         boolean success = (response.getStatusCode() == 0);
diff --git a/brooklyn-server/pom.xml b/brooklyn-server/pom.xml
index c497ee4..4e6012b 100644
--- a/brooklyn-server/pom.xml
+++ b/brooklyn-server/pom.xml
@@ -146,7 +146,7 @@
         <jsr311-api.version>1.1.1</jsr311-api.version>
         <maxmind.version>0.8.1</maxmind.version>
         <jna.version>4.0.0</jna.version>
-        <winrm4j.version>0.1.0</winrm4j.version>
+        <winrm4j.version>0.2.0</winrm4j.version>
         
         <!-- Transitive dependencies, declared explicitly to avoid version mismatch -->
         <clojure.version>1.4.0</clojure.version>
diff --git a/brooklyn-server/software/base/src/main/java/org/apache/brooklyn/entity/software/base/AbstractSoftwareProcessWinRmDriver.java b/brooklyn-server/software/base/src/main/java/org/apache/brooklyn/entity/software/base/AbstractSoftwareProcessWinRmDriver.java
index 6a39cc2..de88cba 100644
--- a/brooklyn-server/software/base/src/main/java/org/apache/brooklyn/entity/software/base/AbstractSoftwareProcessWinRmDriver.java
+++ b/brooklyn-server/software/base/src/main/java/org/apache/brooklyn/entity/software/base/AbstractSoftwareProcessWinRmDriver.java
@@ -48,7 +48,6 @@
 import org.apache.brooklyn.util.stream.Streams;
 import org.apache.brooklyn.util.text.Strings;
 import org.apache.brooklyn.util.time.Duration;
-import org.python.core.PyException;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -239,7 +238,7 @@
         if (Strings.isBlank(regularCommand)) {
             response = getLocation().executePsScript(ImmutableList.of(powerShellCommand));
         } else {
-            response = getLocation().executeScript(ImmutableList.of(regularCommand));
+            response = getLocation().executeCommand(ImmutableList.of(regularCommand));
         }
 
         if (currentTask != null) {
@@ -259,7 +258,7 @@
     }
 
     public int execute(List<String> script) {
-        return getLocation().executeScript(script).getStatusCode();
+        return getLocation().executeCommand(script).getStatusCode();
     }
 
     public int executePsScriptNoRetry(List<String> psScript) {
@@ -281,8 +280,9 @@
     public void rebootAndWait() {
         try {
             executePsScriptNoRetry(ImmutableList.of("Restart-Computer -Force"));
-        } catch (PyException e) {
+        } catch (Exception e) {
             // Restarting the computer will cause the command to fail; ignore the exception and continue
+            Exceptions.propagateIfFatal(e);
         }
         waitForWinRmStatus(false, entity.getConfig(VanillaWindowsProcess.REBOOT_BEGUN_TIMEOUT));
         waitForWinRmStatus(true, entity.getConfig(VanillaWindowsProcess.REBOOT_COMPLETED_TIMEOUT)).getWithError();
diff --git a/brooklyn-server/software/base/src/test/java/org/apache/brooklyn/entity/software/base/test/location/WinRmMachineLocationLiveTest.java b/brooklyn-server/software/base/src/test/java/org/apache/brooklyn/entity/software/base/test/location/WinRmMachineLocationLiveTest.java
index 884da19..2e34ef7 100644
--- a/brooklyn-server/software/base/src/test/java/org/apache/brooklyn/entity/software/base/test/location/WinRmMachineLocationLiveTest.java
+++ b/brooklyn-server/software/base/src/test/java/org/apache/brooklyn/entity/software/base/test/location/WinRmMachineLocationLiveTest.java
@@ -63,7 +63,7 @@
  * Tests execution of commands (batch and powershell) on Windows over WinRM, and of
  * file upload.
  * 
- * There are limitations with what is supported by PyWinRM. These are highlighted in
+ * There are limitations with what is supported by winrm4j. These are highlighted in
  * tests marked as "WIP" (see individual tests).
  * 
  * These limitations are documented in docs/guide/yaml/winrm/index.md.
@@ -146,7 +146,7 @@
         String remotePath = "C:\\myfile-"+Identifiers.makeRandomId(4)+".txt";
         machine.copyTo(new ByteArrayInputStream(contents.getBytes()), remotePath);
         
-        WinRmToolResponse response = machine.executeScript("type "+remotePath);
+        WinRmToolResponse response = machine.executeCommand("type "+remotePath);
         String msg = "statusCode="+response.getStatusCode()+"; out="+response.getStdOut()+"; err="+response.getStdErr();
         assertEquals(response.getStatusCode(), 0, msg);
         assertEquals(response.getStdOut().trim(), contents, msg);
@@ -159,7 +159,7 @@
             String remotePath = "C:\\myfile-"+Identifiers.makeRandomId(4)+".txt";
             machine.copyTo(localFile, remotePath);
             
-            WinRmToolResponse response = machine.executeScript("type "+remotePath);
+            WinRmToolResponse response = machine.executeCommand("type "+remotePath);
             String msg = "statusCode="+response.getStatusCode()+"; out="+response.getStdOut()+"; err="+response.getStdErr();
             assertEquals(response.getStatusCode(), 0, msg);
             assertEquals(response.getStdOut().trim(), contents, msg);
@@ -174,26 +174,18 @@
     }
     
     /*
-     * TODO Not supported in PyWinRM.
+     * TODO Not supported in winrm4j (or PyWinRM).
      * 
-     * Executing (in python):
-     *     import winrm
-     *     s = winrm.Session('52.12.211.247', auth=('Administrator', 'pa55w0rd'))
-     *     r = s.run_cmd("echo first \r\n echo second")
-     * gives just "first".
+     * Just gives "first", and exit code 1.
      */
-    @Test(groups={"Live", "WIP"})
+    @Test(groups={"Live", "WIP"}, enabled=false)
     public void testExecMultiLineScript() throws Exception {
         assertExecSucceeds("echo first" + "\r\n" + "echo second", "first"+"\r\n"+"second", "");
     }
     
-    /*
-     * TODO Not supported in PyWinRM. Under the covers, we just concatenate the commands.
-     * See {@link #testExecMultiLineScript()}.
-     */
-    @Test(groups={"Live", "WIP"})
+    @Test(groups={"Live"})
     public void testExecMultiPartScript() throws Exception {
-        assertExecSucceeds(ImmutableList.of("echo first", "echo second"), "first"+"\r\n"+"second", "");
+        assertExecSucceeds(ImmutableList.of("echo first", "echo second"), "first "+"\r\n"+"second", "");
     }
     
     @Test(groups="Live")
@@ -212,7 +204,7 @@
     }
 
     /*
-     * TODO Not supported in PyWinRM.
+     * TODO Not supported in winrm4j (or PyWinRM).
      * 
      * Executing (in python):
      *     import winrm
@@ -443,7 +435,7 @@
     }
 
     /*
-     * TODO Not supported in PyWinRM - single line .ps1 file with "exit 1" gives an
+     * TODO Not supported in winrm4j - single line .ps1 file with "exit 1" gives an
      * exit code 0 over PyWinRM, but an exit code 1 when executed locally!
      * 
      * Executing (in python):
@@ -554,12 +546,12 @@
 
     private void assertExecFails(String cmd) {
         Stopwatch stopwatch = Stopwatch.createStarted();
-        assertFailed(cmd, machine.executeScript(cmd), stopwatch);
+        assertFailed(cmd, machine.executeCommand(cmd), stopwatch);
     }
 
     private void assertExecFails(List<String> cmds) {
         Stopwatch stopwatch = Stopwatch.createStarted();
-        assertFailed(cmds, machine.executeScript(cmds), stopwatch);
+        assertFailed(cmds, machine.executeCommand(cmds), stopwatch);
     }
     
     private void assertExecPsFails(String cmd) {
@@ -574,12 +566,12 @@
 
     private void assertExecSucceeds(String cmd, String stdout, String stderr) {
         Stopwatch stopwatch = Stopwatch.createStarted();
-        assertSucceeded(cmd, machine.executeScript(cmd), stdout, stderr, stopwatch);
+        assertSucceeded(cmd, machine.executeCommand(cmd), stdout, stderr, stopwatch);
     }
 
     private void assertExecSucceeds(List<String> cmds, String stdout, String stderr) {
         Stopwatch stopwatch = Stopwatch.createStarted();
-        assertSucceeded(cmds, machine.executeScript(cmds), stdout, stderr, stopwatch);
+        assertSucceeded(cmds, machine.executeCommand(cmds), stdout, stderr, stopwatch);
     }
 
     private void assertExecPsSucceeds(String cmd, String stdout, String stderr) {
diff --git a/brooklyn-server/software/winrm/src/main/java/org/apache/brooklyn/feed/windows/WindowsPerformanceCounterFeed.java b/brooklyn-server/software/winrm/src/main/java/org/apache/brooklyn/feed/windows/WindowsPerformanceCounterFeed.java
index b6f8684..1939ed0 100644
--- a/brooklyn-server/software/winrm/src/main/java/org/apache/brooklyn/feed/windows/WindowsPerformanceCounterFeed.java
+++ b/brooklyn-server/software/winrm/src/main/java/org/apache/brooklyn/feed/windows/WindowsPerformanceCounterFeed.java
@@ -116,8 +116,8 @@
         private String uniqueTag;
         private volatile boolean built;
 
-        public Builder entity(EntityLocal val) {
-            this.entity = checkNotNull(val, "entity");
+        public Builder entity(Entity val) {
+            this.entity = (EntityLocal) checkNotNull(val, "entity");
             return this;
         }
         public Builder addSensor(WindowsPerformanceCounterPollConfig<?> config) {
diff --git a/brooklyn-server/software/winrm/src/main/java/org/apache/brooklyn/location/winrm/WinRmMachineLocation.java b/brooklyn-server/software/winrm/src/main/java/org/apache/brooklyn/location/winrm/WinRmMachineLocation.java
index 8a2a786..d04c366 100644
--- a/brooklyn-server/software/winrm/src/main/java/org/apache/brooklyn/location/winrm/WinRmMachineLocation.java
+++ b/brooklyn-server/software/winrm/src/main/java/org/apache/brooklyn/location/winrm/WinRmMachineLocation.java
@@ -44,7 +44,7 @@
 import org.apache.brooklyn.util.core.internal.ssh.SshTool;
 import org.apache.brooklyn.util.core.internal.winrm.WinRmTool;
 import org.apache.brooklyn.util.core.internal.winrm.WinRmToolResponse;
-import org.apache.brooklyn.util.core.internal.winrm.pywinrm.Winrm4jTool;
+import org.apache.brooklyn.util.core.internal.winrm.winrm4j.Winrm4jTool;
 import org.apache.brooklyn.util.exceptions.Exceptions;
 import org.apache.brooklyn.util.stream.Streams;
 import org.apache.brooklyn.util.text.Strings;
@@ -212,17 +212,50 @@
         return (result == null) ? ImmutableSet.<String>of() : ImmutableSet.copyOf(result);
     }
 
+    /**
+     * @deprecated since 0.9.0; use {@link #executeCommand(String)}
+     */
+    @Deprecated
     public WinRmToolResponse executeScript(String script) {
-        return executeScript(ImmutableList.of(script));
+        return executeCommand(script);
     }
 
+    /**
+     * @deprecated since 0.9.0; use {@link #executeCommand(List)}
+     */
+    @Deprecated
     public WinRmToolResponse executeScript(List<String> script) {
-        return executeScript(ImmutableMap.of(), script);
+        return executeCommand(script);
     }
     
+    /**
+     * @deprecated since 0.9.0; use {@link #executeCommand(Map, List)}
+     */
+    @Deprecated
     public WinRmToolResponse executeScript(Map<?,?> props, List<String> script) {
+        return executeCommand(props, script);
+    }
+
+    /**
+     * @since 0.9.0 (previously was {@code executeScript(String)}
+     */
+    public WinRmToolResponse executeCommand(String script) {
+        return executeCommand(ImmutableList.of(script));
+    }
+
+    /**
+     * @since 0.9.0 (previously was {@code executeScript(List)}
+     */
+    public WinRmToolResponse executeCommand(List<String> script) {
+        return executeCommand(ImmutableMap.of(), script);
+    }
+    
+    /**
+     * @since 0.9.0 (previously was {@code executeScript(Map, List)}
+     */
+    public WinRmToolResponse executeCommand(Map<?,?> props, List<String> script) {
         WinRmTool tool = newWinRmTool(props);
-        return tool.executeScript(script);
+        return tool.executeCommand(script);
     }
 
     public WinRmToolResponse executePsScript(String psScript) {
diff --git a/brooklyn-server/software/winrm/src/main/java/org/apache/brooklyn/util/core/internal/winrm/WinRmTool.java b/brooklyn-server/software/winrm/src/main/java/org/apache/brooklyn/util/core/internal/winrm/WinRmTool.java
index 6d2fb06..5515ec5 100644
--- a/brooklyn-server/software/winrm/src/main/java/org/apache/brooklyn/util/core/internal/winrm/WinRmTool.java
+++ b/brooklyn-server/software/winrm/src/main/java/org/apache/brooklyn/util/core/internal/winrm/WinRmTool.java
@@ -66,8 +66,17 @@
             "Size of file chunks (in bytes) to be used when copying a file to the remote server", 
             1024);
 
+    /**
+     * @deprecated since 0.9.0; use {@link #executeCommand(List)} to avoid ambiguity between native command and power shell.
+     */
+    @Deprecated
     WinRmToolResponse executeScript(List<String> commands);
 
+    /**
+     * @since 0.9.0
+     */
+    WinRmToolResponse executeCommand(List<String> commands);
+
     WinRmToolResponse executePs(List<String> commands);
     
     WinRmToolResponse copyToServer(InputStream source, String destination);
diff --git a/brooklyn-server/software/winrm/src/main/java/org/apache/brooklyn/util/core/internal/winrm/pywinrm/Winrm4jTool.java b/brooklyn-server/software/winrm/src/main/java/org/apache/brooklyn/util/core/internal/winrm/winrm4j/Winrm4jTool.java
similarity index 96%
rename from brooklyn-server/software/winrm/src/main/java/org/apache/brooklyn/util/core/internal/winrm/pywinrm/Winrm4jTool.java
rename to brooklyn-server/software/winrm/src/main/java/org/apache/brooklyn/util/core/internal/winrm/winrm4j/Winrm4jTool.java
index 0bdfa14..e023cfb 100644
--- a/brooklyn-server/software/winrm/src/main/java/org/apache/brooklyn/util/core/internal/winrm/pywinrm/Winrm4jTool.java
+++ b/brooklyn-server/software/winrm/src/main/java/org/apache/brooklyn/util/core/internal/winrm/winrm4j/Winrm4jTool.java
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.brooklyn.util.core.internal.winrm.pywinrm;
+package org.apache.brooklyn.util.core.internal.winrm.winrm4j;
 
 import static com.google.common.base.Preconditions.checkNotNull;
 
@@ -84,15 +84,21 @@
     }
     
     @Override
-    public org.apache.brooklyn.util.core.internal.winrm.WinRmToolResponse executeScript(final List<String> commands) {
+    public org.apache.brooklyn.util.core.internal.winrm.WinRmToolResponse executeCommand(final List<String> commands) {
         return exec(new Function<io.cloudsoft.winrm4j.winrm.WinRmTool, io.cloudsoft.winrm4j.winrm.WinRmToolResponse>() {
             @Override public WinRmToolResponse apply(io.cloudsoft.winrm4j.winrm.WinRmTool tool) {
-                return tool.executeScript(commands);
+                return tool.executeCommand(commands);
             }
         });
     }
 
     @Override
+    @Deprecated
+    public org.apache.brooklyn.util.core.internal.winrm.WinRmToolResponse executeScript(final List<String> commands) {
+        return executeCommand(commands);
+    }
+    
+    @Override
     public org.apache.brooklyn.util.core.internal.winrm.WinRmToolResponse executePs(final List<String> commands) {
         return exec(new Function<io.cloudsoft.winrm4j.winrm.WinRmTool, io.cloudsoft.winrm4j.winrm.WinRmToolResponse>() {
             @Override public WinRmToolResponse apply(io.cloudsoft.winrm4j.winrm.WinRmTool tool) {
diff --git a/brooklyn-server/software/winrm/src/test/java/org/apache/brooklyn/feed/windows/WindowsPerformanceCounterFeedLiveTest.java b/brooklyn-server/software/winrm/src/test/java/org/apache/brooklyn/feed/windows/WindowsPerformanceCounterFeedLiveTest.java
index de7d481..412a732 100644
--- a/brooklyn-server/software/winrm/src/test/java/org/apache/brooklyn/feed/windows/WindowsPerformanceCounterFeedLiveTest.java
+++ b/brooklyn-server/software/winrm/src/test/java/org/apache/brooklyn/feed/windows/WindowsPerformanceCounterFeedLiveTest.java
@@ -20,16 +20,15 @@
 
 import java.util.Map;
 
-import org.apache.brooklyn.api.entity.EntityLocal;
+import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.entity.EntitySpec;
 import org.apache.brooklyn.api.location.Location;
-import org.apache.brooklyn.api.location.MachineLocation;
 import org.apache.brooklyn.api.location.MachineProvisioningLocation;
 import org.apache.brooklyn.api.sensor.AttributeSensor;
+import org.apache.brooklyn.core.entity.EntityAsserts;
 import org.apache.brooklyn.core.sensor.Sensors;
 import org.apache.brooklyn.core.test.BrooklynAppLiveTestSupport;
 import org.apache.brooklyn.core.test.entity.TestEntity;
-import org.apache.brooklyn.test.EntityTestUtils;
 import org.apache.brooklyn.util.collections.MutableMap;
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
@@ -51,8 +50,8 @@
  * <pre>
  * {@code brooklyn.location.named.WindowsLiveTest=byon:(hosts="ec2-xx-xxx-xxx-xx.eu-west-1.compute.amazonaws.com")
  * brooklyn.location.named.WindowsLiveTest.user=Administrator
- * brooklyn.location.named.WindowsLiveTest.privateKeyFile = ~/.ssh/id_rsa
- * brooklyn.location.named.WindowsLiveTest.publicKeyFile = ~/.ssh/id_rsa.pub
+ * brooklyn.location.named.WindowsLiveTest.password=pa55word
+ * brooklyn.location.named.WindowsLiveTest.osFamily=windows
  * }</pre>
  * The location must by {@code byon} or another primitive type. Unfortunately, it's not possible to
  * use a jclouds location, as adding a dependency on brooklyn-locations-jclouds would cause a
@@ -66,7 +65,7 @@
     private static final String LOCATION_SPEC = "named:WindowsLiveTest";
 
     private Location loc;
-    private EntityLocal entity;
+    private Entity entity;
 
     @BeforeMethod(alwaysRun=true)
     public void setUp() throws Exception {
@@ -75,16 +74,15 @@
         Map<String,?> allFlags = MutableMap.<String,Object>builder()
                 .put("tags", ImmutableList.of(getClass().getName()))
                 .build();
-        MachineProvisioningLocation<? extends MachineLocation> provisioningLocation =
-                (MachineProvisioningLocation<? extends MachineLocation>)
-                        mgmt.getLocationRegistry().resolve(LOCATION_SPEC, allFlags);
+        MachineProvisioningLocation<?> provisioningLocation = (MachineProvisioningLocation<?>) 
+                mgmt.getLocationRegistry().resolve(LOCATION_SPEC, allFlags);
         loc = provisioningLocation.obtain(ImmutableMap.of());
 
         entity = app.createAndManageChild(EntitySpec.create(TestEntity.class));
         app.start(ImmutableList.of(loc));
     }
 
-    @Test(groups={"Live","Disabled"}, enabled=false)
+    @Test(groups={"Live","Disabled"})
     public void testRetrievesPerformanceCounters() throws Exception {
         // We can be pretty sure that a Windows instance in the cloud will have zero telephone lines...
         entity.sensors().set(TELEPHONE_LINES, 42);
@@ -94,7 +92,7 @@
                 .addSensor("\\Telephony\\Lines", TELEPHONE_LINES)
                 .build();
         try {
-            EntityTestUtils.assertAttributeEqualsEventually(entity, TELEPHONE_LINES, 0);
+            EntityAsserts.assertAttributeEqualsEventually(entity, TELEPHONE_LINES, 0);
         } finally {
             feed.stop();
         }