public void Run(RegressionEnvironment env)
            {
                // Single module
                Module moduleB = GetModule("B", "C");
                try {
                    ModuleOrderUtil.GetModuleOrder(Arrays.AsList(new Module[] {moduleB}), EmptySet<string>.Instance, new ModuleOrderOptions());
                    Assert.Fail();
                }
                catch (ModuleOrderException ex) {
                    Assert.AreEqual("Module-dependency not found as declared by module 'B' for uses-declaration 'C'", ex.Message);
                }

                // multiple module
                Module[] modules = new Module[] {GetModule("B", "C"), GetModule("C", "D"), GetModule("D", "x")};
                try {
                    ModuleOrderUtil.GetModuleOrder(Arrays.AsList(modules), EmptySet<string>.Instance, new ModuleOrderOptions());
                    Assert.Fail();
                }
                catch (ModuleOrderException ex) {
                    Assert.AreEqual("Module-dependency not found as declared by module 'D' for uses-declaration 'x'", ex.Message);
                }

                // turn off uses-checks
                ModuleOrderOptions options = new ModuleOrderOptions();
                options.IsCheckUses = false;
                try {
                    ModuleOrderUtil.GetModuleOrder(Arrays.AsList(modules), EmptySet<string>.Instance, options);
                }
                catch (ModuleOrderException e) {
                    throw new EPRuntimeException(e);
                }
            }
            public void Run(RegressionEnvironment env)
            {
                // Circular 3
                Module moduleB = GetModule("B", "C");
                Module moduleC = GetModule("C", "D");
                Module moduleD = GetModule("D", "B");

                try {
                    ModuleOrderUtil.GetModuleOrder(
                        Arrays.AsList(new Module[] {moduleC, moduleD, moduleB}),
                        EmptySet<string>.Instance,
                        new ModuleOrderOptions());
                    Assert.Fail();
                }
                catch (ModuleOrderException ex) {
                    Assert.AreEqual(
                        "Circular dependency detected in module uses-relationships: module 'C' uses (depends on) module 'D' uses (depends on) module 'B'",
                        ex.Message);
                }

                // Circular 1 - this is allowed
                moduleB = GetModule("B", "B");
                ModuleOrder order = null;
                try {
                    order = ModuleOrderUtil.GetModuleOrder(
                        Arrays.AsList(new Module[] {moduleC, moduleD, moduleB}),
                        EmptySet<string>.Instance,
                        new ModuleOrderOptions());
                }
                catch (ModuleOrderException e) {
                    throw new EPRuntimeException(e);
                }

                AssertOrder(new Module[] {moduleB, moduleD, moduleC}, order);

                // Circular 2
                moduleB = GetModule("B", "C");
                moduleC = GetModule("C", "B");
                try {
                    ModuleOrderUtil.GetModuleOrder(Arrays.AsList(new Module[] {moduleC, moduleB}), EmptySet<string>.Instance, new ModuleOrderOptions());
                    Assert.Fail();
                }
                catch (ModuleOrderException ex) {
                    Assert.AreEqual("Circular dependency detected in module uses-relationships: module 'C' uses (depends on) module 'B'", ex.Message);
                }

                // turn off circular check
                ModuleOrderOptions options = new ModuleOrderOptions();
                options.IsCheckCircularDependency = false;
                try {
                    order = ModuleOrderUtil.GetModuleOrder(Arrays.AsList(new Module[] {moduleC, moduleB}), EmptySet<string>.Instance, options);
                }
                catch (ModuleOrderException e) {
                    throw new EPRuntimeException(e);
                }

                AssertOrder(new Module[] {moduleB, moduleC}, order);
            }
            public void Run(RegressionEnvironment env)
            {
                try {
                    Module moduleA = null;
                    Module moduleB = null;
                    Module moduleC = null;
                    Module moduleD = null;
                    Module moduleE = null;
                    ModuleOrder order = null;

                    // Tree of 4 deep
                    moduleA = GetModule("A");
                    moduleB = GetModule("B", "A");
                    moduleC = GetModule("C", "A", "B", "D");
                    moduleD = GetModule("D", "A", "B");
                    order = ModuleOrderUtil.GetModuleOrder(
                        Arrays.AsList(new Module[] {moduleC, moduleD, moduleB, moduleA}),
                        EmptySet<string>.Instance,
                        new ModuleOrderOptions());
                    AssertOrder(new Module[] {moduleA, moduleB, moduleD, moduleC}, order);

                    // Zero items
                    order = ModuleOrderUtil.GetModuleOrder(Arrays.AsList(new Module[] { }), EmptySet<string>.Instance, new ModuleOrderOptions());
                    AssertOrder(new Module[] { }, order);

                    // 1 item
                    moduleA = GetModule("A");
                    order = ModuleOrderUtil.GetModuleOrder(Arrays.AsList(new Module[] {moduleA}), EmptySet<string>.Instance, new ModuleOrderOptions());
                    AssertOrder(new Module[] {moduleA}, order);

                    // 2 item
                    moduleA = GetModule("A", "B");
                    moduleB = GetModule("B");
                    order = ModuleOrderUtil.GetModuleOrder(Arrays.AsList(new Module[] {moduleB, moduleA}), EmptySet<string>.Instance, new ModuleOrderOptions());
                    AssertOrder(new Module[] {moduleB, moduleA}, order);

                    // 3 item
                    moduleB = GetModule("B");
                    moduleC = GetModule("C", "B");
                    moduleD = GetModule("D");
                    order = ModuleOrderUtil.GetModuleOrder(
                        Arrays.AsList(new Module[] {moduleB, moduleC, moduleD}),
                        EmptySet<string>.Instance,
                        new ModuleOrderOptions());
                    AssertOrder(new Module[] {moduleB, moduleC, moduleD}, order);
                    order = ModuleOrderUtil.GetModuleOrder(
                        Arrays.AsList(new Module[] {moduleD, moduleC, moduleB}),
                        EmptySet<string>.Instance,
                        new ModuleOrderOptions());
                    AssertOrder(new Module[] {moduleB, moduleD, moduleC}, order);

                    // 2 trees of 2 deep
                    moduleA = GetModule("A", "B");
                    moduleB = GetModule("B");
                    moduleC = GetModule("C", "D");
                    moduleD = GetModule("D");
                    order = ModuleOrderUtil.GetModuleOrder(
                        Arrays.AsList(new Module[] {moduleC, moduleB, moduleA, moduleD}),
                        EmptySet<string>.Instance,
                        new ModuleOrderOptions());
                    AssertOrder(new Module[] {moduleB, moduleD, moduleC, moduleA}, order);

                    // Tree of 5 deep
                    moduleA = GetModule("A", "C");
                    moduleB = GetModule("B");
                    moduleC = GetModule("C", "B");
                    moduleD = GetModule("D", "C", "E");
                    moduleE = GetModule("E");
                    order = ModuleOrderUtil.GetModuleOrder(
                        Arrays.AsList(new Module[] {moduleA, moduleB, moduleC, moduleD, moduleE}),
                        EmptySet<string>.Instance,
                        new ModuleOrderOptions());
                    AssertOrder(new Module[] {moduleB, moduleC, moduleE, moduleA, moduleD}, order);
                    order = ModuleOrderUtil.GetModuleOrder(
                        Arrays.AsList(new Module[] {moduleB, moduleE, moduleC, moduleA, moduleD}),
                        EmptySet<string>.Instance,
                        new ModuleOrderOptions());
                    AssertOrder(new Module[] {moduleB, moduleE, moduleC, moduleA, moduleD}, order);
                    order = ModuleOrderUtil.GetModuleOrder(
                        Arrays.AsList(new Module[] {moduleA, moduleD, moduleE, moduleC, moduleB}),
                        EmptySet<string>.Instance,
                        new ModuleOrderOptions());
                    AssertOrder(new Module[] {moduleB, moduleE, moduleC, moduleA, moduleD}, order);

                    // Tree with null names
                    moduleA = GetModule(null, "C", "A", "B", "D");
                    moduleB = GetModule(null, "C");
                    moduleC = GetModule("A");
                    moduleD = GetModule("B", "A", "C");
                    moduleE = GetModule("C");
                    ModuleOrderOptions options = new ModuleOrderOptions();
                    options.IsCheckUses = false;
                    order = ModuleOrderUtil.GetModuleOrder(
                        Arrays.AsList(new Module[] {moduleA, moduleB, moduleC, moduleD, moduleE}),
                        EmptySet<string>.Instance,
                        options);
                    AssertOrder(new Module[] {moduleC, moduleE, moduleD, moduleA, moduleB}, order);

                    // Tree with duplicate names
                    moduleA = GetModule("A", "C");
                    moduleB = GetModule("B", "C");
                    moduleC = GetModule("A", "B");
                    moduleD = GetModule("D", "A");
                    moduleE = GetModule("C");
                    order = ModuleOrderUtil.GetModuleOrder(
                        Arrays.AsList(new Module[] {moduleA, moduleB, moduleC, moduleD, moduleE}),
                        EmptySet<string>.Instance,
                        options);
                    AssertOrder(new Module[] {moduleE, moduleB, moduleA, moduleC, moduleD}, order);
                }
                catch (Exception ex) {
                    throw new EPRuntimeException(ex);
                }
            }