CB-12416 (Windows) Built bundles are misplaced when building for multiple archs

Added scale-240 exclude back to avoid an empty Windows 10 package creation
This closes #226
diff --git a/spec/e2e/endtoend.spec.js b/spec/e2e/endtoend.spec.js
index ac86ab0..71ed278 100644
--- a/spec/e2e/endtoend.spec.js
+++ b/spec/e2e/endtoend.spec.js
@@ -35,8 +35,14 @@
         appPackagesFolder = path.join(buildDirectory, projectFolder, 'AppPackages'),
         buildScriptPath   = '"' + path.join(buildDirectory, projectFolder, 'cordova', 'build') + '"';
 
+    function verifySubDirContainsFile(subDirName, fileName) {
+        var subDir = path.join(appPackagesFolder, subDirName);
+        var packages = shell.ls(subDir);
+        expect(packages.filter(function(file) { return file.match(fileName); }).length).toBe(1);
+    }
+
     beforeEach(function(){
-      shell.exec(path.join('bin', 'create') + ' "' + projectFolder + '" com.test.app 応用', {silent : true});
+        shell.exec(path.join('bin', 'create') + ' "' + projectFolder + '" com.test.app 応用', {silent : true});
     });
 
     afterEach(function() {
@@ -68,11 +74,11 @@
         expect(packages.filter(function(file) { return file.match(/.*Phone.*x86.*\.appx.*/); }).length).toBe(1);
         expect(packages.filter(function(file) { return file.match(/.*Phone.*x64.*\.appx.*/); }).length).toBe(1);
         expect(packages.filter(function(file) { return file.match(/.*Phone.*arm.*\.appx.*/); }).length).toBe(1);
-        expect(packages.filter(function(file) { return file.match(/.*Phone.*AnyCPU.*\.appx.*/); }).length).toBe(1);
+        expect(packages.filter(function(file) { return file.match(/.*Phone.*AnyCPU.*\.appx.*/i); }).length).toBe(1);
         expect(packages.filter(function(file) { return file.match(/.*Windows.*x64.*\.appx.*/); }).length).toBe(1);
         expect(packages.filter(function(file) { return file.match(/.*Windows.*x86.*\.appx.*/); }).length).toBe(1);
         expect(packages.filter(function(file) { return file.match(/.*Windows.*arm.*\.appx.*/); }).length).toBe(1);
-        expect(packages.filter(function(file) { return file.match(/.*Windows.*anycpu.*\.appx.*/); }).length).toBe(1);
+        expect(packages.filter(function(file) { return file.match(/.*Windows.*anycpu.*\.appx.*/i); }).length).toBe(1);
     });
 
     it('spec.5 should build project containing plugin with InProcessServer extension', function(done){
@@ -103,10 +109,15 @@
         });
     });
 
-    it('spec.6 should generate appxupload for Windows 8.1 project bundle release build', function(){
+    it('spec.6 should generate appxupload and appxbundle for Windows 8.1 project bundle release build', function(){
         shell.exec(buildScriptPath + ' --release --win --bundle --archs=\"x64 x86 arm\"', {silent : true});
         var packages = shell.ls(appPackagesFolder);
         expect(packages.filter(function(file) { return file.match(/.*bundle\.appxupload$/); }).length > 0).toBeTruthy();
+
+        var bundleDirName = 'CordovaApp.Windows_1.0.0.0_Test';
+        expect(packages.filter(function(file) { return file.match(bundleDirName); }).length).toBe(1);
+
+        verifySubDirContainsFile(bundleDirName, 'CordovaApp.Windows_1.0.0.0_x64_x86_arm.appxbundle');
     });
 
     it('spec.6.1 should generate appxupload for Windows 8.1 project non-bundle release build', function(){
@@ -115,15 +126,51 @@
         expect(packages.filter(function(file) { return file.match(/.*\.appxupload$/); }).length).toBe(3);
     });
 
-    it('spec.7 should generate appxupload for Windows 10 project bundle release build', function(){
+    it('spec.7 should generate appxupload and appxbundle for Windows 10 project bundle release build', function(){
         shell.exec(buildScriptPath + ' --release --win --appx=uap --bundle --archs=\"x64 x86 arm\"', {silent : true});
         var packages = shell.ls(appPackagesFolder);
         expect(packages.filter(function(file) { return file.match(/.*bundle\.appxupload$/); }).length > 0).toBeTruthy();
+
+        var bundleDirName = 'CordovaApp.Windows10_1.0.0.0_Test';
+        expect(packages.filter(function(file) { return file.match(bundleDirName); }).length).toBe(1);
+
+        verifySubDirContainsFile(bundleDirName, 'CordovaApp.Windows10_1.0.0.0_x64_x86_arm.appxbundle');
     });
 
     it('spec.7.1 should generate appxupload for Windows 10 project non-bundle release build', function(){
         shell.exec(buildScriptPath + ' --release --win --appx=uap --archs=\"x64 x86 arm\"', {silent : true});
         var packages = shell.ls(appPackagesFolder);
         expect(packages.filter(function(file) { return file.match(/.*\.appxupload$/); }).length).toBe(3);
+
+        // CB-12416 Should build appx in separate dirs for each architecture
+        var armSubDir = 'CordovaApp.Windows10_1.0.0.0_arm_Test',
+            x64SubDir = 'CordovaApp.Windows10_1.0.0.0_x64_Test',
+            x86SubDir = 'CordovaApp.Windows10_1.0.0.0_x86_Test';
+
+        // Should contain a subdirectory for each of the architectures
+        expect(packages.filter(function(file) { return file.match(armSubDir); }).length).toBe(1);
+        expect(packages.filter(function(file) { return file.match(x64SubDir); }).length).toBe(1);
+        expect(packages.filter(function(file) { return file.match(x86SubDir); }).length).toBe(1);
+
+        // These subdirectories should contain corresponding appx files
+        verifySubDirContainsFile(armSubDir, 'CordovaApp.Windows10_1.0.0.0_arm.appx');
+        verifySubDirContainsFile(x64SubDir, 'CordovaApp.Windows10_1.0.0.0_x64.appx');
+        verifySubDirContainsFile(x86SubDir, 'CordovaApp.Windows10_1.0.0.0_x86.appx');
+    });
+
+    it('spec.8 for a non-bundle case for Windows Phone 8.1 it should build appx in separate dirs for each architecture', function(){
+        shell.exec(buildScriptPath + ' --release --phone --archs=\"x86 arm\"', {silent : true});
+        var packages = shell.ls(appPackagesFolder);
+
+        var armSubDir = 'CordovaApp.Phone_1.0.0.0_arm_Test',
+            x86SubDir = 'CordovaApp.Phone_1.0.0.0_x86_Test';
+
+        // Should contain a subdirectory for each of the architectures
+        expect(packages.filter(function(file) { return file.match(armSubDir); }).length).toBe(1);
+        expect(packages.filter(function(file) { return file.match(x86SubDir); }).length).toBe(1);
+
+        // These subdirectories should contain corresponding appx files
+        verifySubDirContainsFile(armSubDir, 'CordovaApp.Phone_1.0.0.0_arm.appx');
+        verifySubDirContainsFile(x86SubDir, 'CordovaApp.Phone_1.0.0.0_x86.appx');
     });
 });
diff --git a/spec/unit/build.spec.js b/spec/unit/build.spec.js
index 3abd630..ade3a01 100644
--- a/spec/unit/build.spec.js
+++ b/spec/unit/build.spec.js
@@ -449,8 +449,9 @@
             .fail(fail)
             .finally(function() {
                 expect(fail).not.toHaveBeenCalled();
+                // CB-12416 AppxBundle=Never is present because we are not building a bundle
                 expect(buildTools.buildProject).toHaveBeenCalledWith(jasmine.any(String),
-                    jasmine.any(String), jasmine.any(String), [ 'foo=bar' ]);
+                    jasmine.any(String), jasmine.any(String), [ 'foo=bar', '/p:AppxBundle=Never' ]);
 
                 done();
             });
diff --git a/template/CordovaApp.Windows.jsproj b/template/CordovaApp.Windows.jsproj
index b5f43d6..35c8f68 100644
--- a/template/CordovaApp.Windows.jsproj
+++ b/template/CordovaApp.Windows.jsproj
@@ -79,9 +79,9 @@
     <AppxManifest Include="package.windows.appxmanifest">
       <SubType>Designer</SubType>
     </AppxManifest>
-    <Content Exclude="images\*SplashScreenPhone*" Include="images\*.png" />
-    <Content Exclude="images\*SplashScreenPhone*" Include="images\*.jpg" />
-    <Content Exclude="images\*SplashScreenPhone*" Include="images\*.jpeg" />
+    <Content Exclude="images\*SplashScreenPhone*;images\*.scale-240.*" Include="images\*.png" />
+    <Content Exclude="images\*SplashScreenPhone*;images\*.scale-240.*" Include="images\*.jpg" />
+    <Content Exclude="images\*SplashScreenPhone*;images\*.scale-240.*" Include="images\*.jpeg" />
   </ItemGroup>
   <ItemGroup>
     <SDKReference Include="Microsoft.WinJS.2.0, Version=1.0" />
diff --git a/template/CordovaApp.Windows10.jsproj b/template/CordovaApp.Windows10.jsproj
index 8a496dd..d2fa1bf 100644
--- a/template/CordovaApp.Windows10.jsproj
+++ b/template/CordovaApp.Windows10.jsproj
@@ -98,9 +98,9 @@
     <AppxManifest Include="package.windows10.appxmanifest">
       <SubType>Designer</SubType>
     </AppxManifest>
-    <Content Exclude="images\*SplashScreenPhone*" Include="images\*.png" />
-    <Content Exclude="images\*SplashScreenPhone*" Include="images\*.jpg" />
-    <Content Exclude="images\*SplashScreenPhone*" Include="images\*.jpeg" />
+    <Content Exclude="images\*SplashScreenPhone*;images\*.scale-240.*" Include="images\*.png" />
+    <Content Exclude="images\*SplashScreenPhone*;images\*.scale-240.*" Include="images\*.jpg" />
+    <Content Exclude="images\*SplashScreenPhone*;images\*.scale-240.*" Include="images\*.jpeg" />
   </ItemGroup>
   <Import Project="CordovaApp.projitems" Label="Shared" />
   <Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\$(WMSJSProjectDirectory)\Microsoft.VisualStudio.$(WMSJSProject).targets" />
diff --git a/template/cordova/lib/build.js b/template/cordova/lib/build.js
index ca79fcf..b9bbfeb 100644
--- a/template/cordova/lib/build.js
+++ b/template/cordova/lib/build.js
@@ -342,6 +342,11 @@
                 // Only add the CordovaBundlePlatforms argument when on the last build step
                 var bundleArchs = (index === configsArray.length - 1) ? bundleTerms : build.arch;
                 otherProperties.push('/p:CordovaBundlePlatforms=' + bundleArchs);
+            } else {
+                // https://issues.apache.org/jira/browse/CB-12416
+                // MSBuild uses AppxBundle=Always by default which leads to a bundle created even if
+                // --bundle was not passed - override that:
+                otherProperties.push('/p:AppxBundle=Never');
             }
 
             // https://issues.apache.org/jira/browse/CB-12298