public override void Exec()
        {
            try
            {
                UIHierarchy solExplorer = this.ApplicationObject.ToolWindows.SolutionExplorer;
                UIHierarchyItem hierItem = (UIHierarchyItem)((System.Array)solExplorer.SelectedItems).GetValue(0);
                ProjectItem projItem = (ProjectItem)hierItem.Object;

                SourceControl2 oSourceControl = ((SourceControl2)this.ApplicationObject.SourceControl);
                string sProvider = "";
                string sSourceControlServerName = "";
                string sServerBinding = "";
                string sProject = "";
                string sDefaultSourceSafePath = "";
                if (oSourceControl != null)
                {
                    SourceControlBindings bindings = null;
                    try
                    {
                        bindings = oSourceControl.GetBindings(projItem.ContainingProject.FileName);
                    }
                    catch
                    {
                        //now that you can have custom diff viewers via the preferences window
                    }
                    if (bindings != null)
                    {
                        sProvider = bindings.ProviderName;
                        sSourceControlServerName = bindings.ServerName;
                        sServerBinding = bindings.ServerBinding;
                        if (sProvider == PROVIDER_NAME_SOURCESAFE)
                        {
                            if (sServerBinding.IndexOf("\",") <= 0) throw new Exception("Can't find SourceSafe project path.");
                            sProject = sServerBinding.Substring(1, sServerBinding.IndexOf("\",") - 1);
                        }
                        else if (sProvider == PROVIDER_NAME_TFS)
                        {
                            sProject = sServerBinding;
                        }
                        if (oSourceControl.IsItemUnderSCC(projItem.get_FileNames(0)))
                        {
                            if (projItem.get_FileNames(0).ToLower().StartsWith(bindings.LocalBinding.ToLower()))
                            {
                                sDefaultSourceSafePath = sProject + projItem.get_FileNames(0).Substring(bindings.LocalBinding.Length).Replace('\\','/');
                            }
                            else
                            {
                                sDefaultSourceSafePath = sProject + "/" + projItem.Name;
                            }
                        }
                    }
                }

                if (projItem.Document != null && !projItem.Document.Saved)
                {
                    if (MessageBox.Show("This command compares the disk version of a file. Do you want to save your changes to disk before proceeding?", "Save Changes?", MessageBoxButtons.YesNo) == DialogResult.Yes)
                        projItem.Save("");
                }

                SSIS.SmartDiff form = new BIDSHelper.SSIS.SmartDiff();
                form.SourceControlProvider = sProvider;
                form.DefaultWindowsPath = projItem.get_FileNames(0);
                if (sProvider == PROVIDER_NAME_SOURCESAFE || sProvider == PROVIDER_NAME_TFS)
                {
                    form.DefaultSourceSafePath = sDefaultSourceSafePath;
                    form.SourceSafeIniDirectory = sSourceControlServerName;
                }
                DialogResult res = form.ShowDialog();
                if (res != DialogResult.OK) return;

                //get the XSLT for this file extension
                string sXslt = null;
                string sProjectItemFileName = projItem.Name.ToLower();
                bool bNewLineOnAttributes = true;
                foreach (string extension in DTS_FILE_EXTENSIONS)
                {
                    if (sProjectItemFileName.EndsWith(extension))
                    {
                        sXslt = BIDSHelper.Resources.Common.SmartDiffDtsx;
                        break;
                    }
                }
                foreach (string extension in SSAS_FILE_EXTENSIONS)
                {
                    if (sProjectItemFileName.EndsWith(extension))
                    {
                        sXslt = BIDSHelper.Resources.Common.SmartDiffSSAS;
                        break;
                    }
                }
                foreach (string extension in SSRS_FILE_EXTENSIONS)
                {
                    if (sProjectItemFileName.EndsWith(extension))
                    {
                        sXslt = BIDSHelper.Resources.Common.SmartDiffSSRS;
                        bNewLineOnAttributes = false;
                        break;
                    }
                }

                string sOldFile = System.IO.Path.GetTempFileName();
                string sNewFile = System.IO.Path.GetTempFileName();

                try
                {
                    string sOldFileName = form.txtCompare.Text;
                    string sNewFileName = form.txtTo.Text;

                    if (form.txtCompare.Text.StartsWith("$/"))
                    {
                        if (sProvider == PROVIDER_NAME_SOURCESAFE)
                            GetSourceSafeFile(sSourceControlServerName, form.txtCompare.Text, sOldFile);
                        else if (sProvider == PROVIDER_NAME_TFS)
                            GetTFSFile(sSourceControlServerName, form.txtCompare.Text, sOldFile);
                        sOldFileName += " (server)";
                    }
                    else
                    {
                        System.IO.File.Copy(form.txtCompare.Text, sOldFile, true);
                        sOldFileName += " (local)";
                    }

                    if (form.txtTo.Text.StartsWith("$/"))
                    {
                        if (sProvider == PROVIDER_NAME_SOURCESAFE)
                            GetSourceSafeFile(sSourceControlServerName, form.txtTo.Text, sNewFile);
                        else if (sProvider == PROVIDER_NAME_TFS)
                            GetTFSFile(sSourceControlServerName, form.txtTo.Text, sNewFile);
                        sNewFileName += " (server)";
                    }
                    else
                    {
                        System.IO.File.Copy(form.txtTo.Text, sNewFile, true);
                        sNewFileName += " (local)";
                    }

                    PrepXmlForDiff(sOldFile, sXslt, bNewLineOnAttributes);
                    PrepXmlForDiff(sNewFile, sXslt, bNewLineOnAttributes);

                    ShowDiff(sOldFile, sNewFile, form.checkIgnoreCase.Checked, form.checkIgnoreEOL.Checked, form.checkIgnoreWhiteSpace.Checked, sOldFileName, sNewFileName);
                }
                finally
                {
                    try
                    {
                        System.IO.File.Delete(sOldFile);
                        System.IO.File.Delete(sNewFile);
                    }
                    catch { }
                }

            }
            catch (System.Exception ex)
            {
                string sError = "";
                Exception exLoop = ex;
                while (exLoop != null)
                {
                    sError += exLoop.Message + "\r\n";
                    exLoop = exLoop.InnerException;
                }
                MessageBox.Show(sError, "BIDS Helper Smart Diff Error");
            }
        }
        private void ExecInternal()
        {
            try
            {
                UIHierarchy     solExplorer = this.ApplicationObject.ToolWindows.SolutionExplorer;
                UIHierarchyItem hierItem    = (UIHierarchyItem)((System.Array)solExplorer.SelectedItems).GetValue(0);
                ProjectItem     projItem    = (ProjectItem)hierItem.Object;

#if !(YUKON || KATMAI || DENALI || SQL2014)
                if (projItem.Name.ToLower().EndsWith(".bim"))
                {
                    var sandboxWrapper = new BIDSHelper.SSAS.DataModelingSandboxWrapper(this);
                    if (sandboxWrapper.IsTabularMetadata)
                    {
                        string compatibility = sandboxWrapper.DatabaseCompatibilityLevel.ToString();
                        System.Windows.Forms.MessageBox.Show("BIDS Helper Smart Diff is not supported for " + compatibility + " compatibility level models yet.", "BIDS Helper Smart Diff");
                        return;
                    }
                }
#endif

                SourceControl2 oSourceControl           = ((SourceControl2)this.ApplicationObject.SourceControl);
                string         sProvider                = "";
                string         sSourceControlServerName = "";
                string         sServerBinding           = "";
                string         sProject = "";
                string         sDefaultSourceSafePath = "";
                if (oSourceControl != null)
                {
                    SourceControlBindings bindings = null;
                    try
                    {
                        bindings = oSourceControl.GetBindings(projItem.ContainingProject.FileName);
                    }
                    catch
                    {
                        //now that you can have custom diff viewers via the preferences window
                    }
                    if (bindings != null)
                    {
                        sProvider = bindings.ProviderName;
                        sSourceControlServerName = bindings.ServerName;
                        sServerBinding           = bindings.ServerBinding;
                        if (sProvider == PROVIDER_NAME_SOURCESAFE)
                        {
                            if (sServerBinding.IndexOf("\",") <= 0)
                            {
                                throw new Exception("Can't find SourceSafe project path.");
                            }
                            sProject = sServerBinding.Substring(1, sServerBinding.IndexOf("\",") - 1);
                        }
                        else if (sProvider == PROVIDER_NAME_TFS)
                        {
                            sProject = sServerBinding;
                        }
                        if (oSourceControl.IsItemUnderSCC(projItem.get_FileNames(0)))
                        {
                            if (projItem.get_FileNames(0).ToLower().StartsWith(bindings.LocalBinding.ToLower()))
                            {
                                sDefaultSourceSafePath = sProject + projItem.get_FileNames(0).Substring(bindings.LocalBinding.Length).Replace('\\', '/');
                            }
                            else
                            {
                                sDefaultSourceSafePath = sProject + "/" + projItem.Name;
                            }
                        }
                    }
                    else
                    {
                        try
                        {
                            if (GitHelper.IsPathInGitRepository(projItem.get_FileNames(0)))
                            {
                                sSourceControlServerName = GitHelper.GetGitRepositoryPath(projItem.get_FileNames(0));
                                sDefaultSourceSafePath   = "$/" + GitHelper.GetRelativePath(projItem.get_FileNames(0));
                                sProvider = PROVIDER_NAME_GIT;
                            }
                        }
                        catch (Exception ex)
                        {
                            package.Log.Exception("Could not check whether solution is a Git repository", ex);
                        }
                    }
                }

                if (projItem.Document != null && !projItem.Document.Saved)
                {
                    if (MessageBox.Show("This command compares the disk version of a file. Do you want to save your changes to disk before proceeding?", "Save Changes?", MessageBoxButtons.YesNo) == DialogResult.Yes)
                    {
                        projItem.Save("");
                    }
                }

                SSIS.SmartDiff form = new BIDSHelper.SSIS.SmartDiff();
                form.SourceControlProvider = sProvider;
                form.DefaultWindowsPath    = projItem.get_FileNames(0);
                if (sProvider == PROVIDER_NAME_SOURCESAFE || sProvider == PROVIDER_NAME_TFS || sProvider == PROVIDER_NAME_GIT)
                {
                    form.DefaultSourceSafePath  = sDefaultSourceSafePath;
                    form.SourceSafeIniDirectory = sSourceControlServerName;
                }
                DialogResult res = form.ShowDialog();
                if (res != DialogResult.OK)
                {
                    return;
                }


                //get the XSLT for this file extension
                string sXslt = null;
                string sProjectItemFileName = projItem.Name.ToLower();
                bool   bNewLineOnAttributes = true;
                foreach (string extension in DTS_FILE_EXTENSIONS)
                {
                    if (sProjectItemFileName.EndsWith(extension))
                    {
                        sXslt = BIDSHelper.Resources.Common.SmartDiffDtsx;
                        break;
                    }
                }
                foreach (string extension in SSAS_FILE_EXTENSIONS)
                {
                    if (sProjectItemFileName.EndsWith(extension))
                    {
                        sXslt = BIDSHelper.Resources.Common.SmartDiffSSAS;
                        break;
                    }
                }
                foreach (string extension in SSRS_FILE_EXTENSIONS)
                {
                    if (sProjectItemFileName.EndsWith(extension))
                    {
                        sXslt = BIDSHelper.Resources.Common.SmartDiffSSRS;
                        bNewLineOnAttributes = false;
                        break;
                    }
                }

                string sOldFile = System.IO.Path.GetTempFileName();
                string sNewFile = System.IO.Path.GetTempFileName();

                try
                {
                    string sOldFileName = form.txtCompare.Text;
                    string sNewFileName = form.txtTo.Text;

                    if (form.txtCompare.Text.StartsWith("$/"))
                    {
                        if (sProvider == PROVIDER_NAME_SOURCESAFE)
                        {
                            GetSourceSafeFile(sSourceControlServerName, form.txtCompare.Text, sOldFile);
                        }
                        else if (sProvider == PROVIDER_NAME_TFS)
                        {
                            GetTFSFile(sSourceControlServerName, form.txtCompare.Text, sOldFile);
                        }
                        else if (sProvider == PROVIDER_NAME_GIT)
                        {
                            GetGitFile(sSourceControlServerName, form.txtCompare.Text, sOldFile);
                        }
                        sOldFileName += " (server)";
                    }
                    else
                    {
                        System.IO.File.Copy(form.txtCompare.Text, sOldFile, true);
                        sOldFileName += " (local)";
                    }

                    if (form.txtTo.Text.StartsWith("$/"))
                    {
                        if (sProvider == PROVIDER_NAME_SOURCESAFE)
                        {
                            GetSourceSafeFile(sSourceControlServerName, form.txtTo.Text, sNewFile);
                        }
                        else if (sProvider == PROVIDER_NAME_TFS)
                        {
                            GetTFSFile(sSourceControlServerName, form.txtTo.Text, sNewFile);
                        }
                        else if (sProvider == PROVIDER_NAME_GIT)
                        {
                            GetGitFile(sSourceControlServerName, form.txtTo.Text, sNewFile);
                        }
                        sNewFileName += " (server)";
                    }
                    else
                    {
                        System.IO.File.Copy(form.txtTo.Text, sNewFile, true);
                        sNewFileName += " (local)";
                    }

                    PrepXmlForDiff(sOldFile, sXslt, bNewLineOnAttributes);
                    PrepXmlForDiff(sNewFile, sXslt, bNewLineOnAttributes);

                    ShowDiff(sOldFile, sNewFile, form.checkIgnoreCase.Checked, form.checkIgnoreEOL.Checked, form.checkIgnoreWhiteSpace.Checked, sOldFileName, sNewFileName);
                }
                finally
                {
                    try
                    {
                        System.IO.File.Delete(sOldFile);
                        System.IO.File.Delete(sNewFile);
                    }
                    catch { }
                }
            }
            catch (System.Exception ex)
            {
                string    sError = "";
                Exception exLoop = ex;
                while (exLoop != null)
                {
                    sError += exLoop.Message + "\r\n";
                    exLoop  = exLoop.InnerException;
                }
                sError += ex.StackTrace;
                MessageBox.Show(sError, "BIDS Helper Smart Diff Error");
            }
        }