public void promoteFile(ScriptRunner pScriptRunner, PromotionFile pPromotionFile) 
  throws ExPromote {
    
    PromotionController lController = pScriptRunner.getPromotionController();
    
    boolean lPromoteFile = lController.validateAndStartFilePromote(pPromotionFile);    
    if(lPromoteFile){
      //Do the promotion
      boolean lSuccess = true;
      try {
        doPromote(pScriptRunner, pPromotionFile);
      }
      catch (ExPromote e){
        lSuccess = false;
        handleError(e, pPromotionFile);
        throw e;
      }
      catch (ExRuntimeRoot e) {
        lSuccess = false;
        handleError(e, pPromotionFile);
        throw e;
      }
      catch (Throwable th){
        lSuccess = false;
        ExPromote e = new ExPromote("Unexpected error promoting file " + pPromotionFile.getFilePath(), th);
        handleError(e, pPromotionFile);
        throw e;
      }
      finally {        
        //Log the total time on the database row
        try {
          lController.finaliseFilePromote(pPromotionFile, lSuccess);  
        }
        catch (Throwable th){
          //Only re-throw if there wasn't already an error
          if(lSuccess){
            throw new ExFatalError("Unexpected error finalising promotion log for file " + pPromotionFile.getFilePath(), th);
          }
          else {
            Logger.logInfo("Unexpected error finalising promotion log for file " + pPromotionFile.getFilePath() + ": " + th.getMessage());
          }          
        }
      }      
    }
    else {
      Logger.logInfo("Skipping " + pPromotionFile.getSequencePosition() + ": " + pPromotionFile.getFilePath() + 
                     " - " + (lController.isNoExecController() ? "-noexec promotion" : "already promoted in this label"));
    }
    
  }