public async void SyncFxGenerateSyncCodeInProject(object sender, ExecutedRoutedEventArgs e)
        {
            var databaseInfo = ValidateMenuInfo(sender);

            if (databaseInfo == null)
            {
                return;
            }
            if (package == null)
            {
                return;
            }

            var dteH = new EnvDteHelper();

            var project = dteH.GetProject();

            if (project == null)
            {
                EnvDteHelper.ShowError("Please select a project in Solution Explorer, where you want the SyncFx classes to be placed");
                return;
            }
            if (!dteH.ContainsAllowed(project))
            {
                EnvDteHelper.ShowError("The selected project type does not support Sync Framework (please let me know if I am wrong)");
                return;
            }

            var tfm = ThreadHelper.JoinableTaskFactory.Run(() => project.GetAttributeAsync("TargetFrameworkMoniker"));

            if (string.IsNullOrEmpty(tfm))
            {
                EnvDteHelper.ShowError("The selected project type does not support Sync Framework - missing TargetFrameworkMoniker");
                return;
            }
            if (!tfm.Contains(".NETFramework"))
            {
                EnvDteHelper.ShowError("The selected project type does not support .NET Desktop - wrong TargetFrameworkMoniker: " + tfm);
                return;
            }
            if (databaseInfo.DatabaseInfo.DatabaseType != DatabaseType.SQLCE35)
            {
                EnvDteHelper.ShowError("Sorry, only version 3.5 databases are supported for now");
                return;
            }

            try
            {
                var fileNameWithoutExtension = Path.GetFileNameWithoutExtension(databaseInfo.DatabaseInfo.Caption);
                if (fileNameWithoutExtension != null)
                {
                    var model = fileNameWithoutExtension.Replace(" ", string.Empty).Replace("#", string.Empty).Replace(".", string.Empty).Replace("-", string.Empty);
                    var sfd   = new SyncFxDialog {
                        ModelName = model
                    };

                    var res = sfd.ShowModal();
                    if (!res.HasValue || res.Value != true || (sfd.Tables.Count <= 0))
                    {
                        return;
                    }
                    model = sfd.ModelName;
                    var defaultNamespace = ThreadHelper.JoinableTaskFactory.Run(() => project.GetAttributeAsync("DefaultNamespace"));

                    var classes     = new SyncFxHelper().GenerateCodeForScope(string.Empty, databaseInfo.DatabaseInfo.ConnectionString, "SQLCE", model, sfd.Columns.Where(c => sfd.Tables.Contains(c.TableName)).ToList(), defaultNamespace);
                    var projectPath = Path.GetDirectoryName(project.FullPath);

                    foreach (var item in classes)
                    {
                        var fileName = Path.Combine(projectPath, item.Key + ".cs");
                        if (File.Exists(fileName))
                        {
                            File.Delete(fileName);
                        }
                        File.WriteAllText(fileName, item.Value);
                        ThreadHelper.JoinableTaskFactory.Run(() => project.AddExistingFilesAsync(fileName));
                    }
                    //Adding references - http://blogs.msdn.com/b/murat/archive/2008/07/30/envdte-adding-a-refernce-to-a-project.aspx
                    await EnvDteHelper.AddReferenceAsync(project, "System.Data.SqlServerCe, Version=3.5.1.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91");

                    await EnvDteHelper.AddReferenceAsync(project, "Microsoft.Synchronization, Version=2.1.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91");

                    await EnvDteHelper.AddReferenceAsync(project, "Microsoft.Synchronization.Data, Version=3.1.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91");

                    await EnvDteHelper.AddReferenceAsync(project, "Microsoft.Synchronization.Data.SqlServer, Version=3.1.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91");

                    await EnvDteHelper.AddReferenceAsync(project, "Microsoft.Synchronization.Data.SqlServerCe, Version=3.1.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91");

                    EnvDteHelper.ShowMessage("Scope: " + model + " code generated.");
                    DataConnectionHelper.LogUsage("DatabaseSyncCodegen");
                }
            }
            catch (Exception ex)
            {
                DataConnectionHelper.SendError(ex, databaseInfo.DatabaseInfo.DatabaseType, false);
            }
        }
        public async void SyncFxGenerateLocalDatabaseCacheCode(object sender, ExecutedRoutedEventArgs e)
        {
            // http://www.mztools.com/articles/2007/MZ2007011.aspx
            var menuItem = sender as MenuItem;

            if (menuItem == null)
            {
                return;
            }
            var dteH    = new EnvDteHelper();
            var project = dteH.GetProject();

            if (project == null)
            {
                EnvDteHelper.ShowError("Please select a project in Solution Explorer, where you want the SyncFx classes to be placed");
                return;
            }
            if (!dteH.ContainsAllowed(project))
            {
                EnvDteHelper.ShowError("The selected project type does not support Sync Framework (please let me know if I am wrong)");
                return;
            }

            var tfm = ThreadHelper.JoinableTaskFactory.Run(() => project.GetAttributeAsync("TargetFrameworkMoniker"));

            if (string.IsNullOrEmpty(tfm))
            {
                EnvDteHelper.ShowError("The selected project type does not support Sync Framework - missing TargetFrameworkMoniker");
                return;
            }
            if (!tfm.Contains(".NETFramework"))
            {
                EnvDteHelper.ShowError("The selected project type does not support .NET Desktop - wrong TargetFrameworkMoniker: " + tfm);
                return;
            }

            try
            {
                var serverConnectionString = DataConnectionHelper.PromptForConnectionString(_package);
                if (string.IsNullOrEmpty(serverConnectionString))
                {
                    return;
                }
                string clientConnectionString;

                //grab target SQL CE Database
                var dialog = new ConnectionDialog();
                dialog.DbType = DatabaseType.SQLCE35;
                var result = dialog.ShowModal();
                if (result.HasValue && result.Value && !string.IsNullOrWhiteSpace(dialog.ConnectionString))
                {
                    clientConnectionString = dialog.ConnectionString;
                }
                else
                {
                    return;
                }

                var model        = string.Empty;
                var sfd          = new SyncFxDialog();
                var databaseInfo = new DatabaseMenuCommandParameters
                {
                    DatabaseInfo = new DatabaseInfo
                    {
                        ConnectionString = serverConnectionString,
                        DatabaseType     = DatabaseType.SQLServer
                    }
                };
                SyncFxGetObjectsForSync(sfd, databaseInfo);
                sfd.ModelName = model;

                var res = sfd.ShowModal();
                if (res.HasValue && res.Value && (sfd.Tables.Count > 0) && !string.IsNullOrWhiteSpace(sfd.ModelName))
                {
                    model = sfd.ModelName;
                    var defaultNamespace = ThreadHelper.JoinableTaskFactory.Run(() => project.GetAttributeAsync("DefaultNamespace"));

                    var columns     = sfd.Columns.Where(c => sfd.Tables.Contains(c.TableName)).ToList();
                    var classes     = new SyncFxHelper().GenerateCodeForScope(serverConnectionString, clientConnectionString, "SQL", model, columns, defaultNamespace);
                    var projectPath = Path.GetDirectoryName(project.FullPath);

                    foreach (var item in classes)
                    {
                        var fileName = Path.Combine(projectPath, item.Key + ".cs");
                        if (File.Exists(fileName))
                        {
                            File.Delete(fileName);
                        }
                        File.WriteAllText(fileName, item.Value);
                        ThreadHelper.JoinableTaskFactory.Run(() => project.AddExistingFilesAsync(fileName));
                    }
                    //Adding references - http://blogs.msdn.com/b/murat/archive/2008/07/30/envdte-adding-a-refernce-to-a-project.aspx
                    await EnvDteHelper.AddReferenceAsync(project, "System.Data.SqlServerCe, Version=3.5.1.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91");

                    await EnvDteHelper.AddReferenceAsync(project, "Microsoft.Synchronization, Version=2.1.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91");

                    await EnvDteHelper.AddReferenceAsync(project, "Microsoft.Synchronization.Data, Version=3.1.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91");

                    await EnvDteHelper.AddReferenceAsync(project, "Microsoft.Synchronization.Data.SqlServer, Version=3.1.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91");

                    await EnvDteHelper.AddReferenceAsync(project, "Microsoft.Synchronization.Data.SqlServerCe, Version=3.1.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91");

                    EnvDteHelper.ShowMessage("Scope: " + model + " code generated.");
                    DataConnectionHelper.LogUsage("DatabasesSyncAddLocalDBCache");
                }
            }
            catch (Exception ex)
            {
                DataConnectionHelper.SendError(ex, DatabaseType.SQLServer);
            }
        }
        public async void GenerateDataContextInProject(object sender, ExecutedRoutedEventArgs e)
        {
            var databaseInfo = ValidateMenuInfo(sender);

            if (databaseInfo == null)
            {
                return;
            }

            if (package == null)
            {
                return;
            }
            if (EnvDteHelper.IsDebugMode())
            {
                EnvDteHelper.ShowError("Cannot generate code while debugging");
                return;
            }

            var helper = Helpers.RepositoryHelper.CreateEngineHelper(databaseInfo.DatabaseInfo.DatabaseType);

            if (!helper.IsV35DbProviderInstalled())
            {
                EnvDteHelper.ShowError("This feature requires the SQL Server Compact 3.5 SP2 DbProvider to be properly installed");
                return;
            }

            var dteH = new EnvDteHelper();

            var project = dteH.GetProject();

            if (project == null)
            {
                EnvDteHelper.ShowError("Please select a project in Solution Explorer, where you want the DataContext to be placed");
                return;
            }
            if (!dteH.ContainsAllowed(project))
            {
                EnvDteHelper.ShowError("The selected project type does not support LINQ to SQL (please let me know if I am wrong)");
                return;
            }

            var tfm = ThreadHelper.JoinableTaskFactory.Run(() => project.GetAttributeAsync("TargetFrameworkMoniker"));

            if (string.IsNullOrEmpty(tfm))
            {
                EnvDteHelper.ShowError("No TFM");
                return;
            }

            if (!tfm.Contains(".NETFramework"))
            {
                EnvDteHelper.ShowError("The selected project type does not support .NET Desktop - wrong TargetFrameworkMoniker: " + tfm);
                return;
            }

            var sqlMetalPath = ProbeSqlMetalRegPaths();

            if (string.IsNullOrEmpty(sqlMetalPath))
            {
                EnvDteHelper.ShowError("Could not find SQLMetal file location");
                return;
            }

            var sdfFileName = string.Empty;

            try
            {
                using (var repository = Helpers.RepositoryHelper.CreateRepository(databaseInfo.DatabaseInfo))
                {
                    var tables        = repository.GetAllTableNames();
                    var pks           = repository.GetAllPrimaryKeys();
                    var checkedTables = string.Empty;
                    foreach (var tableName in tables)
                    {
                        var pk = pks.Where(k => k.TableName == tableName).FirstOrDefault();
                        if (pk.TableName == null)
                        {
                            checkedTables += tableName + Environment.NewLine;
                        }
                    }
                    if (!string.IsNullOrEmpty(checkedTables))
                    {
                        var message = string.Format("The tables below do not have Primary Keys defined,{0}and will not be generated properly:{1}{2}", Environment.NewLine, Environment.NewLine, checkedTables);
                        EnvDteHelper.ShowError(message);
                    }
                    var dbInfo = repository.GetDatabaseInfo();
                    foreach (var kvp in dbInfo)
                    {
                        if (kvp.Key == "Database")
                        {
                            sdfFileName = kvp.Value;
                            break;
                        }
                    }
                    sdfFileName = Path.GetFileName(sdfFileName);
                }

                var fileNameWithoutExtension = Path.GetFileNameWithoutExtension(databaseInfo.DatabaseInfo.Caption);
                if (fileNameWithoutExtension != null)
                {
                    var model = fileNameWithoutExtension.Replace(" ", string.Empty).Replace("#", string.Empty).Replace(".", string.Empty).Replace("-", string.Empty);
                    model = model + "Context";
                    var dcDialog = new DataContextDialog();
                    dcDialog.ModelName   = model;
                    dcDialog.IsDesktop   = true;
                    dcDialog.ProjectName = project.Name;
                    dcDialog.NameSpace   = ThreadHelper.JoinableTaskFactory.Run(() => project.GetAttributeAsync("DefaultNamespace"));

                    if (ThreadHelper.JoinableTaskFactory.Run(() => project.IsKindAsync(ProjectTypes.VB)))
                    {
                        dcDialog.CodeLanguage = "VB";
                    }
                    else
                    {
                        dcDialog.CodeLanguage = "C#";
                    }
                    var result = dcDialog.ShowModal();
                    if (!result.HasValue || result.Value != true || string.IsNullOrWhiteSpace(dcDialog.ModelName))
                    {
                        return;
                    }
                    if (dcDialog.AddRowversionColumns)
                    {
                        AddRowVersionColumns(databaseInfo);
                    }

                    var sdfPath = databaseInfo.DatabaseInfo.ConnectionString;

                    //If version 4.0, create a 3.5 schema sdf, and use that as connection string
                    if (databaseInfo.DatabaseInfo.DatabaseType == DatabaseType.SQLCE40)
                    {
                        var tempFile = Path.GetTempFileName();
                        using (var repository = Helpers.RepositoryHelper.CreateRepository(databaseInfo.DatabaseInfo))
                        {
                            var generator = DataConnectionHelper.CreateGenerator(repository, tempFile, databaseInfo.DatabaseInfo.DatabaseType);
                            generator.ScriptDatabaseToFile(Scope.Schema);
                        }
                        if (sdfFileName != null)
                        {
                            sdfPath = Path.Combine(Path.GetTempPath(), sdfFileName);
                        }
                        using (Stream stream = new MemoryStream(Resources.SqlCe35AddinStore))
                        {
                            // Create a FileStream object to write a stream to a file
                            using (var fileStream = File.Create(sdfPath, (int)stream.Length))
                            {
                                // Fill the bytes[] array with the stream data
                                var bytesInStream = new byte[stream.Length];
                                stream.Read(bytesInStream, 0, bytesInStream.Length);
                                // Use FileStream object to write to the specified file
                                fileStream.Write(bytesInStream, 0, bytesInStream.Length);
                            }
                        }
                        var info = new DatabaseInfo
                        {
                            ConnectionString = "Data Source=" + sdfPath,
                            DatabaseType     = DatabaseType.SQLCE35
                        };
                        using (var repository = Helpers.RepositoryHelper.CreateRepository(info))
                        {
                            var script = File.ReadAllText(tempFile);
                            repository.ExecuteSql(script);
                        }
                        sdfPath = info.ConnectionString;
                    }

                    var versionNumber = GetVersionTableNumber(databaseInfo.DatabaseInfo, true);

                    model = dcDialog.ModelName;
                    var dcPath = Path.Combine(Path.GetTempPath(), model + ".cs");
                    if (dcDialog.CodeLanguage == "VB")
                    {
                        dcPath = Path.Combine(Path.GetTempPath(), model + ".vb");
                    }
                    var parameters = " /provider:SQLCompact /code:\"" + dcPath + "\"";
                    parameters += " /conn:\"" + sdfPath + "\"";
                    parameters += " /context:" + model;
                    if (dcDialog.Pluralize)
                    {
                        parameters += " /pluralize";
                    }
                    if (!string.IsNullOrWhiteSpace(dcDialog.NameSpace))
                    {
                        parameters += " /namespace:" + dcDialog.NameSpace;
                    }
                    var dcH = new DataContextHelper();

                    var sqlmetalResult = dcH.RunSqlMetal(sqlMetalPath, parameters);
                    if (!File.Exists(dcPath))
                    {
                        EnvDteHelper.ShowError("Error during SQL Metal run: " + sqlmetalResult);
                        return;
                    }

                    if (dcDialog.MultipleFiles)
                    {
                        var classes     = DataContextHelper.SplitIntoMultipleFiles(dcPath, dcDialog.NameSpace, model);
                        var projectPath = Path.GetDirectoryName(project.FullPath);

                        foreach (var item in classes)
                        {
                            var fileName = Path.Combine(projectPath, item.Key + ".cs");
                            if (File.Exists(fileName))
                            {
                                File.Delete(fileName);
                            }
                            File.WriteAllText(fileName, item.Value);
                            var classItem = dteH.GetProjectDataContextClass(project, fileName);
                            if (classItem != null)
                            {
                                File.Delete(classItem.FullPath);
                            }
                            ThreadHelper.JoinableTaskFactory.Run(() => project.AddExistingFilesAsync(fileName));
                        }
                    }
                    else
                    {
                        var extension = ".cs";
                        if (dcDialog.CodeLanguage == "VB")
                        {
                            extension = ".vb";
                        }
                        var dcItem = dteH.GetProjectDc(project, model, extension);
                        //TODO Test!
                        var dcTarget = Path.Combine(Path.GetDirectoryName(project.FullPath), model + extension);
                        if (dcItem == null)
                        {
                            File.Copy(dcPath, dcTarget);
                            ThreadHelper.JoinableTaskFactory.Run(() => project.AddExistingFilesAsync(dcTarget));
                        }
                        else
                        {
                            if (EnvDteHelper.ShowMessageBox("The Data Context class already exists in the project, do you wish to replace it?", OLEMSGBUTTON.OLEMSGBUTTON_YESNO, OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_SECOND, OLEMSGICON.OLEMSGICON_QUERY) == System.Windows.Forms.DialogResult.Yes)
                            {
                                File.Copy(dcPath, dcTarget, true);
                                ThreadHelper.JoinableTaskFactory.Run(() => project.AddExistingFilesAsync(dcTarget));
                            }
                        }
                    }
                    await EnvDteHelper.AddReferenceAsync(project, "System.Data.Linq");

                    if (dcDialog.AddConnectionStringBuilder)
                    {
                        var projectPath = Path.GetDirectoryName(project.FullPath);

                        var fileName = "LocalDatabaseConnectionStringBuilder.cs";

                        var filePath = Path.Combine(projectPath, fileName);
                        if (File.Exists(filePath))
                        {
                            File.Delete(filePath);
                        }
                        using (Stream stream = new MemoryStream(Resources.LocalDatabaseConnectionStringBuilder))
                        {
                            // Create a FileStream object to write a stream to a file
                            using (var fileStream = File.Create(filePath, (int)stream.Length))
                            {
                                // Fill the bytes[] array with the stream data
                                var bytesInStream = new byte[stream.Length];
                                stream.Read(bytesInStream, 0, bytesInStream.Length);
                                // Use FileStream object to write to the specified file
                                fileStream.Write(bytesInStream, 0, bytesInStream.Length);
                            }
                        }
                        ThreadHelper.JoinableTaskFactory.Run(() => project.AddExistingFilesAsync(filePath));
                    }

                    // Creates __Version table and adds one row if desired
                    if (dcDialog.AddVersionTable)
                    {
                        using (var repository = Helpers.RepositoryHelper.CreateRepository(databaseInfo.DatabaseInfo))
                        {
                            var list = repository.GetAllTableNames();
                            if (!list.Contains("__VERSION"))
                            {
                                repository.ExecuteSql(string.Format(@"
                                CREATE TABLE [__VERSION] (
                                  [SchemaVersion] int NOT NULL
                                , [DateUpdated] datetime NOT NULL DEFAULT (GETDATE())
                                );
                                GO
                                CREATE INDEX [IX_SchemaVersion] ON [__VERSION] ([SchemaVersion] DESC);
                                GO
                                INSERT INTO [__VERSION] ([SchemaVersion]) VALUES ({0});
                                GO", versionNumber));
                            }
                        }
                    }
                    DataConnectionHelper.LogUsage("DatabaseCreateDC");
                }
            }
            catch (Exception ex)
            {
                DataConnectionHelper.SendError(ex, databaseInfo.DatabaseInfo.DatabaseType, false);
            }
        }