def METHOD_NAME(crashLogData):
    if not ("Build: " in crashLogData):
        print "Error: Can't determine build version"
        exit(-1)
    # Find the version of the app that generated the crash
    app = crashLogData.split("Application: ")[1] .split(" ", 1)[0]
    buildVersion = crashLogData.split("Build: ")[1] .split("\n", 1)[0]
    # Remove any white characters
    buildVersion = re.sub("\s", "", buildVersion)
    # Check the symbols FILE is here
    dSYMSFile = os.path.join("symbols", app, buildVersion, app)
    if not os.path.exists(dSYMSFile):
        # No, get it from the Matrix Jenkins
        if app == "matrixConsole":
             if "develop" in buildVersion:
                  jenkinsJob = "MatrixConsoleiOSDevelop"
             else:
                  jenkinsJob = "MatrixConsoleiOS"
        elif app == "Riot":
             if "develop" in buildVersion:
                  jenkinsJob = "RiotiOSDevelop"
             else:
                  jenkinsJob = "RiotiOS"
        jenkinsBuild = re.findall(r"#(.*)", buildVersion)
        if len(jenkinsBuild):
             jenkinsBuild = jenkinsBuild[0]
        if not jenkinsJob or not jenkinsBuild:
            print "Error: Can't extract build version"
            exit(-1)
        XCArchiveTarGzURL = "http://matrix.org/jenkins/view/MatrixView/job/%s/%s/artifact/out/*.tar.gz/*zip*/out.zip" % (jenkinsJob, jenkinsBuild)
        print "Downloading symbols for %s (Build %s) at %s..." % (app, buildVersion, XCArchiveTarGzURL)
        responseCode = download_xcarchive_tar_gz(app, XCArchiveTarGzURL, dSYMSFile)
        if not 200 == responseCode:
            print "Error: Can't download the symbols file (Responce code: %d)" % responseCode
            if 401 == responseCode:
                print "Check your credentials in credentials.py"
            exit(-1)
    # Quick sanitization of HLTM chars
    crashLogData = crashLogData.replace("&lt;", "<").replace("&gt;", ">")
    # Extract memory addresses of our symbors
    memoryLocations = re.findall(r"(0x.*) %s \+ (.*)" % app, crashLogData)
    for (address, offset) in memoryLocations:
        # Convert the relative address in hex (implicitly required by atos) and the offset 
        loadAddress = hex(int(address, 16) - int(offset))
        # Use system tool to retrieve the symbol
        #print("atos -arch arm64 -o %s -l %s %s > symbol.tmp" % (dSYMSFile, loadAddress, address))
        os.system("atos -arch arm64 -o %s -l %s %s > symbol.tmp" % (dSYMSFile, loadAddress, address))
        # Extract the symbol
        file = open("symbol.tmp")
        symbol = file.read().replace("\n", "")
        file.close()
        os.remove("symbol.tmp")
        crashLogData =  crashLogData.replace(offset, "%s -> %s" % (offset, symbol))
    # Check result
    if "Signal detected:" in crashLogData:
        # In the case of a signal, we must find the handleSignal symbol in the result
        if not "handleSignal" in crashLogData:
            crashLogData = crashLogData + "\n* Warning: This symbolication seems invalid!\n"
    else:
        # In the case of a NS Exception, if the crash occured on the main thread, we must find the start and the main function at the call stack root.
        # If it is from another thread (ie its stack starts with start_wqthread), we can't validate the result
        if not "start_wqthread" in crashLogData:
            if not ("main" in crashLogData and "start" in crashLogData):
                crashLogData = crashLogData + "\n* Warning: This symbolication seems invalid!\n"
    return crashLogData