private Map<String, PatchScript> preParsePatchScripts(PromotionManifestParser pManifestParser){
    
    Logger.logInfo("Validating patches...");
    
    Map<String, PatchScript> lParsedScriptMap = new HashMap<String, PatchScript>();
    //Map of patch labels to highest orders - used to verify script order is correct
    Map<String, Integer> lScriptNumberMap = new HashMap<String, Integer>();
    
    for(PromotionFile lPromotionFile : pManifestParser.getPromotionFileList()){
      if(BuiltInLoader.LOADER_NAME_PATCH.equals(lPromotionFile.getLoaderName())){
        try {
          PatchScript lScript = PatchScript.createFromPromotionFile(this, lPromotionFile);
          Integer lPreviousNumber = lScriptNumberMap.get(lScript.getPatchLabel());
          
          if(lPreviousNumber != null && lScript.getPatchNumber() < lPreviousNumber){
            throw new ExFatalError("Patch order violation - " + lScript.getDisplayName() + " is implicated after patch with number " + lPreviousNumber);
          }
          
          if(lPromotionFile.isForcedDuplicate()){
            throw new ExFatalError("Patch " + lScript.getDisplayName() + " at position " + lPromotionFile.getSequencePosition() + 
                                   " cannot be a forced duplicate; patches may only be run once in a promote.");
          };
          
          lParsedScriptMap.put(lPromotionFile.getFilePath(), lScript);
          lScriptNumberMap.put(lScript.getPatchLabel(), lScript.getPatchNumber());
        }
        catch (ExParser e){
          throw new ExFatalError("Could not parse patch " + lPromotionFile.getFilePath() + ": " + e.getMessage(), e);
        }
        catch (IOException e){
          throw new ExFatalError("Could not parse patch " + lPromotionFile.getFilePath(), e);
        }
      }
    }
    
    return lParsedScriptMap;
    
  }