static int Main(string[] args)
        {
            try
            {
                var extra = _options.Parse(args);
                if (extra.Count != 0)
                {
                    Console.Error.WriteLine($"Invalid option: {extra[0]}");
                    PrintUsage();
                    return(1);
                }
            }
            catch (OptionException)
            {
                PrintUsage();
                return(2);
            }

            int errcode;

            if (!CheckBasicOptions(args, out errcode))
            {
                return(errcode);
            }

            GroupLoader.LoaderParams parms = new GroupLoader.LoaderParams
            {
                PrimLimit = Convert.ToInt32(_primLimit),
                Checks    = (GroupLoader.LoaderChecks)Convert.ToInt16(_checks)
            };

            ExpLib.Init();

            GroupDisplayData        data        = null;
            List <GroupDisplayData> multiGroups = null;

            if (_stream)
            {
                string input = Console.In.ReadToEnd();
                data = GroupLoader.Instance.LoadFromXML(input, parms);
            }
            else if (_xmlFile != null)
            {
                string input = File.ReadAllText(_xmlFile);
                data = GroupLoader.Instance.LoadFromXML(input, parms);
            }
            else if (_aggrDir != null)
            {
                multiGroups = new List <GroupDisplayData>();
                var dirList = Directory.EnumerateFiles(_aggrDir, "*.xml");
                foreach (var file in dirList)
                {
                    string input = File.ReadAllText(file);
                    multiGroups.Add(GroupLoader.Instance.LoadFromXML(input, parms));
                }
            }
            else if (_userId != UUID.Zero && _invItemId != UUID.Zero)
            {
                data = GroupLoader.Instance.Load(_userId, _invItemId, parms);
            }
            else
            {
                Console.Error.WriteLine("Either stream, file, aggregation, or userid and invitemid are required parameters");
                PrintUsage();
                return(5);
            }

            IExportFormatter formatter = ExportFormatterFactory.Instance.Get(_formatter);
            ExportResult     res       = multiGroups != null?formatter.Export(multiGroups) : formatter.Export(data);

            Console.Out.WriteLine($"Scene Statistics:\n\n" +
                                  $"Concrete objects: {res.Stats.ConcreteCount}\n" +
                                  $"Instanced objects: {res.Stats.InstanceCount}\n" +
                                  $"Unique submeshes: {res.Stats.SubmeshCount}\n" +
                                  $"Concrete primitives: {res.Stats.PrimCount}\n" +
                                  $"Unique textures: {res.Stats.TextureCount}\n");

            //sort the prim and face stats
            var sortedGroupsByPrimCount    = res.Stats.GroupsByPrimCount.OrderByDescending(o => o.Item2);
            var sortedGroupsBySubmeshCount = res.Stats.GroupsBySubmeshCount.OrderByDescending(o => o.Item2);

            //top 10
            Console.Out.WriteLine("Top 10 groups by prim count");
            foreach (var grp in sortedGroupsByPrimCount.Take(10))
            {
                Console.Out.WriteLine($"{grp.Item2} {grp.Item1}");
            }

            Console.Out.WriteLine();

            Console.Out.WriteLine("Top 10 groups by submesh count");
            foreach (var grp in sortedGroupsBySubmeshCount.Take(10))
            {
                Console.Out.WriteLine($"{grp.Item2} {grp.Item1}");
            }

            Console.Out.WriteLine();

            PackagerParams pp = new PackagerParams {
                Direct = _direct
            };

            IPackager packager = PackagerFactory.Instance.Get(_packager);

            packager.CreatePackage(res, _outputDir, pp);

            ExpLib.ShutDown();

            return(0);
        }
 public void Register(IExportFormatter formatter, string name)
 {
     _formatters.Add(name, formatter);
 }