    public boolean perform(AbstractBuild build, Launcher launcher, BuildListener listener) {
        try {
            FilePath[] files = build.getProject().getWorkspace().list("test-result/*");
            for (FilePath filePath : files) {
                filePath.delete();
            }
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
        Map<String,String> exitcodes = new HashMap<String, String>();
        String playpath = null;
        if(play_path != null && play_path.length() > 0) {
            playpath = play_path;
        } else if(getDescriptor().path()!= null){
            playpath = getDescriptor().path();
        }else{
            listener.getLogger().println("play path is null");
            return false;
        }
        listener.getLogger().println("play path is "+playpath);
        FilePath workDir = build.getWorkspace();
        String application_path = ((PlayAutoTestJobProperty)build.getProject().getProperty(PlayAutoTestJobProperty.class)).getApplication_path();
        if (application_path!= null && application_path.length() > 0) {
            workDir = build.getWorkspace().child(application_path);
        }
        try {
            for(String play_cmd : this.play_cmds){
                if(play_cmd!=null && play_cmd.length()==0) continue;
                listener.getLogger().println("Substituting job parameters from " + play_cmd);
                ParametersAction param = build.getAction(hudson.model.ParametersAction.class);
                List<ParameterValue> values = param.getParameters();
                if (values != null) {
                    for (ParameterValue value : values) {
                        String v = value.createVariableResolver(build).resolve(value.getName());
                        play_cmd = play_cmd.replace("${" + value.getName() + "}", v);
                    }
                }
                String[] cmds= play_cmd.split(" ",2);
                String cmd = playpath + " " + cmds[0] +" "+workDir.toString()+" "+(cmds.length>=2? cmds[1]:"");
                listener.getLogger().println("Executing " + cmd);
                Proc proc = launcher.launch(cmd, new String[0],listener.getLogger(),workDir);
                int exitcode = proc.join();
                exitcodes.put(play_cmd, (exitcode==0? "Done":"Fail"));
                if(exitcode!=0) {
                    listener.getLogger().println("****************************************************");
                    listener.getLogger().println("* ERROR!!! while executing "+play_cmd);
                    listener.getLogger().println("****************************************************");
                    return false;
                }
                if("auto-test".equalsIgnoreCase(play_cmd)){
                    if(! new File(workDir.toString()+"/test-result/result.passed").exists()){
                        build.setResult(Result.UNSTABLE);
                    }
                }
            }
            listener.getLogger().println("Each commands' results:");
            for(Map.Entry<String, String> rec : exitcodes.entrySet()){
                listener.getLogger().println("  "+rec.getKey()+": "+rec.getValue());
            }
            return exitcodes.containsValue("Fail")? false : true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    public boolean perform(AbstractBuild build, Launcher launcher, BuildListener listener) {
        try {
            FilePath[] files = build.getProject().getWorkspace().list("test-result/*");
            for (FilePath filePath : files) {
                filePath.delete();
            }
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
        Map<String,String> exitcodes = new HashMap<String, String>();
        String playpath = null;
        if(play_path != null && play_path.length() > 0) {
            playpath = play_path;
        } else if(getDescriptor().path()!= null){
            playpath = getDescriptor().path();
        }else{
            listener.getLogger().println("play path is null");
            return false;
        }
        listener.getLogger().println("play path is "+playpath);
        FilePath workDir = build.getWorkspace();
        String application_path = ((PlayAutoTestJobProperty)build.getProject().getProperty(PlayAutoTestJobProperty.class)).getApplication_path();
        if (application_path!= null && application_path.length() > 0) {
            workDir = build.getWorkspace().child(application_path);
        }
        try {
            for(String play_cmd : this.play_cmds){
                if(play_cmd!=null && play_cmd.length()==0) continue;
                listener.getLogger().println("Substituting job parameters from " + play_cmd);
                ParametersAction param = build.getAction(hudson.model.ParametersAction.class);
                List<ParameterValue> values = param.getParameters();
                if (values != null) {
                    for (ParameterValue value : values) {
                        String v = value.createVariableResolver(build).resolve(value.getName());
                        play_cmd = play_cmd.replace("${" + value.getName() + "}", v);
                    }
                }
                String[] cmds= play_cmd.split(" ",2);
                String cmd = playpath + " " + cmds[0] +" \""+workDir.toString()+"\" "+(cmds.length>=2? cmds[1]:"");
                listener.getLogger().println("Executing " + cmd);
                Proc proc = launcher.launch(cmd, new String[0],listener.getLogger(),workDir);
                int exitcode = proc.join();
                exitcodes.put(play_cmd, (exitcode==0? "Done":"Fail"));
                if(exitcode!=0) {
                    listener.getLogger().println("****************************************************");
                    listener.getLogger().println("* ERROR!!! while executing "+play_cmd);
                    listener.getLogger().println("****************************************************");
                    return false;
                }
                if("auto-test".equalsIgnoreCase(play_cmd)){
                    if(! new File(workDir.toString()+"/test-result/result.passed").exists()){
                        build.setResult(Result.UNSTABLE);
                    }
                }
            }
            listener.getLogger().println("Each commands' results:");
            for(Map.Entry<String, String> rec : exitcodes.entrySet()){
                listener.getLogger().println("  "+rec.getKey()+": "+rec.getValue());
            }
            return exitcodes.containsValue("Fail")? false : true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
