internal DestinationProjXml(string destProj)
        {
            DestProjAbsolutePath = PathMaker.MakeAbsolutePathFromPossibleRelativePathOrDieTrying(null, destProj);
            DestProjDirectory = Path.GetDirectoryName(DestProjAbsolutePath) ?? "";

            try
            {
                DestProjXdoc = XDocument.Load(DestProjAbsolutePath);
                RootXelement = DestProjXdoc.Element(Settings.MSBuild + "Project");
                ItemGroups = RootXelement?.Elements(Settings.MSBuild + "ItemGroup").ToList();
            }
            catch (Exception e)
            {
                App.Crash(e, "Crash: DestProjXml CTOR loading destination XML from " + DestProjAbsolutePath);
            }

            if (RootXelement == null)
                App.Crash("Crash: No MSBuild Namespace in " + DestProjAbsolutePath);

            StartPlaceHolder = FindCommentOrCrashIfDuplicatesFound(Settings.StartPlaceholderComment);
            EndPlaceHolder = FindCommentOrCrashIfDuplicatesFound(Settings.EndPlaceholderComment);

            if (StartPlaceHolder == null && RootXelement != null)
            {
                XElement lastItemGroup = ItemGroups?.Last();
                lastItemGroup?.AddAfterSelf(new XComment(Settings.EndPlaceholderComment));
                lastItemGroup?.AddAfterSelf(new XComment(Settings.StartPlaceholderComment));
                StartPlaceHolder = FindCommentOrCrashIfDuplicatesFound(Settings.StartPlaceholderComment);
                EndPlaceHolder = FindCommentOrCrashIfDuplicatesFound(Settings.EndPlaceholderComment);
            }

            OldLinkedXml = ReadLinkedXml();
            Keepers = new List<XElement>();
        }
		public SliceSettingsWidget(List<SettingsLayer> layerFilters = null, NamedSettingsLayers viewFilter = NamedSettingsLayers.All)
		{
			this.layerFilters = layerFilters;
			this.viewFilter = viewFilter;

			// The last layer of the layerFilters is the target persistence layer
			persistenceLayer = layerFilters?.Last() ?? ActiveSliceSettings.Instance.UserLayer;

			textImageButtonFactory = new TextImageButtonFactory();
			textImageButtonFactory.normalFillColor = RGBA_Bytes.Transparent;
			textImageButtonFactory.FixedHeight = 15 * TextWidget.GlobalPointSizeScaleRatio;
			textImageButtonFactory.fontSize = 8;
			textImageButtonFactory.borderWidth = 1;
			textImageButtonFactory.normalBorderColor = new RGBA_Bytes(ActiveTheme.Instance.PrimaryTextColor, 200);
			textImageButtonFactory.hoverBorderColor = new RGBA_Bytes(ActiveTheme.Instance.PrimaryTextColor, 200);

			this.textImageButtonFactory.disabledTextColor = RGBA_Bytes.Gray;
			this.textImageButtonFactory.hoverTextColor = ActiveTheme.Instance.PrimaryTextColor;
			this.textImageButtonFactory.normalTextColor = ActiveTheme.Instance.SecondaryTextColor;
			this.textImageButtonFactory.pressedTextColor = ActiveTheme.Instance.PrimaryTextColor;

			int minSettingNameWidth = (int)(180 * TextWidget.GlobalPointSizeScaleRatio + .5);
			buttonFactory.FixedHeight = 20 * TextWidget.GlobalPointSizeScaleRatio;
			buttonFactory.fontSize = 10;
			buttonFactory.normalFillColor = RGBA_Bytes.White;
			buttonFactory.normalTextColor = RGBA_Bytes.DarkGray;

			FlowLayoutWidget pageTopToBottomLayout = new FlowLayoutWidget(FlowDirection.TopToBottom, vAnchor: Agg.UI.VAnchor.ParentTop);
			pageTopToBottomLayout.AnchorAll();
			pageTopToBottomLayout.Padding = new BorderDouble(3, 0);
			this.AddChild(pageTopToBottomLayout);

			settingsControlBar = new SettingsControlBar()
			{
				HAnchor = HAnchor.ParentLeftRight,
				BackgroundColor = ActiveTheme.Instance.TransparentDarkOverlay,
				Padding = new BorderDouble(8, 12, 8, 8)
			};

			pageTopToBottomLayout.AddChild(settingsControlBar);

			noConnectionMessageContainer = new AltGroupBox(new TextWidget("No Printer Selected".Localize(), pointSize: 18, textColor: ActiveTheme.Instance.SecondaryAccentColor));
			noConnectionMessageContainer.Margin = new BorderDouble(top: 10);
			noConnectionMessageContainer.BorderColor = ActiveTheme.Instance.PrimaryTextColor;
			noConnectionMessageContainer.HAnchor = Agg.UI.HAnchor.ParentLeftRight;
			noConnectionMessageContainer.Height = 90;

			string noConnectionString = "No printer is currently selected. Please select a printer to edit slice settings.".Localize();
			noConnectionString += "\n\n" + "NOTE: You need to select a printer, but do not need to connect to it.".Localize();
			TextWidget noConnectionMessage = new TextWidget(noConnectionString, pointSize: 10);
			noConnectionMessage.Margin = new BorderDouble(5);
			noConnectionMessage.TextColor = ActiveTheme.Instance.PrimaryTextColor;
			noConnectionMessage.VAnchor = VAnchor.ParentCenter;

			noConnectionMessageContainer.AddChild(noConnectionMessage);
			pageTopToBottomLayout.AddChild(noConnectionMessageContainer);

			categoryTabs = new TabControl();
			categoryTabs.TabBar.BorderColor = ActiveTheme.Instance.PrimaryTextColor;
			categoryTabs.Margin = new BorderDouble(top: 8);
			categoryTabs.AnchorAll();

			sliceSettingsDetailControl = new SliceSettingsDetailControl();

			List<TabBar> sideTabBarsListForLayout = new List<TabBar>();
			for (int categoryIndex = 0; categoryIndex < SliceSettingsOrganizer.Instance.UserLevels[UserLevel].CategoriesList.Count; categoryIndex++)
			{
				OrganizerCategory category = SliceSettingsOrganizer.Instance.UserLevels[UserLevel].CategoriesList[categoryIndex];
				string categoryPageLabel = category.Name.Localize();
				TabPage categoryPage = new TabPage(categoryPageLabel);
				SimpleTextTabWidget textTabWidget = new SimpleTextTabWidget(categoryPage, category.Name + " Tab", 16,
						ActiveTheme.Instance.TabLabelSelected, new RGBA_Bytes(), ActiveTheme.Instance.TabLabelUnselected, new RGBA_Bytes());
				categoryPage.AnchorAll();
				categoryTabs.AddTab(textTabWidget);

				TabControl sideTabs = CreateSideTabsAndPages(minSettingNameWidth, category);
				sideTabBarsListForLayout.Add(sideTabs.TabBar);

				categoryPage.AddChild(sideTabs);
			}

			categoryTabs.TabBar.AddChild(new HorizontalSpacer());
			categoryTabs.TabBar.AddChild(sliceSettingsDetailControl);

			if (sliceSettingsDetailControl.SelectedValue == "Advanced" && ActiveSliceSettings.Instance.ActiveSliceEngineType == SlicingEngineTypes.Slic3r)
			{
				TabPage extraSettingsPage = new TabPage("Other");
				SimpleTextTabWidget extraSettingsTextTabWidget = new SimpleTextTabWidget(extraSettingsPage, "Other Tab", 16,
						ActiveTheme.Instance.TabLabelSelected, new RGBA_Bytes(), ActiveTheme.Instance.TabLabelUnselected, new RGBA_Bytes());
				extraSettingsPage.AnchorAll();
				int count;
				TabControl extraSettingsSideTabs = CreateExtraSettingsSideTabsAndPages(minSettingNameWidth, categoryTabs, out count);
				if (count > 0)
				{
					categoryTabs.AddTab(extraSettingsTextTabWidget);
					sideTabBarsListForLayout.Add(extraSettingsSideTabs.TabBar);
					extraSettingsPage.AddChild(extraSettingsSideTabs);
				}
			}

			double sideTabBarsMinimumWidth = 0;
			foreach (TabBar tabBar in sideTabBarsListForLayout)
			{
				sideTabBarsMinimumWidth = Math.Max(sideTabBarsMinimumWidth, tabBar.Width);
			}
			foreach (TabBar tabBar in sideTabBarsListForLayout)
			{
				tabBar.MinimumSize = new Vector2(sideTabBarsMinimumWidth, tabBar.MinimumSize.y);
			}

			if (sideTabBarsListForLayout.Count == 1)
			{
				sideTabBarsListForLayout[0].MinimumSize = new Vector2(0, 0);
				sideTabBarsListForLayout[0].Width = 0;
			}

			pageTopToBottomLayout.AddChild(categoryTabs);
			AddHandlers();
			SetVisibleControls();

			// Make sure we are on the right tab when we create this view
			{
				string settingsName = "SliceSettingsWidget_CurrentTab";
				string selectedTab = UserSettings.Instance.get(settingsName);
				categoryTabs.SelectTab(selectedTab);

				categoryTabs.TabBar.TabIndexChanged += (object sender, EventArgs e) =>
				{
					UserSettings.Instance.set(settingsName, categoryTabs.TabBar.SelectedTabName);
				};
			}

			this.AnchorAll();
		}