private string CreateShellQuery(ConnectionProperties props)
        {
            var driver = new MongoDynamicDataContextDriver();

            //build the query XDocument
            var doc   = new XDocument();
            var query = new XElement("Query");

            doc.Add(query);
            query.SetAttributeValue("Kind", "Program");
            query.SetElementValue("Reference", Path.Combine(driver.GetDriverFolder(), "LinqPadMongoDriver.dll"));
            foreach (string loc in props.AssemblyLocations)
            {
                var el = new XElement("Reference");
                el.SetValue(loc);
                query.Add(el);
            }
            foreach (string ns in MongoDynamicDataContextDriver.GetNamespacesToAdd(props)
                     .Concat(new[]
            {
                "System",
                "GDSX.Externals.LinqPad.Driver"
            }))
            {
                var el = new XElement("Namespace");
                el.SetValue(ns);
                query.Add(el);
            }

            StringBuilder sb = new StringBuilder();

            using (var writer = XmlWriter.Create(sb, new XmlWriterSettings {
                OmitXmlDeclaration = true
            }))
                doc.Save(writer);

            sb.AppendLine();


            var ass = Assembly.GetExecutingAssembly();

            using (var stream = ass.GetManifestResourceStream("GDSX.Externals.LinqPad.Driver.ShellInitQuery.linq"))
            {
                if (stream == null)
                {
                    throw new Exception("Could not find static code files");
                }
                using (var reader = new StreamReader(stream))
                    sb.Append(reader.ReadToEnd());
            }

            return(sb.ToString());
        }
        private List <string> ValidateLinqQuery(LinqPadQuery query, ConnectionProperties props)
        {
            List <string> errors = new List <string>();

            StringBuilder sb = new StringBuilder();

            foreach (var ns in query.Namespaces)
            {
                sb.Append("using ").Append(ns).AppendLine(";");
            }
            sb.AppendFormat(@"
public class TestQuery
{{
    public TestQuery()
    {{

    }}

    {0}
}}", query.Query);

            var             driver = new MongoDynamicDataContextDriver();
            CompilerResults results;

            using (var codeProvider = new CSharpCodeProvider(new Dictionary <string, string>()
            {
                { "CompilerVersion", "v4.0" }
            }))
            {
                var assemblyNames = new HashSet <string>(query.References, new AssemblyPathEqualityComparer());

                //add additional assemblies which may or may not have been overridden
                assemblyNames.AddRange("System.dll System.Core.dll".Split());
                assemblyNames.Add(Path.Combine(driver.GetDriverFolder(), "MongoDB.Driver.dll"));
                assemblyNames.Add(Path.Combine(driver.GetDriverFolder(), "MongoDB.Bson.dll"));
                assemblyNames.Add(Path.Combine(driver.GetDriverFolder(), "LinqPadMongoDriver.dll"));

                var options = new CompilerParameters(assemblyNames.ToArray());
                options.GenerateInMemory = true;

                results = codeProvider.CompileAssemblyFromSource(options, sb.ToString());
            }
            if (results.Errors.Count > 0)
            {
                errors.AddRange(results.Errors.Cast <CompilerError>().Select(x => x.ToString()));

                return(errors);
            }

            Type       compiledType = results.CompiledAssembly.GetType("TestQuery");
            object     instance     = Activator.CreateInstance(compiledType);
            MethodInfo initMethod   = compiledType.GetMethod("Initialize", new[] { typeof(ConnectionProperties) });

            if (initMethod == null)
            {
                errors.Add(string.Format("The query must contain a method called Initialize that takes one parameter of type {0}", typeof(ConnectionProperties)));
                return(errors);
            }


            return(errors);
        }