/// <summary>
        /// Just an hack. We should have a better story for sending files to the server
        /// </summary>
        /// <param name="args"></param>
        /// <returns></returns>
        static private string[] AdjustPaths(string[] args)
        {
            Contract.Requires(args != null);
            Contract.Requires(Contract.ForAll(args, a => a != null));

            var result = new string[args.Length];

            for (var i = 0; i < args.Length; i++)
            {
                var arg = args[i];
                if (arg.Length > 0)
                {
                    if (arg[0] == '@')
                    {
                        var path = arg.Substring(1, arg.Length - 1);

                        while (i < args.Length && !File.Exists(path))
                        {
                            i++;
                            if (i < args.Length)
                            {
                                path += " " + args[i];
                            }
                        }
                        if (i == args.Length)
                        {
                            return(args);
                        }

                        var    fullPath = Path.GetFullPath(path);
                        string unc;
                        if (FileSystemAbstractions.TryGetUniversalName(fullPath, out unc))
                        {
                            result[i] = "@" + unc;
                            continue;
                        }
                    }
                    else if (arg[0] != '-' && arg[0] != '/')
                    {
                        string unc;
                        if (FileSystemAbstractions.TryGetUniversalName(arg, out unc))
                        {
                            result[i] = unc;
                            continue;
                        }
                    }
                }

                result[i] = args[i];
            }

            return(result);
        }
        public string GetOutputDirectory()
        {
            var currTmp = string.Format(@"{0}\{1}", Path.GetTempPath(), CloudotDir);

            if (!Directory.Exists(currTmp))
            {
                Directory.CreateDirectory(currTmp);
            }
            string result;

            if (FileSystemAbstractions.TryGetUniversalName(currTmp, out result))
            {
                return(result);
            }
            else
            {
                return(null);
            }
        }
        private static List <Tuple <int, string> > ExtractPathsAndUpdateThePackageInfo(ref AnalysisPackageInfo packageInfo)
        {
            Contract.Requires(packageInfo.ExpandedClousotOptions != null);
            Contract.Ensures(packageInfo.AssembliesToAnalyze != null);
            Contract.Ensures(packageInfo.ExpandedClousotOptions == Contract.OldValue(packageInfo.ExpandedClousotOptions));

            var result = new List <Tuple <int, string> >();
            var assembliesToAnalyse    = new List <string>();
            var expandedClousotOptions = packageInfo.ExpandedClousotOptions;

            // Very stuping parsing algorithm, to be improved?

            // Step 0: get the clousot options that contain paths
            var clousotOptionsForPaths = GeneralOptions.GetClousotOptionsWithPaths().ToArray(); // Use ToArray to speed up the look ups

            // Step 1: go all over the clousot options to find those fields, or the dirs we are interested in
            for (var i = 0; i < expandedClousotOptions.Length; i++)
            {
                var option = expandedClousotOptions[i];

                var pathsInTheOptions = GetPaths(option);

                // Step 1a : Is the current option a path?
                if (pathsInTheOptions.Count == 1)
                {
                    // PrintPaths(pathsInTheOptions, "Found an assembly to analyze:");
                    AddIntoResult(result, i, pathsInTheOptions);
                    // Executed only once because of the test above
                    foreach (var match in pathsInTheOptions)
                    {
                        assembliesToAnalyse.Add(match.ToString());
                    }
                }
                // Step 1b : search inside the option
                else
                {
                    option = option.Substring(1); // Remove the first char
                    var tryFind = clousotOptionsForPaths.Where(t => option.StartsWith(t));
                    // Found a match
                    if (tryFind.Any())
                    {
                        foreach (var candidatePath in option.Split(';'))
                        {
                            var matches = GetPaths(candidatePath);
                            // PrintPaths(matches, "Found path(s) for option in position " + i);
                            AddIntoResult(result, i, matches);
                        }
                    }
                }
            }

            // Step 2: create the normalized command line
            var clonedCommandLine = packageInfo.ExpandedClousotOptions.Clone() as string[];

            Contract.Assume(clonedCommandLine != null);
            foreach (var pair in result)
            {
                string unc;
                if (FileSystemAbstractions.TryGetUniversalName(Path.GetFullPath(pair.Item2), out unc))
                {
                    clonedCommandLine[pair.Item1] = clonedCommandLine[pair.Item1].Replace(pair.Item2, unc);
                }
                else
                {
                    clonedCommandLine = null;
                    break;
                }
            }

            packageInfo.AssembliesToAnalyze = assembliesToAnalyse.ToArray();
            packageInfo.ExpandedClousotOptionsNormalized = clonedCommandLine;

            return(result);
        }