/* For automated testing, pass extra arguments on to Lua script */
static void nbSetForwardedArguments(NBodyFlags* nbf, const char** args)
{
    nbf->forwardedArgs = mwGetForwardedArguments(args, &nbf->numForwardedArgs);
}
/* Read project preferences and command line arguments */
static int parseParameters(int argc, const char** argv, SeparationFlags* sfOut)
{
    poptContext context;
    int argRead;
    static int version = FALSE;
    static int copyright = FALSE;
    static unsigned int numParams = 0;
    static int serverParams = 0;
    static const char** rest = NULL;
    static SeparationFlags sf;

    static const struct poptOption options[] =
        {
            {
                "astronomy-parameter-file", 'a',
                POPT_ARG_STRING, &sf.ap_file,
                0, "Astronomy parameter file", NULL
            },

            {
                "star-points-file", 's',
                POPT_ARG_STRING, &sf.star_points_file,
                0, "Star points files", NULL
            },

            {
                "output", 'o',
                POPT_ARG_STRING, &sf.separation_outfile,
                0, "Output file for separation (enables separation)", NULL
            },

            {
                "seed", 'e',
                POPT_ARG_INT, &sf.separationSeed,
                SEED_ARGUMENT, "Seed for random number generator", NULL
            },

            {
                "modfit", 'f',
                POPT_ARG_NONE, &sf.modfit,
                0, "Modified fit from Newby 2011", NULL
            },

            {
				"newbg", 'y',
				POPT_ARG_NONE, &sf.background,
				0, "Uses broken power law as background fit", NULL
			},

            {
                "ignore-checkpoint", 'i',
                POPT_ARG_NONE, &sf.ignoreCheckpoint,
                0, "Ignore the checkpoint file", NULL
            },

            {
                "cleanup-checkpoint", 'c',
                POPT_ARG_NONE, &sf.cleanupCheckpoint,
                0, "Delete checkpoint on successful", NULL
            },

            {
                "print-likelihood-text", 't',
                POPT_ARG_NONE, &sf.LikelihoodToText,
                0, "Create text file with likelihood for use in local MLE", NULL
            },

            {
                "debug-boinc", 'g',
                POPT_ARG_NONE, &sf.debugBOINC,
                0, "Init BOINC with debugging. No effect if not built with BOINC_APPLICATION", NULL
            },

            {
                "process-priority", 'b',
                POPT_ARG_INT, &sf.processPriority,
                0, "Set process priority. Set priority 0 (lowest) to 4 (highest)", NULL
            },

            {
                "device", 'd',
                POPT_ARG_INT, &sf.useDevNumber,
                0, "Device number passed by BOINC to use", NULL
            },

            {
                "non-responsive", 'r',
                POPT_ARG_NONE, &sf.nonResponsive,
                0, "Do not care about display responsiveness (use with caution)", NULL
            },

            {
                "gpu-target-frequency", 'q',
                POPT_ARG_DOUBLE, &sf.targetFrequency,
                0, "Target frequency for GPU tasks" , NULL
            },

            {
                "gpu-wait-factor", 'w',
                POPT_ARG_DOUBLE, &sf.waitFactor,
                0, "Wait correction factor when using high CPU workarounds" , NULL
            },

            {
                "gpu-polling-mode", 'm',
                POPT_ARG_INT, &sf.pollingMode,
                0, "Interval for polling GPU: (-2 (default): Use mode -1 unless working around high CPU driver issue.  -1: use clWaitForEvents(). 0: Use clWaitForEvents() with initial wait, >= 1: sets manual interval polling in ms)" , NULL
            },

            {
                "gpu-disable-checkpointing", 'k',
                POPT_ARG_NONE, &sf.disableGPUCheckpointing,
                0, "Disable checkpointing with GPUs" , NULL
            },

            {
                "platform", 'l',
                POPT_ARG_INT, &sf.usePlatform,
                0, "CL platform index to use", NULL
            },

            {
                "platform-vendor", '\0',
                POPT_ARG_STRING, &sf.preferredPlatformVendor,
                0, "CL Platform vendor name to try to use", NULL
            },

            {
                "verbose", '\0',
                POPT_ARG_NONE, &sf.verbose,
                0, "Print some extra debugging information", NULL
            },

            {
                "force-no-opencl", '\0',
                POPT_ARG_NONE, &sf.forceNoOpenCL,
                0, "Use regular CPU path instead of OpenCL if available", NULL
            },

            {
                "force-no-il-kernel", '\0',
                POPT_ARG_NONE, &sf.forceNoILKernel,
                0, "Do not use AMD IL replacement kernels if available", NULL
            },

            {
                "force-no-intrinsics", '\0',
                POPT_ARG_NONE, &sf.forceNoIntrinsics,
                0, "Use old default path", NULL
            },

            {
                "force-x87", '\0',
                POPT_ARG_NONE, &sf.forceX87,
                0, "Force to use x87 path (ignored if x86_64)", NULL
            },

            {
                "force-sse2", '\0',
                POPT_ARG_NONE, &sf.forceSSE2,
                0, "Force to use SSE2 path", NULL
            },

            {
                "force-sse3", '\0',
                POPT_ARG_NONE, &sf.forceSSE3,
                0, "Force to use SSE3 path", NULL
            },

            {
                "force-sse4.1", '\0',
                POPT_ARG_NONE, &sf.forceSSE41,
                0, "Force to use SSE4.1 path", NULL
            },

            {
                "force-avx", '\0',
                POPT_ARG_NONE, &sf.forceAVX,
                0, "Force to use AVX path", NULL
            },

            {
                "p", 'p',
                POPT_ARG_NONE, &serverParams,
                0, "Unused dummy argument to satisfy primitive arguments the server sends", NULL
            },

            {
                "np", '\0',
                POPT_ARG_INT | POPT_ARGFLAG_ONEDASH, &numParams,
                0, "Unused dummy argument to satisfy primitive arguments the server sends", NULL
            },

            {
                "version", 'v',
                POPT_ARG_NONE, &version,
                0, "Print version information", NULL
            },

            {
                "copyright", '\0',
                POPT_ARG_NONE, &copyright,
                0, "Print copyright information and exit", NULL
            },

            POPT_AUTOHELP
            POPT_TABLEEND
        };

    setInitialFlags(&sf);

    context = poptGetContext(argv[0], argc, argv, options, POPT_CONTEXT_POSIXMEHARDER);
    if (!context)
    {
        mw_printf("Failed to get popt context\n");
        exit(EXIT_FAILURE);
    }

    if (argc < 2)
    {
        poptPrintUsage(context, stderr, 0);
        poptFreeContext(context);
        exit(EXIT_FAILURE);
    }

    argRead = mwReadArguments(context);
    if (argRead < 0)
    {
        poptFreeContext(context);
        freeSeparationFlags(&sf);
        exit(EXIT_FAILURE);
    }

    if (version)
    {
        printVersion(FALSE, sf.verbose);
    }

    if (copyright)
    {
        printCopyright();
    }

    if (version || copyright)
    {
        exit(EXIT_SUCCESS);
    }

    sf.setSeed = !!(argRead & SEED_ARGUMENT); /* Check if these flags were used */

    sf.do_separation = (sf.separation_outfile && strcmp(sf.separation_outfile, ""));
    if (sf.do_separation)
        prob_ok_init(sf.separationSeed, sf.setSeed);

    rest = poptGetArgs(context);
    sf.forwardedArgs = mwGetForwardedArguments(rest, &sf.nForwardedArgs);
    sf.numArgs = mwReadRestArgs(rest, sf.nForwardedArgs); /* Temporary */

    poptFreeContext(context);
    setDefaults(&sf);
    *sfOut = sf;

    return 0;
}