protected void Prepare(string source, bool minimizeNames = true, bool expectErrors = false) {
			IProjectContent project = new CSharpProjectContent();
			var parser = new CSharpParser();

			using (var rdr = new StringReader(source)) {
				var pf = new CSharpUnresolvedFile { FileName = "File.cs" };
				var syntaxTree = parser.Parse(rdr, pf.FileName);
				syntaxTree.AcceptVisitor(new TypeSystemConvertVisitor(pf));
				project = project.AddOrUpdateFiles(pf);
			}
			project = project.AddAssemblyReferences(new[] { Files.Mscorlib });

			_errorReporter = new MockErrorReporter(!expectErrors);

			var compilation = project.CreateCompilation();
			var s = new AttributeStore(compilation, _errorReporter);
			RunAutomaticMetadataAttributeAppliers(s, compilation);
			s.RunAttributeCode();

			Metadata = new MetadataImporter(_errorReporter, compilation, s, new CompilerOptions { MinimizeScript = minimizeNames });

			Metadata.Prepare(compilation.GetAllTypeDefinitions());

			AllErrors = _errorReporter.AllMessages.ToList().AsReadOnly();
			AllErrorTexts = _errorReporter.AllMessages.Select(m => m.FormattedMessage).ToList().AsReadOnly();
			if (expectErrors) {
				Assert.That(AllErrorTexts, Is.Not.Empty, "Compile should have generated errors");
			}
			else {
				Assert.That(AllErrorTexts, Is.Empty, "Compile should not generate errors");
			}

			AllTypes = compilation.MainAssembly.TopLevelTypeDefinitions.SelectMany(SelfAndNested).ToDictionary(t => t.ReflectionName);
		}
		public static Tuple<string, MockErrorReporter> Compile(string source, bool expectErrors = false) {
			var sourceFile = new MockSourceFile("file.cs", source);
			var er = new MockErrorReporter(!expectErrors);
			var n = new Namer();
			var references = new[] { Files.Mscorlib };
			var compilation = PreparedCompilation.CreateCompilation("x", new[] { sourceFile }, references, null);;
			var s = new AttributeStore(compilation.Compilation, er);
			var md = new MetadataImporter(er, compilation.Compilation, s, new CompilerOptions());
			var rtl = new RuntimeLibrary(md, er, compilation.Compilation, n, s);
			var l = new MockLinker();
			md.Prepare(compilation.Compilation.GetAllTypeDefinitions());
			var compiler = new Compiler(md, n, rtl, er);

			var compiledTypes = compiler.Compile(compilation).ToList();

			if (expectErrors) {
				Assert.That(er.AllMessages, Is.Not.Empty, "Compile should have generated errors");
				return Tuple.Create((string)null, er);
			}

			Assert.That(er.AllMessages, Is.Empty, "Compile should not generate errors");

			var js = new OOPEmulatorInvoker(new OOPEmulator(compilation.Compilation, md, rtl, n, l, s, er), md, er).Process(compiledTypes, null);
			js = new Linker(md, n, s, compilation.Compilation).Process(js);

			string script = OutputFormatter.Format(js, allowIntermediates: false);

			return Tuple.Create(script, er);
		}
		protected string Process(string source, string[] typeNames = null, string entryPoint = null, IEnumerable<IAssemblyResource> resources = null, IErrorReporter errorReporter = null) {
			bool assertNoErrors = errorReporter == null;
			errorReporter = errorReporter ?? new MockErrorReporter(true);
			var sourceFile = new MockSourceFile("file.cs", source);
			var n = new Namer();
			var references = new[] { Files.Mscorlib };
			var compilation = PreparedCompilation.CreateCompilation("x", new[] { sourceFile }, references, null, resources);
			var md = new MetadataImporter(errorReporter, compilation.Compilation, new CompilerOptions());
			var rtl = new RuntimeLibrary(md, errorReporter, compilation.Compilation, n);
			var l = new MockLinker();
			md.Prepare(compilation.Compilation.GetAllTypeDefinitions());
			var compiler = new Compiler(md, n, rtl, errorReporter);
			var compiledTypes = compiler.Compile(compilation).ToList();
			var obj = new OOPEmulator(compilation.Compilation, md, rtl, n, l, errorReporter);
			IMethod ep;
			if (entryPoint != null) {
				var type = compiledTypes.Single(c => c.CSharpTypeDefinition.FullName == entryPoint.Substring(0, entryPoint.IndexOf('.')));
				ep = type.CSharpTypeDefinition.Methods.Single(m => m.FullName == entryPoint);
			}
			else {
				ep = null;
			}
			var rewritten = obj.Process(compiledTypes.Where(t => typeNames == null || typeNames.Contains(t.CSharpTypeDefinition.FullName)), ep);

			if (assertNoErrors)
				Assert.That(((MockErrorReporter)errorReporter).AllMessages, Is.Empty, "Should not have errors");

			return string.Join("", rewritten.Select(s => OutputFormatter.Format(s, allowIntermediates: true)));
		}
		protected OOPEmulator CreateEmulator(ICompilation compilation, IErrorReporter errorReporter = null) {
			var n = new Namer();
			errorReporter = errorReporter ?? new MockErrorReporter();
			var md = new MetadataImporter(errorReporter, compilation, new CompilerOptions());
			md.Prepare(compilation.GetAllTypeDefinitions());
			var rtl = new RuntimeLibrary(md, errorReporter, compilation, n);
			return new OOPEmulator(compilation, md, rtl, n, new MockLinker(), errorReporter);
		}
		public void ConstructorsAreReportedAsJsonConstructors() {
			var compilation = new SimpleCompilation(new CSharpProjectContent());
			var er = new MockErrorReporter(true);
			var md = new MetadataImporter(er, compilation, new CompilerOptions());
			Assert.That(er.AllMessages, Is.Empty, "Prepare should not generate errors");

			var t = CreateType(compilation);

			var c = md.GetConstructorSemantics(DefaultResolvedMethod.GetDummyConstructor(compilation, t));
			Assert.That(c.Type, Is.EqualTo(ConstructorScriptSemantics.ImplType.Json));
		}
		protected Tuple<ICompilation, List<JsType>> Compile(string source, IEnumerable<IAssemblyResource> resources = null) {
			var errorReporter = new MockErrorReporter(true);
			var sourceFile = new MockSourceFile("file.cs", source);
			var n = new Namer();
			var references = new[] { Files.Mscorlib };
			var compilation = PreparedCompilation.CreateCompilation("x", new[] { sourceFile }, references, null, resources);
			var md = new MetadataImporter(errorReporter, compilation.Compilation, new CompilerOptions());
			var rtl = new RuntimeLibrary(md, errorReporter, compilation.Compilation, n);
			md.Prepare(compilation.Compilation.GetAllTypeDefinitions());
			var compiler = new Compiler(md, n, rtl, errorReporter);
			var compiledTypes = compiler.Compile(compilation).ToList();

			return Tuple.Create(compilation.Compilation, compiledTypes);

		}
		public void AnonymousTypePropertyNamesAreNotMinimized() {
			var compilation = new SimpleCompilation(new CSharpProjectContent());
			var er = new MockErrorReporter(true);
			var md = new MetadataImporter(er, compilation, new CompilerOptions());
			Assert.That(er.AllMessages, Is.Empty, "Prepare should not generate errors");

			var t = CreateType(compilation);

			var p1 = md.GetPropertySemantics(t.GetProperties().Single(p => p.Name == "prop1"));
			Assert.That(p1.Type, Is.EqualTo(PropertyScriptSemantics.ImplType.Field));
			Assert.That(p1.FieldName, Is.EqualTo("prop1"));

			var p2 = md.GetPropertySemantics(t.GetProperties().Single(p => p.Name == "Prop2"));
			Assert.That(p2.Type, Is.EqualTo(PropertyScriptSemantics.ImplType.Field));
			Assert.That(p2.FieldName, Is.EqualTo("Prop2"));
		}
		public void PropertiesAreImplementedAsFieldsWithTheSameName() {
			var compilation = new SimpleCompilation(new CSharpProjectContent());
			var er = new MockErrorReporter(true);
			var s = new AttributeStore(compilation, er);
			var md = new MetadataImporter(er, compilation, s, new CompilerOptions());
			Assert.That(er.AllMessages, Is.Empty, "Prepare should not generate errors");

			var t = CreateType(compilation);

			var p1 = md.GetPropertySemantics(t.GetProperties().Single(p => p.Name == "prop1"));
			Assert.That(p1.Type, Is.EqualTo(PropertyScriptSemantics.ImplType.Field));
			Assert.That(p1.FieldName, Is.EqualTo("prop1"));

			var p2 = md.GetPropertySemantics(t.GetProperties().Single(p => p.Name == "Prop2"));
			Assert.That(p2.Type, Is.EqualTo(PropertyScriptSemantics.ImplType.Field));
			Assert.That(p2.FieldName, Is.EqualTo("Prop2"));
		}
		protected Tuple<ICompilation, IOOPEmulator, List<JsType>> Compile(string source, IEnumerable<IAssemblyResource> resources = null, IErrorReporter errorReporter = null) {
			errorReporter = errorReporter ?? new MockErrorReporter(true);
			var sourceFile = new MockSourceFile("file.cs", source);
			var n = new Namer();
			var references = new[] { Files.Mscorlib };
			var compilation = PreparedCompilation.CreateCompilation("x", new[] { sourceFile }, references, null, resources);
			var s = new AttributeStore(compilation.Compilation, errorReporter);
			RunAutomaticMetadataAttributeAppliers(s, compilation.Compilation);
			s.RunAttributeCode();
			var md = new MetadataImporter(errorReporter, compilation.Compilation, s, new CompilerOptions());
			var rtl = new RuntimeLibrary(md, errorReporter, compilation.Compilation, n, s);
			md.Prepare(compilation.Compilation.GetAllTypeDefinitions());
			var compiler = new Compiler(md, n, rtl, errorReporter);
			var compiledTypes = compiler.Compile(compilation).ToList();

			return Tuple.Create(compilation.Compilation, (IOOPEmulator)new OOPEmulator(compilation.Compilation, md, rtl, n, new MockLinker(), s, errorReporter), compiledTypes);

		}
		public void TransparentIdentiferIsValidJavascriptIdentifierStartingWithDollar() {
			var compilation = new SimpleCompilation(new CSharpProjectContent());
			var er = new MockErrorReporter(true);
			var s = new AttributeStore(compilation, er);
			var md = new MetadataImporter(er, compilation, s, new CompilerOptions());
			Assert.That(er.AllMessages, Is.Empty, "Prepare should not generate errors");

			var t = CreateType(compilation, new[] { "<>Identifier" });

			var c = md.GetPropertySemantics(t.GetProperties().Single());
			Assert.That(c.Type, Is.EqualTo(PropertyScriptSemantics.ImplType.Field));
			Assert.That(c.FieldName, Is.EqualTo("$Identifier"));
		}
        private Tuple<JsClass, MockErrorReporter> Compile(string source, bool expectErrors = false)
        {
            var sourceFile = new MockSourceFile("file.cs", source);
            var er = new MockErrorReporter(!expectErrors);
            var n = new Namer();
            var references = new[] { Mscorlib, QUnit };
            var compilation = PreparedCompilation.CreateCompilation("Test", new[] { sourceFile }, references, null);
            var s = new AttributeStore(compilation.Compilation, er);
            s.RunAttributeCode();
            var md = new MetadataImporter(er, compilation.Compilation, s, new CompilerOptions());
            var rtl = new RuntimeLibrary(md, er, compilation.Compilation, n, s);
            md.Prepare(compilation.Compilation.GetAllTypeDefinitions());
            var compiler = new Compiler(md, n, rtl, er);

            var result = compiler.Compile(compilation).ToList();
            Assert.That(result, Has.Count.EqualTo(1), "Should compile exactly one type");
            Assert.That(er.AllMessages, Is.Empty, "Compile should not generate errors");

            result = new TestRewriter(er, rtl, s).Rewrite(result).ToList();
            Assert.That(result, Has.Count.EqualTo(1), "Should have one type after rewrite");
            Assert.That(result[0], Is.InstanceOf<JsClass>(), "Compiled type should be a class after rewrite");

            if (expectErrors) {
                Assert.That(er.AllMessages, Is.Not.Empty);
            }
            else {
                Assert.That(er.AllMessages, Is.Empty);
            }

            return Tuple.Create((JsClass)result[0], er);
        }