/// <summary>
        /// Console entry point
        /// </summary>
        /// <param name="args">command line arguments</param>
        /// <returns>0 if all extractions are successful.</returns>
        private static int Main(string[] args)
        {
            var options = new Options();

            var parser = new Parser(settings =>
            {
                settings.CaseSensitive = false;
                settings.HelpWriter = Console.Error;
                settings.ParsingCulture = CultureInfo.InvariantCulture;
            });

            var result = parser.ParseArguments(args, options);

            if (!result)
            {
                Fail();
                return -1;
            }

            TfsTeamProjectCollection tfs =
                TfsTeamProjectCollectionFactory.GetTeamProjectCollection(new Uri(options.Collection));
            try
            {
                tfs.EnsureAuthenticated();
            }
            catch (Exception)
            {
                Fail("Connection to TFS failed");
                return -1;
            }

            // Getting Identity Service
            var ims = tfs.GetService<IIdentityManagementService>();

            var someExtractionFail = false;
            foreach (var userName in options.Users)
            {
                Console.WriteLine("===== Extracting Permissions for User {0} ======", userName);
                var fileName = Helpers.GenerateFileName(userName, options.OutputFile);
                var extractionStatus = ExtractPermissionForUserName(ims, userName, options, fileName, tfs);

                if (!extractionStatus)
                {
                    someExtractionFail = true;
                }
            }

            if (someExtractionFail)
            {
                Fail("An error occured during the extraction");
                return -1;
            }

            return 0;
        }
        /// <summary>
        /// Run the extraction algorithm for a specific user
        /// </summary>
        /// <param name="ims">Identity management service</param>
        /// <param name="userName">user name</param>
        /// <param name="options">command line parameters</param>
        /// <param name="fileName">File name</param>
        /// <param name="tfs">team project collection</param>
        /// <returns>true if successful</returns>
        private static bool ExtractPermissionForUserName(IIdentityManagementService ims, string userName, Options options, string fileName, TfsTeamProjectCollection tfs)
        {
            TeamFoundationIdentity userIdentity = ims.ReadIdentity(
                IdentitySearchFactor.AccountName,
                userName,
                MembershipQuery.None,
                ReadIdentityOptions.IncludeReadFromSource);

            if (userIdentity == null)
            {
                Console.WriteLine("User {0} can't connect to the Collection {1}. Please verifiy!", userName, options.Collection);
                Console.ReadLine();
                return false;
            }

            // get workItem store
            var workItemStore = tfs.GetService<WorkItemStore>();

            ////Initiate Report

            // Initiate a new object of Permission Report
            var permissionsReport = new PermissionsReport
            {
                Date = DateTime.Now,
                TfsCollectionUrl = options.Collection,
                UserName = userName,
                TeamProjects = new List<TfsTeamProject>()
            };

            try
            {
                // retrieve list of Team Projects in the given collection
                ProjectCollection workItemsProjects = workItemStore.Projects;
                foreach (Project teamProject in workItemsProjects)
                {
                    if (options.Projects != null)
                    {
                        if (!options.Projects.Contains(teamProject.Name))
                        {
                            Console.WriteLine(" ...skipping Team Project: {0}", teamProject.Name);
                            continue;
                        }
                    }

                    // Create project security token
                    string projectSecurityToken = "$PROJECT:" + teamProject.Uri.AbsoluteUri;

                    // Project Permissions   
                    var server = tfs.GetService<ISecurityService>();
                    var vcs = tfs.GetService<VersionControlServer>();
                    TeamFoundation.Git.Client.GitRepositoryService gitRepostoryService = tfs.GetService<TeamFoundation.Git.Client.GitRepositoryService>();

                    Console.WriteLine("==== Extracting Permissions for {0} Team Project ====", teamProject.Name);
                    var groups = GetUserGroups(tfs, teamProject.Uri.AbsoluteUri, userIdentity);
                    var projectLevelPermissions = ExtractGenericSecurityNamespacePermissions(server, PermissionScope.TeamProject, userIdentity, projectSecurityToken, ims, groups);

                    // Version Control Permissions
                    var versionControlPermissions = ExtractVersionControlPermissions(server, groups, userIdentity, teamProject.Name, ims, vcs);
                    var gitVersionControlPermissions = ExtractGitVersionControlPermissions(server, groups, userIdentity, teamProject.Name, ims, vcs, gitRepostoryService);

                    // Build Permissions
                    var buildPermissions = ExtractBuildPermissions(server, projectSecurityToken, userIdentity);

                    // WorkItems Area Permissions
                    var areasPermissions = ExtractAreasPermissions(server, teamProject, userIdentity, ims, groups);

                    // WorkItems Iteration Permissions
                    var iterationPermissions = ExtractIterationPermissions(server, teamProject, userIdentity, ims, groups);

                    // Workspace Permissions
                    // var workspacePermission = ExtractGenericSecurityNamespacePermissions(server, PermissionScope.Workspaces, userIdentity, projectSecurityToken, ims, groups);

                    // Set TFS report Data
                    // Create Team Project node in XML file
                    var tfsTeamProject = new TfsTeamProject
                    {
                        Name = teamProject.Name,
                        AreaPermissions = areasPermissions,
                        BuildPermissions = buildPermissions,
                        IterationPermissions = iterationPermissions,
                        ProjectLevelPermissions =
                            new ProjectLevelPermissions
                            {
                                ProjectLevelPermissionsList
                                    =
                                    projectLevelPermissions
                            },
                        GitVersionControlPermissions = new VersionControlPermissions
                        {
                            VersionControlPermissionsList = gitVersionControlPermissions
                        },
                        VersionControlPermissions = new VersionControlPermissions
                        {
                            VersionControlPermissionsList = versionControlPermissions
                        }
                    };

                    tfsTeamProject.VersionControlPermissions.VersionControlPermissionsList.AddRange(versionControlPermissions);
                    permissionsReport.TeamProjects.Add(tfsTeamProject);
                }

                // Generate output file
                FileInfo fi = new FileInfo(fileName);
                if (!Directory.Exists(fi.DirectoryName))
                {
                    Console.Write("Creating Output Directory {0}", fi.DirectoryName);
                    Directory.CreateDirectory(fi.DirectoryName);
                }

                var fs = new FileStream(fileName, FileMode.Create);
                var streamWriter = new StreamWriter(fs, Encoding.UTF8);

                using (streamWriter)
                {
                    var xmlSerializer = new XmlSerializer(typeof(PermissionsReport));
                    xmlSerializer.Serialize(streamWriter, permissionsReport);
                    streamWriter.Flush();
                }

                if (options.Html)
                {
                    var tranformationFileName = Path.Combine(Path.GetDirectoryName(fileName), "ALMRanger.xsl");
                    File.WriteAllText(tranformationFileName, Resources.ALMRangers_SampleXslt);
                    var htmlOuput = Path.ChangeExtension(fileName, ".html");

                    var logoFile = Path.Combine(Path.GetDirectoryName(fileName), "ALMRangers_Logo.png");
                    Resources.ALMRangers_Logo.Save(logoFile);
                    XmlTransformationManager.TransformXmlUsingXsl(fileName, tranformationFileName, htmlOuput);
                }

                return true;
            }
            catch (TeamFoundationServiceException ex)
            {
                Console.WriteLine(ex.Message);
                return false;
            }
        }