public override void Execute()
        {
            int nConstellations;
            int factorA, factorB, a, b, factor;
            bool gotMatch;
            List<Region> neutralRegions = new List<Region>();
            List<Region> spawnRegions = new List<Region>();

            System.Diagnostics.Trace.WriteLine(this.Name + " - Execute - begin");

            //BUILD REGIONS
            foreach (Color c in Galaxy.Instance.Configuration.shape().regions.Keys) Galaxy.Instance.Regions.Add(new Region(c));

            neutralRegions.AddRange(Galaxy.Instance.Regions.FindAll((Region r) => { return !r.isSpawn(); }));
            spawnRegions.AddRange(Galaxy.Instance.Regions.FindAll((Region r) => { return r.isSpawn(); }));

            System.Diagnostics.Trace.WriteLine(Galaxy.Instance.Configuration.shape().regions.Keys.Count.ToString() + " theoretical regions");
            System.Diagnostics.Trace.WriteLine(Galaxy.Instance.Regions.Count.ToString() + " actual regions");
            System.Diagnostics.Trace.WriteLine(spawnRegions.Count.ToString() + " spawn regions");
            foreach (Region r in spawnRegions) System.Diagnostics.Trace.WriteLine("-->" + r.Index.ToString() + " containing " + r.Count.ToString()+ " stars");
            System.Diagnostics.Trace.WriteLine(neutralRegions.Count.ToString() + " neutral regions");
            foreach (Region r in neutralRegions) System.Diagnostics.Trace.WriteLine("-->" + r.Index.ToString() + " containing " + r.Count.ToString() + " stars");

            //DETERMINE ACTUAL CONSTELLATIONS NUMBER
            nConstellations = Galaxy.Instance.Configuration.constellations();
            System.Diagnostics.Trace.WriteLine("Configuration requested constellations : " + Galaxy.Instance.Configuration.constellations().ToString());

            while ((nConstellations * Settings.Instance.generationConstraints.minStarsPerConstellation) > Galaxy.Instance.Stars.Count)
                nConstellations--;
            if (nConstellations <= 0)
                nConstellations = 1;

            if (nConstellations < Galaxy.Instance.Configuration.constellations())
            {
                System.Diagnostics.Trace.WriteLine("Min stars per constellation : " + Settings.Instance.generationConstraints.minStarsPerConstellation.ToString());
                System.Diagnostics.Trace.WriteLine("Will use only " + nConstellations.ToString() + " constellations");
                this.Defects.Add("Number of constellations was limited by stars number");
            }

            //DISTRIBUTE CONSTELLATIONS ACROSS REGIONS
            if (nConstellations == 1)
            {
                System.Diagnostics.Trace.WriteLine("Single Constellation");
                Constellation c = new Constellation();
                c.AddRange(Galaxy.Instance.Stars);
            }
            else if (nConstellations == Galaxy.Instance.Regions.Count)
            {
                System.Diagnostics.Trace.WriteLine("One Constellation Per Region");
                foreach (Region r in Galaxy.Instance.Regions)
                {
                    Constellation c = new Constellation();
                    c.AddRange(r);
                }
            }
            else
            {
                System.Diagnostics.Trace.WriteLine("Other Case");
                factorA = 0;
                factorB = 0;
                gotMatch = false;

                for (a = 1; a < 20; a++)
                {
                    for (b = 0; b < 20; b++)
                    {
                        if (a * spawnRegions.Count + b * neutralRegions.Count == nConstellations)
                        {
                            gotMatch = true;
                            factorA = a;
                            factorB = b;
                        }
                    }
                }

                if (gotMatch)
                {
                    System.Diagnostics.Trace.WriteLine("Could find integers A=" + factorA.ToString() + " and B=" + factorB.ToString());
                    System.Diagnostics.Trace.WriteLine("Allowing A Constellations in each Spawn Region");
                    System.Diagnostics.Trace.WriteLine("And B Constellation in each Neutral Region");
                    if (factorA > 0)
                    {
                        foreach (Region r in spawnRegions)
                        {
                            this.MakeConstellations(factorA, r);
                        }
                    }
                    if (factorB > 0)
                    {
                        foreach (Region r in neutralRegions)
                        {
                            this.MakeConstellations(factorB, r);
                        }
                    }
                }
                else
                {
                    System.Diagnostics.Trace.WriteLine("No exact match");

                    if (nConstellations >= spawnRegions.Count)
                    {
                        System.Diagnostics.Trace.WriteLine("More Constellations than Spawn Regions");
                        foreach (Region r in spawnRegions)
                        {
                            this.MakeConstellations(1, r);
                        }
                        if (nConstellations - spawnRegions.Count > 0)
                        {
                            List<StarSystem> pool = new List<StarSystem>();

                            foreach(Region r in neutralRegions)
                                pool.AddRange(r);

                            this.MakeConstellations(nConstellations - spawnRegions.Count, pool);
                        }
                    }
                    else
                    {
                        System.Diagnostics.Trace.WriteLine("Less Constellations than Spawn Regions");
                        factor = 1;
                        while (factor * nConstellations < spawnRegions.Count) factor++;

                        Region start;
                        Region merge;
                        List<Region> adjacentSpawnRegions = new List<Region>();
                        List<Region> mergedRegions = new List<Region>();
                        List<Region> nextStartCandidates = new List<Region>();
                        List<StarSystem> pool = new List<StarSystem>();
                        int i;

                        //loop
                        //starting with one random spawn region
                        //merge (factor adjacent spawn regions) into result
                        //make one constellation in result
                        //until remaining spawn regions number less than factor

                        System.Diagnostics.Trace.WriteLine("Using topology to try grouping " + factor.ToString() + " Spawn Regions in each Constellation");

                        start = spawnRegions.ElementAt(GalaxyGeneratorPlugin.random.Next(spawnRegions.Count));
                        while ((spawnRegions.Count >= factor) && (start != null) && (Galaxy.Instance.Constellations.Count < nConstellations))
                        {
                            i = 0;
                            spawnRegions.Remove(start);
                            mergedRegions.Clear();
                            mergedRegions.Add(start);
                            adjacentSpawnRegions.AddRange(start.adjacentRegions().FindAll((r) => { return r.isSpawn(); }));
                            adjacentSpawnRegions.RemoveAll((r) => { return !spawnRegions.Contains(r); });
                            for (; (i < factor-1) && (adjacentSpawnRegions.Count > 0); i++)
                            {
                                adjacentSpawnRegions.Clear();
                                foreach (Region r in mergedRegions) adjacentSpawnRegions.AddRange(r.adjacentRegions());
                                adjacentSpawnRegions.RemoveAll((r) => { return mergedRegions.Contains(r); });
                                adjacentSpawnRegions.RemoveAll((r) => { return !r.isSpawn(); });
                                adjacentSpawnRegions.RemoveAll((r) => { return !spawnRegions.Contains(r); });
                                if (adjacentSpawnRegions.Count > 0)
                                {
                                    merge = adjacentSpawnRegions.ElementAt(GalaxyGeneratorPlugin.random.Next(adjacentSpawnRegions.Count));
                                    mergedRegions.Add(merge);
                                    spawnRegions.Remove(merge);
                                }
                            }

                            System.Diagnostics.Trace.WriteLine("Merging regions :");
                            foreach (Region r in mergedRegions)
                                System.Diagnostics.Trace.WriteLine("--->"+r.Index.ToString());

                            pool.Clear();
                            foreach (Region r in mergedRegions) pool.AddRange(r);
                            this.MakeConstellations(1, pool);

                            nextStartCandidates.Clear();
                            foreach(Region r in mergedRegions) nextStartCandidates.AddRange(r.adjacentRegions());
                            nextStartCandidates.RemoveAll((r) => { return mergedRegions.Contains(r); });
                            nextStartCandidates.RemoveAll((r) => { return !r.isSpawn(); });
                            nextStartCandidates.RemoveAll((r) => { return !spawnRegions.Contains(r); });

                            if (nextStartCandidates.Count > 0)
                                start = nextStartCandidates.ElementAt(GalaxyGeneratorPlugin.random.Next(nextStartCandidates.Count));
                            else if (spawnRegions.Count > 0)
                                start = spawnRegions.ElementAt(GalaxyGeneratorPlugin.random.Next(spawnRegions.Count));
                            else
                                start = null;
                        }

                        //merge (remaining spawn regions with neutral regions) into result
                        //make (nConstellations - Galaxy.Instance.Constellations.Count) constellations in result
                        System.Diagnostics.Trace.WriteLine("Merging remaining Spawn Regions with Neutral Regions");
                        System.Diagnostics.Trace.WriteLine("and making remaining Constellations");
                        pool.Clear();
                        foreach (Region r in spawnRegions) pool.AddRange(r);
                        foreach (Region r in neutralRegions) pool.AddRange(r);
                        this.MakeConstellations(nConstellations - Galaxy.Instance.Constellations.Count, pool);
                    }
                }

                if (Galaxy.Instance.Constellations.Count == 0)
                {
                    System.Diagnostics.Trace.WriteLine("Failing to associate regions and constellations");
                    System.Diagnostics.Trace.WriteLine("Creating brutally " + nConstellations.ToString() + " constellations with " + Galaxy.Instance.Stars.Count.ToString());
                    this.MakeConstellations(nConstellations, Galaxy.Instance.Stars);
                    this.Defects.Add("Unable to correlate regions and constellations");
                }

                this.AggregateIsolatedStars();
            }

            this.Result = true;

            System.Diagnostics.Trace.WriteLine(this.Name + " - Execute - end");
        }