    private void doAPKWithAPKBuilder( File outputFile, File dexFile, File zipArchive, ArrayList<File> sourceFolders,
                                      ArrayList<File> jarFiles, ArrayList<File> nativeFolders,
                                      boolean signWithDebugKeyStore ) throws MojoExecutionException
    {
        getLog().debug( "Building APK with internal APKBuilder" );
        sourceFolders.add( new File( project.getBuild().getOutputDirectory() ) );
        for ( Artifact artifact : getRelevantCompileArtifacts() )
        {
            if ( extractDuplicates )
            {
                try
                {
                    computeDuplicateFiles( artifact.getFile() );
                }
                catch ( Exception e )
                {
                    getLog().warn( "Cannot compute duplicates files from " + artifact.getFile().getAbsolutePath(), e );
                }
            }
            jarFiles.add( artifact.getFile() );
        }
        if ( extractDuplicates )
        {
            List<String> duplicates = new ArrayList<String>();
            List<File> jarToModify = new ArrayList<File>();
            for ( String s : jars.keySet() )
            {
                List<File> l = jars.get( s );
                if ( l.size() > 1 )
                {
                    getLog().warn( "Duplicate file " + s + " : " + l );
                    duplicates.add( s );
                    for ( int i = 1; i < l.size(); i++ )
                    {
                        if ( ! jarToModify.contains( l.get( i ) ) )
                        {
                            jarToModify.add( l.get( i ) );
                        }
                    }
                }
            }
            for ( File file : jarToModify )
            {
                File newJar;
                newJar = removeDuplicatesFromJar( file, duplicates );
                int index = jarFiles.indexOf( file );
                if ( newJar != null )
                {
                    jarFiles.set( index, newJar );
                }
            }
        }
        String debugKeyStore;
        ApkBuilder apkBuilder; 
        try 
        {
            debugKeyStore = ApkBuilder.getDebugKeystore();
            apkBuilder = 
                    new ApkBuilder( outputFile, zipArchive, dexFile, 
                            ( signWithDebugKeyStore ) ? debugKeyStore : null, null );
            if ( apkDebug )
            {
                apkBuilder.setDebugMode( apkDebug );
            }
            for ( File sourceFolder : sourceFolders )
            {
                apkBuilder.addSourceFolder( sourceFolder );
            }
            for ( File jarFile : jarFiles )
            {
                boolean excluded = false;
                if ( excludeJarResourcesPatterns != null )
                {
                    final String name = jarFile.getName();
                    getLog().debug( "Checking " + name + " against patterns" );
                    for ( Pattern pattern : excludeJarResourcesPatterns )
                    {
                        final Matcher matcher = pattern.matcher( name );
                        if ( matcher.matches() ) 
                        {
                            getLog().debug( "Jar " + name + " excluded by pattern " + pattern );
                            excluded = true;
                            break;
                        } 
                        else 
                        {
                            getLog().debug( "Jar " + name + " not excluded by pattern " + pattern );
                        }
                    }
                }
                if ( excluded )
                {
                    continue;
                }
                if ( jarFile.isDirectory() )
                {
                    String[] filenames = jarFile.list( new FilenameFilter()
                    {
                        public boolean accept( File dir, String name )
                        {
                            return PATTERN_JAR_EXT.matcher( name ).matches();
                        }
                    } );
                    for ( String filename : filenames )
                    {
                        apkBuilder.addResourcesFromJar( new File( jarFile, filename ) );
                    }
                }
                else
                {
                    apkBuilder.addResourcesFromJar( jarFile );
                }
            }
            for ( File nativeFolder : nativeFolders )
            {
                apkBuilder.addNativeLibraries( nativeFolder );
            }
            apkBuilder.sealApk();
        } 
        catch ( ApkCreationException e )
        {
            throw new MojoExecutionException( e.getMessage() );
        } 
        catch ( DuplicateFileException e )
        {
            throw new MojoExecutionException( e.getMessage() );
        } 
        catch ( SealedApkException e )
        {
            throw new MojoExecutionException( e.getMessage() );
        }
    }

    private void doAPKWithAPKBuilder( File outputFile, File dexFile, File zipArchive, ArrayList<File> sourceFolders,
                                      ArrayList<File> jarFiles, ArrayList<File> nativeFolders,
                                      boolean signWithDebugKeyStore ) throws MojoExecutionException
    {
        getLog().debug( "Building APK with internal APKBuilder" );
        sourceFolders.add( new File( project.getBuild().getOutputDirectory() ) );
        for ( Artifact artifact : getRelevantCompileArtifacts() )
        {
            if ( extractDuplicates )
            {
                try
                {
                    computeDuplicateFiles( artifact.getFile() );
                }
                catch ( Exception e )
                {
                    getLog().warn( "Cannot compute duplicates files from " + artifact.getFile().getAbsolutePath(), e );
                }
            }
            jarFiles.add( artifact.getFile() );
        }
        if ( extractDuplicates )
        {
            List<String> duplicates = new ArrayList<String>();
            List<File> jarToModify = new ArrayList<File>();
            for ( String s : jars.keySet() )
            {
                List<File> l = jars.get( s );
                if ( l.size() > 1 )
                {
                    getLog().warn( "Duplicate file " + s + " : " + l );
                    duplicates.add( s );
                    for ( int i = 1; i < l.size(); i++ )
                    {
                        if ( ! jarToModify.contains( l.get( i ) ) )
                        {
                            jarToModify.add( l.get( i ) );
                        }
                    }
                }
            }
            for ( File file : jarToModify )
            {
                File newJar;
                newJar = removeDuplicatesFromJar( file, duplicates );
                int index = jarFiles.indexOf( file );
                if ( newJar != null )
                {
                    jarFiles.set( index, newJar );
                }
            }
        }
        String debugKeyStore;
        ApkBuilder apkBuilder; 
        try 
        {
            debugKeyStore = ApkBuilder.getDebugKeystore();
            apkBuilder = 
                    new ApkBuilder( outputFile, zipArchive, dexFile, 
                            ( signWithDebugKeyStore ) ? debugKeyStore : null, null );
            if ( apkDebug )
            {
                apkBuilder.setDebugMode( apkDebug );
            }
            for ( File sourceFolder : sourceFolders )
            {
                apkBuilder.addSourceFolder( sourceFolder );
            }
            for ( File jarFile : jarFiles )
            {
                boolean excluded = false;
                if ( excludeJarResourcesPatterns != null )
                {
                    final String name = jarFile.getName();
                    getLog().debug( "Checking " + name + " against patterns" );
                    for ( Pattern pattern : excludeJarResourcesPatterns )
                    {
                        final Matcher matcher = pattern.matcher( name );
                        if ( matcher.matches() ) 
                        {
                            getLog().debug( "Jar " + name + " excluded by pattern " + pattern );
                            excluded = true;
                            break;
                        } 
                        else 
                        {
                            getLog().debug( "Jar " + name + " not excluded by pattern " + pattern );
                        }
                    }
                }
                if ( excluded )
                {
                    continue;
                }
                if ( jarFile.isDirectory() )
                {
                    String[] filenames = jarFile.list( new FilenameFilter()
                    {
                        public boolean accept( File dir, String name )
                        {
                            return PATTERN_JAR_EXT.matcher( name ).matches();
                        }
                    } );
                    for ( String filename : filenames )
                    {
                        apkBuilder.addResourcesFromJar( new File( jarFile, filename ) );
                    }
                }
                else
                {
                    apkBuilder.addResourcesFromJar( jarFile );
                }
            }
            for ( File nativeFolder : nativeFolders )
            {
                apkBuilder.addNativeLibraries( nativeFolder );
            }
            apkBuilder.sealApk();
        } 
        catch ( ApkCreationException e )
        {
            throw new MojoExecutionException( e.getMessage() );
        } 
        catch ( DuplicateFileException e )
        {
            final String msg = String.format("Duplicate file! archive: %s, file1: %s, file2: %s",
                    e.getArchivePath(), e.getFile1(), e.getFile2());
            throw new MojoExecutionException( msg, e );
        } 
        catch ( SealedApkException e )
        {
            throw new MojoExecutionException( e.getMessage() );
        }
    }
