docs: def start(project, credentials=None): #pylint: disable=too-many-return-statements
          """Start execution"""
  
          #handle shortcut
          shortcutresponse = entryshortcut(credentials, True) #protected against endless recursion, will return None when no shortcut is found, True when one is found and starting should continue
          if shortcutresponse is not None and shortcutresponse is not True:
              return shortcutresponse
  
          user, oauth_access_token = parsecredentials(credentials)
          response = Project.create(project, user)
          if response is not None:
              return response
          #if user and not Project.access(project, user):
          #    return flask.make_response("Access denied to project " + project +  " for user " + user,401) #401
  
          statuscode, _, _, _  = Project.status(project, user)
          if statuscode != clam.common.status.READY:
              if oauth_access_token:
                  return withheaders(flask.redirect(getrooturl() + '/' + project + '/?oauth_access_token=' + oauth_access_token),headers={'allow_origin': settings.ALLOW_ORIGIN})
              else:
                  return withheaders(flask.redirect(getrooturl() + '/' + project),headers={'allow_origin': settings.ALLOW_ORIGIN})
  
          #Generate arguments based on POSTed parameters
          commandlineparams = []
          postdata = flask.request.values
  
          errors, parameters, commandlineparams = clam.common.data.processparameters(postdata, settings.PARAMETERS)
  
          sufresources, resmsg = sufficientresources()
          if not sufresources:
              printlog("*** NOT ENOUGH SYSTEM RESOURCES AVAILABLE: " + resmsg + " ***")
              return withheaders(flask.make_response("There are not enough system resources available to accommodate your request. " + resmsg + " .Please try again later.",503),headers={'allow_origin': settings.ALLOW_ORIGIN})
          if not errors: #We don't even bother running the profiler if there are errors
              matchedprofiles, program = clam.common.data.profiler(settings.PROFILES, Project.path(project, user), parameters, settings.SYSTEM_ID, settings.SYSTEM_NAME, getrooturl(), printdebug)
              #converted matched profiles to a list of indices
              matchedprofiles_byindex = []
              for i, profile in enumerate(settings.PROFILES):
                  if profile in matchedprofiles:
                      matchedprofiles_byindex.append(i)
  
          if errors:
              #There are parameter errors, return 403 response with errors marked
              printlog("There are parameter errors, not starting.")
              return Project.response(user, project, parameters,"",False,oauth_access_token, http_code=403)
          elif not matchedprofiles:
              printlog("No profiles matching, not starting.")
              return Project.response(user, project, parameters, "No profiles matching input and parameters, unable to start. Are you sure you added all necessary input files and set all necessary parameters?", False, oauth_access_token,http_code=403)
          else:
              #everything good, write clam.xml output file and start
              with io.open(Project.path(project, user) + "clam.xml",'wb') as f:
                  f.write(Project.response(user, project, parameters, "",True, oauth_access_token, ",".join([str(x) for x in matchedprofiles_byindex]), program).data)
  
  
  
              #Start project with specified parameters
              cmd = settings.COMMAND
              cmd = cmd.replace('$PARAMETERS', " ".join(commandlineparams)) #commandlineparams is shell-safe
              #if 'usecorpus' in postdata and postdata['usecorpus']:
              #    corpus = postdata['usecorpus'].replace('..','') #security
              #    #use a preinstalled corpus:
              #    if os.path.exists(settings.ROOT + "corpora/" + corpus):
              #        cmd = cmd.replace('$INPUTDIRECTORY', settings.ROOT + "corpora/" + corpus + "/")
              #    else:
              #        raise web.webapi.NotFound("Corpus " + corpus + " not found")
              #else:
              cmd = cmd.replace('$INPUTDIRECTORY', Project.path(project, user) + 'input/')
              cmd = cmd.replace('$OUTPUTDIRECTORY',Project.path(project, user) + 'output/')
              cmd = cmd.replace('$TMPDIRECTORY',Project.path(project, user) + 'tmp/')
              cmd = cmd.replace('$STATUSFILE',Project.path(project, user) + '.status')
              cmd = cmd.replace('$DATAFILE',Project.path(project, user) + 'clam.xml')
              cmd = cmd.replace('$USERNAME',user if user else "anonymous")
              cmd = cmd.replace('$PROJECT',project) #alphanumberic only, shell-safe
              cmd = cmd.replace('$OAUTH_ACCESS_TOKEN',oauth_access_token)
              cmd = clam.common.data.escapeshelloperators(cmd)
              #everything should be shell-safe now
              cmd += " 2> " + Project.path(project, user) + "output/error.log" #add error output
  
              pythonpath = ''
              try:
                  pythonpath = ':'.join(settings.DISPATCHER_PYTHONPATH)
              except AttributeError:
                  pass
              if pythonpath:
                  pythonpath = os.path.dirname(settings.__file__) + ':' + pythonpath
              else:
                  pythonpath = os.path.dirname(settings.__file__)
  
              #if settings.DISPATCHER == 'clamdispatcher' and os.path.exists(settings.CLAMDIR + '/' + settings.DISPATCHER + '.py') and stat.S_IXUSR & os.stat(settings.CLAMDIR + '/' + settings.DISPATCHER+'.py')[stat.ST_MODE]:
              #    #backward compatibility for old configurations without setuptools
              #    cmd = settings.CLAMDIR + '/' + settings.DISPATCHER + '.py'
              #else:
              cmd = settings.DISPATCHER + ' ' + pythonpath + ' ' + settingsmodule + ' ' + Project.path(project, user) + ' ' + cmd
              if settings.REMOTEHOST:
                  if settings.REMOTEUSER:
                      cmd = "ssh -o NumberOfPasswordPrompts=0 " + settings.REMOTEUSER + "@" + settings.REMOTEHOST + " " + cmd
                  else:
                      cmd = "ssh -o NumberOfPasswordPrompts=0 " + settings.REMOTEHOST + " " + cmd
              printlog("Starting dispatcher " +  settings.DISPATCHER + " with " + settings.COMMAND + ": " + repr(cmd) + " ..." )
              #process = subprocess.Popen(cmd,cwd=Project.path(project), shell=True)
              process = subprocess.Popen(cmd,cwd=settings.CLAMDIR, shell=True)
              if process:
                  pid = process.pid
                  printlog("Started dispatcher with pid " + str(pid) )
                  with open(Project.path(project, user) + '.pid','w') as f: #will be handled by dispatcher!
                      f.write(str(pid))
                  if shortcutresponse is True:
                      #redirect to project page to lose parameters in URL
                      if oauth_access_token:
                          return withheaders(flask.redirect(getrooturl() + '/' + project + '/?oauth_access_token=' + oauth_access_token),headers={'allow_origin': settings.ALLOW_ORIGIN})
                      else:
                          return withheaders(flask.redirect(getrooturl() + '/' + project),headers={'allow_origin': settings.ALLOW_ORIGIN})
                  else:
                      #normal response (202)
                      return Project.response(user, project, parameters,"",False,oauth_access_token,",".join([str(x) for x in matchedprofiles_byindex]), program,http_code=202) #returns 202 - Accepted
              else:
                  return withheaders(flask.make_response("Unable to launch process",500),headers={'allow_origin': settings.ALLOW_ORIGIN})