text:
// ReSharper disable once CheckNamespace
namespace Fluent
{
    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.Collections.Specialized;
    using System.ComponentModel;
    using System.Windows;
    using System.Windows.Automation.Peers;
    using System.Windows.Controls;
    using System.Windows.Controls.Primitives;
    using System.Windows.Data;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Shapes;
    using Fluent.Extensions;
    using Fluent.Helpers;
    using Fluent.Internal;
    using Fluent.Internal.KnownBoxes;

    ///
    /// RibbonGroup represents a logical group of controls as they appear on
    /// a RibbonTab.  These groups can resize its content
    ///
    [TemplatePart(Name = "PART_DialogLauncherButton", Type = typeof(Button))]
    [TemplatePart(Name = "PART_HeaderContentControl", Type = typeof(ContentControl))]
    [TemplatePart(Name = "PART_CollapsedHeaderContentControl", Type = typeof(ContentControl))]
    [TemplatePart(Name = "PART_Popup", Type = typeof(Popup))]
    [TemplatePart(Name = "PART_UpPanel", Type = typeof(Panel))]
    [TemplatePart(Name = "PART_ParentPanel", Type = typeof(Panel))]
    [TemplatePart(Name = "PART_SnappedImage", Type = typeof(Image))]
    public class RibbonGroupBox : HeaderedItemsControl, IQuickAccessItemProvider, IDropDownControl, IKeyTipedControl, IHeaderedControl, ILogicalChildSupport
    {
        #region Fields

        // up part
        private Panel upPanel;

        private Panel parentPanel;

        // Freezed image (created during snapping)
        private Image snappedImage;

        // Is visual currently snapped
        private bool isSnapped;

        private readonly ItemContainerGeneratorAction updateChildSizesItemContainerGeneratorAction;

        #endregion

        #region Properties

        ///
        /// Get the <see cref="ContentControl"/> responsible for rendering the header.
        ///
        public ContentControl HeaderContentControl { get; private set; }

        ///
        /// Get the <see cref="ContentControl"/> responsible for rendering the header when <see cref="State"/> is equal to <see cref="RibbonGroupBoxState.Collapsed"/>.
        ///
        public ContentControl CollapsedHeaderContentControl { get; private set; }

        #endregion

        #region KeyTip

        /// <inheritdoc />
        public string KeyTip
        {
            get { return (string)this.GetValue(KeyTipProperty); }
            set { this.SetValue(KeyTipProperty, value); }
        }

        ///
        /// Using a DependencyProperty as the backing store for Keys.
        /// This enables animation, styling, binding, etc...
        ///
        public static readonly DependencyProperty KeyTipProperty = Fluent.KeyTip.KeysProperty.AddOwner(typeof(RibbonGroupBox));

        #endregion

        #region Header-Options

        ///
        /// <see cref="DependencyProperty"/> for IsCollapsedHeaderContentPresenter.
        ///
        public static readonly DependencyProperty IsCollapsedHeaderContentPresenterProperty = DependencyProperty.RegisterAttached("IsCollapsedHeaderContentPresenter", typeof(bool), typeof(RibbonGroupBox), new PropertyMetadata(BooleanBoxes.FalseBox));

        ///
        /// Sets the value of <see cref="IsCollapsedHeaderContentPresenterProperty"/>.
        ///
        public static void SetIsCollapsedHeaderContentPresenter(DependencyObject element, bool value)
        {
            element.SetValue(IsCollapsedHeaderContentPresenterProperty, value);
        }

        ///
        /// Gets the value of <see cref="IsCollapsedHeaderContentPresenterProperty"/>.
        ///
        [AttachedPropertyBrowsableForType(typeof(RibbonGroupBox))]
        public static bool GetIsCollapsedHeaderContentPresenter(DependencyObject element)
        {
            return (bool)element.GetValue(IsCollapsedHeaderContentPresenterProperty);
        }

        #endregion

        /// <inheritdoc />
        public Popup DropDownPopup { get; private set; }

        /// <inheritdoc />
        public bool IsContextMenuOpened { get; set; }

        #region State

        ///
        /// Gets or sets the current state of the group
        ///
        public RibbonGroupBoxState State
        {
            get { return (RibbonGroupBoxState)this.GetValue(StateProperty); }
            set { this.SetValue(StateProperty, value); }
        }

        /// Identifies the <see cref="State"/> dependency property.
        public static readonly DependencyProperty StateProperty =
            DependencyProperty.Register(nameof(State), typeof(RibbonGroupBoxState), typeof(RibbonGroupBox), new PropertyMetadata(RibbonGroupBoxState.Large, OnStateChanged));

        ///
        /// On state property changed
        ///
        /// <param name="d">Object</param>
        /// <param name="e">The event data</param>
        private static void OnStateChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var ribbonGroupBox = (RibbonGroupBox)d;
            ribbonGroupBox.updateChildSizesItemContainerGeneratorAction.QueueAction();
        }

        private void UpdateChildSizes()
        {
            var groupBoxState = this.State == RibbonGroupBoxState.QuickAccess
                            ? RibbonGroupBoxState.Collapsed
                            : this.State;

            foreach (var item in this.Items)
            {
                var element = this.ItemContainerGenerator.ContainerFromItem(item);

                if (element is null)
                {
                    continue;
                }

                var targetElement = element;

                if (targetElement is ContentPresenter)
                {
                    targetElement = UIHelper.GetFirstVisualChild(targetElement) ?? targetElement;
                }

                RibbonProperties.SetAppropriateSize(targetElement, groupBoxState);
            }
        }

        #endregion

        #region Scale

        // Current scale index
        private int scale;

        ///
        /// Gets or sets scale index (for internal IRibbonScalableControl)
        ///
        internal int Scale
        {
            get { return this.scale; }

            set
            {
                var difference = value - this.scale;
                this.scale = value;

                for (var i = 0; i < Math.Abs(difference); i++)
                {
                    if (difference > 0)
                    {
                        this.EnlargeScalableItems();
                    }
                    else
                    {
                        this.ReduceScalableItems();
                    }
                }
            }
        }

        private enum ScaleDirection
        {
            Enlarge,
            Reduce
        }

        // Finds and increases size of all scalable elements in this group box
        private void EnlargeScalableItems()
        {
            this.ScaleScaleableItems(ScaleDirection.Enlarge);
        }

        // Finds and decreases size of all scalable elements in this group box
        private void ReduceScalableItems()
        {
            this.ScaleScaleableItems(ScaleDirection.Reduce);
        }

        private void ScaleScaleableItems(ScaleDirection scaleDirection)
        {
            foreach (var item in this.Items)
            {
                var scalableRibbonControl = this.ItemContainerGenerator.ContainerOrContainerContentFromItem<IScalableRibbonControl>(item);

                if (scalableRibbonControl is null
                    || (scalableRibbonControl is UIElement uiElement && uiElement.Visibility != Visibility.Visible))
                {
                    continue;
                }

                switch (scaleDirection)
                {
                    case ScaleDirection.Enlarge:
                        scalableRibbonControl.Enlarge();
                        break;

                    case ScaleDirection.Reduce:
                        scalableRibbonControl.Reduce();
                        break;
                }
            }
        }

        private void ResetScaleableItems()
        {
            foreach (var item in this.Items)
            {
                var scalableRibbonControl = this.ItemContainerGenerator.ContainerOrContainerContentFromItem<IScalableRibbonControl>(item);

                if (scalableRibbonControl is null
                    || (scalableRibbonControl is UIElement uiElement && uiElement.Visibility != Visibility.Visible))
                {
                    continue;
                }

                scalableRibbonControl.ResetScale();
            }
        }

        private void OnScalableControlScaled(object sender, EventArgs e)
        {
            this.TryClearCache();
        }

        ///
        /// Gets or sets whether to reset cache when scalable control is scaled
        ///
        internal ScopeGuard CacheResetGuard { get; }

        private void UpdateScalableControlSubscritions(bool registerEvents)
        {
            foreach (var item in this.Items)
            {
                var scalableRibbonControl = this.ItemContainerGenerator.ContainerOrContainerContentFromItem<IScalableRibbonControl>(item);

                if (scalableRibbonControl is null)
                {
                    continue;
                }

                // Always unregister first to ensure that we don't subscribe twice
                scalableRibbonControl.Scaled -= this.OnScalableControlScaled;

                if (registerEvents)
                {
                    scalableRibbonControl.Scaled += this.OnScalableControlScaled;
                }
            }
        }

        #endregion

        #region IsLauncherVisible

        ///
        /// Gets or sets dialog launcher button visibility
        ///
        public bool IsLauncherVisible
        {
            get { return (bool)this.GetValue(IsLauncherVisibleProperty); }
            set { this.SetValue(IsLauncherVisibleProperty, value); }
        }

        /// Identifies the <see cref="IsLauncherVisible"/> dependency property.
        public static readonly DependencyProperty IsLauncherVisibleProperty =
            DependencyProperty.Register(nameof(IsLauncherVisible), typeof(bool), typeof(RibbonGroupBox), new PropertyMetadata(BooleanBoxes.FalseBox));

        #endregion

        #region LauncherKeys

        ///
        /// Gets or sets key tip for dialog launcher button
        ///
        [DisplayName("DialogLauncher Keys")]
        [Category("KeyTips")]
        [Description("Key tip keys for dialog launcher button")]
        public string LauncherKeys
        {
            get { return (string)this.GetValue(LauncherKeysProperty); }
            set { this.SetValue(LauncherKeysProperty, value); }
        }

        /// Identifies the <see cref="LauncherKeys"/> dependency property.
        public static readonly DependencyProperty LauncherKeysProperty =
            DependencyProperty.Register(nameof(LauncherKeys),
            typeof(string), typeof(RibbonGroupBox), new PropertyMetadata(OnLauncherKeysChanged));

        private static void OnLauncherKeysChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var ribbonGroupBox = (RibbonGroupBox)d;
            if (ribbonGroupBox.LauncherButton != null)
            {
                ribbonGroupBox.LauncherButton.KeyTip = (string)e.NewValue;
            }
        }

        #endregion

        #region LauncherIcon

        ///
        /// Gets or sets launcher button icon
        ///
        public object LauncherIcon
        {
            get { return this.GetValue(LauncherIconProperty); }
            set { this.SetValue(LauncherIconProperty, value); }
        }

        /// Identifies the <see cref="LauncherIcon"/> dependency property.
        public static readonly DependencyProperty LauncherIconProperty =
            DependencyProperty.Register(nameof(LauncherIcon), typeof(object), typeof(RibbonGroupBox), new PropertyMetadata(LogicalChildSupportHelper.OnLogicalChildPropertyChanged));

        #endregion

        #region LauncherIcon

        ///
        /// Gets or sets launcher button text
        ///
        public string LauncherText
        {
            get { return (string)this.GetValue(LauncherTextProperty); }
            set { this.SetValue(LauncherTextProperty, value); }
        }

        /// Identifies the <see cref="LauncherText"/> dependency property.
        public static readonly DependencyProperty LauncherTextProperty =
            DependencyProperty.Register(nameof(LauncherText), typeof(string), typeof(RibbonGroupBox), new PropertyMetadata());

        #endregion

        #region LauncherCommand

        ///
        /// Gets or sets the command to invoke when this button is pressed. This is a dependency property.
        ///
        [Category("Action")]
        [Localizability(LocalizationCategory.NeverLocalize)]
        [Bindable(true)]
        public ICommand LauncherCommand
        {
            get
            {
                return (ICommand)this.GetValue(LauncherCommandProperty);
            }

            set
            {
                this.SetValue(LauncherCommandProperty, value);
            }
        }

        ///
        /// Gets or sets the parameter to pass to the System.Windows.Controls.Primitives.ButtonBase.Command property. This is a dependency property.
        ///
        [Bindable(true)]
        [Localizability(LocalizationCategory.NeverLocalize)]
        [Category("Action")]
        public object LauncherCommandParameter
        {
            get
            {
                return this.GetValue(LauncherCommandParameterProperty);
            }

            set
            {
                this.SetValue(LauncherCommandParameterProperty, value);
            }
        }

        ///
        /// Gets or sets the element on which to raise the specified command. This is a dependency property.
        ///
        [Bindable(true)]
        [Category("Action")]
        public IInputElement LauncherCommandTarget
        {
            get
            {
                return (IInputElement)this.GetValue(LauncherCommandTargetProperty);
            }

            set
            {
                this.SetValue(LauncherCommandTargetProperty, value);
            }
        }

        /// Identifies the <see cref="LauncherCommandParameter"/> dependency property.
        public static readonly DependencyProperty LauncherCommandParameterProperty = DependencyProperty.Register(nameof(LauncherCommandParameter), typeof(object), typeof(RibbonGroupBox), new PropertyMetadata());

        /// Identifies the <see cref="LauncherCommand"/> dependency property.
        public static readonly DependencyProperty LauncherCommandProperty = DependencyProperty.Register(nameof(LauncherCommand), typeof(ICommand), typeof(RibbonGroupBox), new PropertyMetadata());

        /// Identifies the <see cref="LauncherCommandTarget"/> dependency property.
        public static readonly DependencyProperty LauncherCommandTargetProperty = DependencyProperty.Register(nameof(LauncherCommandTarget), typeof(IInputElement), typeof(RibbonGroupBox), new PropertyMetadata());

        #endregion

        #region LauncherToolTip

        ///
        /// Gets or sets launcher button tooltip
        ///
        public object LauncherToolTip
        {
            get { return this.GetValue(LauncherToolTipProperty); }
            set { this.SetValue(LauncherToolTipProperty, value); }
        }

        /// Identifies the <see cref="LauncherToolTip"/> dependency property.
        public static readonly DependencyProperty LauncherToolTipProperty =
            DependencyProperty.Register(nameof(LauncherToolTip), typeof(object), typeof(RibbonGroupBox), new PropertyMetadata());

        #endregion

        #region IsLauncherEnabled

        ///
        /// Gets or sets whether launcher button is enabled
        ///
        public bool IsLauncherEnabled
        {
            get { return (bool)this.GetValue(IsLauncherEnabledProperty); }
            set { this.SetValue(IsLauncherEnabledProperty, value); }
        }

        /// Identifies the <see cref="IsLauncherEnabled"/> dependency property.
        public static readonly DependencyProperty IsLauncherEnabledProperty =
            DependencyProperty.Register(nameof(IsLauncherEnabled), typeof(bool), typeof(RibbonGroupBox), new PropertyMetadata(BooleanBoxes.TrueBox));

        #endregion

        #region LauncherButton

        ///
        /// Gets launcher button
        ///
        public Button LauncherButton
        {
            get { return (Button)this.GetValue(LauncherButtonProperty); }
            private set { this.SetValue(LauncherButtonPropertyKey, value); }
        }

        // ReSharper disable once InconsistentNaming
        private static readonly DependencyPropertyKey LauncherButtonPropertyKey =
            DependencyProperty.RegisterReadOnly(nameof(LauncherButton), typeof(Button), typeof(RibbonGroupBox), new PropertyMetadata());

        /// Identifies the <see cref="LauncherButton"/> dependency property.
        public static readonly DependencyProperty LauncherButtonProperty = LauncherButtonPropertyKey.DependencyProperty;

        #endregion

        #region IsOpen

        /// <inheritdoc />
        public bool IsDropDownOpen
        {
            get { return (bool)this.GetValue(IsDropDownOpenProperty); }
            set { this.SetValue(IsDropDownOpenProperty, value); }
        }

        /// Identifies the <see cref="IsDropDownOpen"/> dependency property.
        public static readonly DependencyProperty IsDropDownOpenProperty = DependencyProperty.Register(nameof(IsDropDownOpen), typeof(bool), typeof(RibbonGroupBox), new PropertyMetadata(BooleanBoxes.FalseBox, OnIsDropDownOpenChanged, CoerceIsDropDownOpen));

        private static object CoerceIsDropDownOpen(DependencyObject d, object basevalue)
        {
            var box = (RibbonGroupBox)d;

            if ((box.State != RibbonGroupBoxState.Collapsed)
                && (box.State != RibbonGroupBoxState.QuickAccess))
            {
                return false;
            }

            return basevalue;
        }

        #endregion

        #region LogicalChildren

        #region Icon

        ///
        /// Gets or sets icon
        ///
        public object Icon
        {
            get { return this.GetValue(IconProperty); }
            set { this.SetValue(IconProperty, value); }
        }

        /// Identifies the <see cref="Icon"/> dependency property.
        public static readonly DependencyProperty IconProperty = RibbonControl.IconProperty.AddOwner(typeof(RibbonGroupBox), new PropertyMetadata(LogicalChildSupportHelper.OnLogicalChildPropertyChanged));

        #endregion

        #region IsSeparatorVisible

        ///
        /// Gets or sets whether the groupbox shows a separator.
        ///
        public bool IsSeparatorVisible
        {
            get { return (bool)this.GetValue(IsSeparatorVisibleProperty); }
            set { this.SetValue(IsSeparatorVisibleProperty, value); }
        }

        /// Identifies the <see cref="IsSeparatorVisible"/> dependency property.
        public static readonly DependencyProperty IsSeparatorVisibleProperty =
          DependencyProperty.Register(nameof(IsSeparatorVisible), typeof(bool), typeof(RibbonGroupBox), new PropertyMetadata(BooleanBoxes.TrueBox));

        #endregion

        #endregion

        #region Events

        ///
        /// Dialog launcher btton click event
        ///
        public event RoutedEventHandler LauncherClick;

        /// <inheritdoc />
        public event EventHandler DropDownOpened;

        /// <inheritdoc />
        public event EventHandler DropDownClosed;

        #endregion

        #region Initialize

        ///
        /// Initializes static members of the <see cref="RibbonGroupBox"/> class.
        ///
        static RibbonGroupBox()
        {
            var type = typeof(RibbonGroupBox);

            DefaultStyleKeyProperty.OverrideMetadata(type, new FrameworkPropertyMetadata(type));
            VisibilityProperty.AddOwner(type, new PropertyMetadata(OnVisibilityChanged));
            FontSizeProperty.AddOwner(type, new FrameworkPropertyMetadata(OnFontSizeChanged));
            FontFamilyProperty.AddOwner(type, new FrameworkPropertyMetadata(OnFontFamilyChanged));

            PopupService.Attach(type);
            ContextMenuService.Attach(type);
        }

        private static void OnVisibilityChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var box = (RibbonGroupBox)d;
            box.TryClearCacheAndResetStateAndScaleAndNotifyParentRibbonGroupsContainer();
        }

        private static void OnFontSizeChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var box = (RibbonGroupBox)d;
            box.TryClearCacheAndResetStateAndScaleAndNotifyParentRibbonGroupsContainer();
        }

        private static void OnFontFamilyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var box = (RibbonGroupBox)d;
            box.TryClearCacheAndResetStateAndScaleAndNotifyParentRibbonGroupsContainer();
        }

        ///
        /// Default constructor
        ///
        public RibbonGroupBox()
        {
            this.CacheResetGuard = new ScopeGuard(() => this.UpdateScalableControlSubscritions(false), () => this.UpdateScalableControlSubscritions(true));

            this.CoerceValue(ContextMenuProperty);
            this.Focusable = false;

            this.Loaded += this.OnLoaded;
            this.Unloaded += this.OnUnloaded;

            this.updateChildSizesItemContainerGeneratorAction = new ItemContainerGeneratorAction(this.ItemContainerGenerator, this.UpdateChildSizes);
        }

        private void OnLoaded(object sender, RoutedEventArgs e)
        {
            this.SubscribeEvents();
        }

        private void OnUnloaded(object sender, RoutedEventArgs e)
        {
            this.UnSubscribeEvents();
        }

        private void SubscribeEvents()
        {
            // Always unsubscribe events to ensure we don't subscribe twice
            this.UnSubscribeEvents();

            this.UpdateScalableControlSubscritions(true);

            if (this.LauncherButton != null)
            {
                this.LauncherButton.Click += this.OnDialogLauncherButtonClick;
            }

            if (this.DropDownPopup != null)
            {
                this.DropDownPopup.Opened += this.OnPopupOpened;
                this.DropDownPopup.Closed += this.OnPopupClosed;
            }
        }

        private void UnSubscribeEvents()
        {
            this.UpdateScalableControlSubscritions(false);

            if (this.LauncherButton != null)
            {
                this.LauncherButton.Click -= this.OnDialogLauncherButtonClick;
            }

            if (this.DropDownPopup != null)
            {
                this.DropDownPopup.Opened -= this.OnPopupOpened;
                this.DropDownPopup.Closed -= this.OnPopupClosed;
            }
        }

        #endregion

        #region Methods

        ///
        /// Gets a panel with items
        ///
        /// <returns></returns>
        internal Panel GetPanel()
        {
            return this.upPanel;
        }

        ///
        /// Gets cmmon layout root for popup and groupbox
        ///
        /// <returns></returns>
        internal Panel GetLayoutRoot()
        {
            return this.parentPanel;
        }

        #endregion

        #region Snapping

        ///
        /// Snaps / Unsnaps the Visual
        /// (remove visuals and substitute with freezed image)
        ///
        public bool IsSnapped
        {
            get
            {
                return this.isSnapped;
            }

            set
            {
                if (value == this.isSnapped)
                {
                    return;
                }

                if (value)
                {
                    if (this.IsVisible)
                    {
                        // Render the freezed image
                        var renderTargetBitmap = new RenderTargetBitmap((int)this.ActualWidth, (int)this.ActualHeight, 96, 96, PixelFormats.Pbgra32);
                        renderTargetBitmap.Render((Visual)VisualTreeHelper.GetChild(this, 0));
                        this.snappedImage.FlowDirection = this.FlowDirection;
                        this.snappedImage.Source = renderTargetBitmap;
                        this.snappedImage.Width = this.ActualWidth;
                        this.snappedImage.Height = this.ActualHeight;
                        this.snappedImage.Visibility = Visibility.Visible;
                        this.isSnapped = true;
                    }
                }
                else if (this.snappedImage != null)
                {
                    // Clean up
                    this.snappedImage.Visibility = Visibility.Collapsed;
                    this.isSnapped = false;
                }

                this.InvalidateVisual();
            }
        }

        #endregion

        #region Caching

#pragma warning disable 414
        // Pair of chached states
        private struct StateScale
        {
            public RibbonGroupBoxState State;
            public int Scale;
        }
#pragma warning restore 414

        // Cache
        private readonly Dictionary<StateScale, Size> cachedMeasures = new Dictionary<StateScale, Size>();

        ///
        /// Gets or sets intermediate state of the group box
        ///
        internal RibbonGroupBoxState StateIntermediate { get; set; }

        ///
        /// Gets or sets intermediate scale of the group box
        ///
        internal int ScaleIntermediate { get; set; }

        ///
        /// Gets intermediate desired size
        ///
        internal Size DesiredSizeIntermediate
        {
            get
            {
                var stateScale = this.GetCurrentIntermediateStateScale();

                if (this.cachedMeasures.TryGetValue(stateScale, out var result) == false)
                {
                    var contentHeight = UIHelper.GetParent<RibbonTabControl>(this)?.ContentHeight ?? RibbonTabControl.DefaultContentHeight;

                    using (this.CacheResetGuard.Start())
                    {
                        // Get desired size for these values
                        var backupState = this.State;
                        var backupScale = this.Scale;
                        this.State = this.StateIntermediate;
                        this.Scale = this.ScaleIntermediate;
                        this.InvalidateLayout();
                        this.Measure(new Size(double.PositiveInfinity, contentHeight));
                        this.cachedMeasures.Remove(stateScale);
                        this.cachedMeasures.Add(stateScale, this.DesiredSize);
                        result = this.DesiredSize;

                        // Rollback changes
                        this.State = backupState;
                        this.Scale = backupScale;
                        this.InvalidateLayout();
                        this.Measure(new Size(double.PositiveInfinity, contentHeight));

                        this.UpdateScalableControlSubscritions(true);
                    }
                }

                return result;
            }
        }

        private bool TryClearCache()
        {
            if (this.CacheResetGuard.IsActive == false)
            {
                this.ClearCache();
                return true;
            }

            return false;
        }

        internal bool TryClearCacheAndResetStateAndScale()
        {
            if (this.CacheResetGuard.IsActive
                || this.IsLoaded == false)
            {
                return false;
            }

            this.UpdateScalableControlSubscritions(false);

            this.State = RibbonGroupBoxState.Large;
            this.Scale = 0;
            this.StateIntermediate = RibbonGroupBoxState.Large;
            this.ScaleIntermediate = 0;
            this.ClearCache();

            this.ResetScaleableItems();

            this.UpdateScalableControlSubscritions(true);
            return true;
        }

        ///
        /// Tries to clear the cache, reset the state and reset the scale.
        /// If that succeeds the parent <see cref="RibbonGroupsContainer"/> is notified about that.
        ///
        /// <returns><c>true</c> if the cache was reset. Otherwise <c>false</c>.</returns>
        public bool TryClearCacheAndResetStateAndScaleAndNotifyParentRibbonGroupsContainer()
        {
            // We should try to clear the entire cache.
            // The entire cache should only be cleared if we don't do regular measuring, but only if some event outside our own measuring code caused size changes (such as elements getting visible/invisible or being added/removed).
            // For reference https://github.com/fluentribbon/Fluent.Ribbon/issues/834
            if (this.TryClearCacheAndResetStateAndScale())
            {
                UIHelper.GetParent<RibbonGroupsContainer>(this)?.GroupBoxCacheClearedAndStateAndScaleResetted(this);
                return true;
            }

            return false;
        }

        ///
        /// Clears cache
        ///
        public void ClearCache()
        {
            this.cachedMeasures.Clear();
        }

        ///
        /// Invalidates layout (with children)
        ///
        internal void InvalidateLayout()
        {
            InvalidateMeasureRecursive(this);
        }

        private static void InvalidateMeasureRecursive(UIElement element)
        {
            if (element is null)
            {
                return;
            }

            element.InvalidateMeasure();

            for (var i = 0; i < VisualTreeHelper.GetChildrenCount(element); i++)
            {
                var child = VisualTreeHelper.GetChild(element, i) as UIElement;

                if (child is null)
                {
                    continue;
                }

                InvalidateMeasureRecursive(child);
            }
        }

        #endregion

        #region Overrides

        /// <inheritdoc />
        public override void OnApplyTemplate()
        {
            this.UnSubscribeEvents();

            // Clear cache
            this.ClearCache();

            this.HeaderContentControl = this.GetTemplateChild("PART_HeaderContentControl") as ContentControl;
            this.CollapsedHeaderContentControl = this.GetTemplateChild("PART_CollapsedHeaderContentControl") as ContentControl;

            this.LauncherButton = this.GetTemplateChild("PART_DialogLauncherButton") as Button;

            if (this.LauncherButton != null)
            {
                if (this.LauncherKeys != null)
                {
                    this.LauncherButton.KeyTip = this.LauncherKeys;
                }
            }

            this.DropDownPopup = this.GetTemplateChild("PART_Popup") as Popup;

            this.upPanel = this.GetTemplateChild("PART_UpPanel") as Panel;
            this.parentPanel = this.GetTemplateChild("PART_ParentPanel") as Panel;

            this.snappedImage = this.GetTemplateChild("PART_SnappedImage") as Image;

            this.SubscribeEvents();
        }

        private void OnPopupOpened(object sender, EventArgs e)
        {
            this.DropDownOpened?.Invoke(this, e);
        }

        private void OnPopupClosed(object sender, EventArgs e)
        {
            this.DropDownClosed?.Invoke(this, e);
        }

        /// <inheritdoc />
        protected override void OnItemsChanged(NotifyCollectionChangedEventArgs e)
        {
            base.OnItemsChanged(e);

            this.TryClearCacheAndResetStateAndScaleAndNotifyParentRibbonGroupsContainer();
        }

        /// <inheritdoc />
        protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e)
        {
            if (ReferenceEquals(e.Source, this) == false
                || this.DropDownPopup is null)
            {
                return;
            }

            if (this.State == RibbonGroupBoxState.Collapsed
                || this.State == RibbonGroupBoxState.QuickAccess)
            {
                e.Handled = true;

                if (!this.IsDropDownOpen)
                {
                    this.IsDropDownOpen = true;
                }
                else
                {
                    PopupService.RaiseDismissPopupEventAsync(this, DismissPopupMode.MouseNotOver);
                }
            }
        }

        /// <inheritdoc />
        protected override void OnChildDesiredSizeChanged(UIElement child)
        {
            base.OnChildDesiredSizeChanged(child);

            // We must always clear the current cached measure.
            this.cachedMeasures.Remove(this.GetCurrentIntermediateStateScale());
        }

        private StateScale GetCurrentIntermediateStateScale()
        {
            var stateScale = new StateScale
            {
                Scale = this.ScaleIntermediate,
                State = this.StateIntermediate
            };
            return stateScale;
        }

        #endregion

        #region Event Handling

        ///
        /// Dialog launcher button click handler
        ///
        /// <param name="sender">Sender</param>
        /// <param name="e">the event data</param>
        private void OnDialogLauncherButtonClick(object sender, RoutedEventArgs e)
        {
            this.LauncherClick?.Invoke(this, e);
        }

        ///
        /// Handles IsOpen propertyu changes
        ///
        /// <param name="d">Object</param>
        /// <param name="e">The event data</param>
        private static void OnIsDropDownOpenChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var groupBox = (RibbonGroupBox)d;

            var oldValue = (bool)e.OldValue;
            var newValue = (bool)e.NewValue;

            groupBox.OnIsDropDownOpenChanged();

            (UIElementAutomationPeer.FromElement(groupBox) as Fluent.Automation.Peers.RibbonGroupBoxAutomationPeer)?.RaiseExpandCollapseAutomationEvent(oldValue, newValue);
        }

        private void OnIsDropDownOpenChanged()
        {
            if (this.IsDropDownOpen)
            {
                this.OnRibbonGroupBoxPopupOpening();
            }
            else
            {
                this.OnRibbonGroupBoxPopupClosing();
            }
        }

        // Handles popup closing
        private void OnRibbonGroupBoxPopupClosing()
        {
            //IsHitTestVisible = true;
            if (ReferenceEquals(Mouse.Captured, this))
            {
                Mouse.Capture(null);
            }
        }

        // handles popup opening
        private void OnRibbonGroupBoxPopupOpening()
        {
            //IsHitTestVisible = false;
            Mouse.Capture(this, CaptureMode.SubTree);
        }

        #endregion

        #region Quick Access Item Creating

        /// <inheritdoc />
        public virtual FrameworkElement CreateQuickAccessItem()
        {
            var groupBox = new RibbonGroupBox();

            RibbonControl.BindQuickAccessItem(this, groupBox);

            groupBox.DropDownOpened += this.OnQuickAccessOpened;
            groupBox.DropDownClosed += this.OnQuickAccessClosed;

            groupBox.State = RibbonGroupBoxState.QuickAccess;

            RibbonControl.Bind(this, groupBox, nameof(this.ItemTemplateSelector), ItemTemplateSelectorProperty, BindingMode.OneWay);
            RibbonControl.Bind(this, groupBox, nameof(this.ItemTemplate), ItemTemplateProperty, BindingMode.OneWay);
            RibbonControl.Bind(this, groupBox, nameof(this.ItemsSource), ItemsSourceProperty, BindingMode.OneWay);
            RibbonControl.Bind(this, groupBox, nameof(this.LauncherCommandParameter), LauncherCommandParameterProperty, BindingMode.OneWay);
            RibbonControl.Bind(this, groupBox, nameof(this.LauncherCommand), LauncherCommandProperty, BindingMode.OneWay);
            RibbonControl.Bind(this, groupBox, nameof(this.LauncherCommandTarget), LauncherCommandTargetProperty, BindingMode.OneWay);
            RibbonControl.Bind(this, groupBox, nameof(this.LauncherIcon), LauncherIconProperty, BindingMode.OneWay);
            RibbonControl.Bind(this, groupBox, nameof(this.LauncherText), LauncherTextProperty, BindingMode.OneWay);
            RibbonControl.Bind(this, groupBox, nameof(this.LauncherToolTip), LauncherToolTipProperty, BindingMode.OneWay);
            RibbonControl.Bind(this, groupBox, nameof(this.IsLauncherEnabled), IsLauncherEnabledProperty, BindingMode.OneWay);
            RibbonControl.Bind(this, groupBox, nameof(this.IsLauncherVisible), IsLauncherVisibleProperty, BindingMode.OneWay);
            RibbonControl.Bind(this, groupBox, nameof(this.LauncherKeys), LauncherKeysProperty, BindingMode.OneWay);
            groupBox.LauncherClick += this.LauncherClick;

            if (this.Icon != null)
            {
                if (this.Icon is Visual iconVisual)
                {
                    var rect = new Rectangle
                    {
                        Width = 16,
                        Height = 16,
                        Fill = new VisualBrush(iconVisual)
                    };
                    groupBox.Icon = rect;
                }
                else
                {
                    RibbonControl.Bind(this, groupBox, nameof(this.Icon), RibbonControl.IconProperty, BindingMode.OneWay);
                }
            }

            return groupBox;
        }

        private void OnQuickAccessOpened(object sender, EventArgs e)
        {
            if (this.IsDropDownOpen == false
                && this.IsSnapped == false)
            {
                var groupBox = (RibbonGroupBox)sender;
                // Save state
                this.IsSnapped = true;

                if (this.ItemsSource is null)
                {
                    for (var i = 0; i < this.Items.Count; i++)
                    {
                        var item = this.Items[0];
                        this.Items.Remove(item);
                        groupBox.Items.Add(item);
                        i--;
                    }
                }
            }
        }

        private void OnQuickAccessClosed(object sender, EventArgs e)
        {
            var groupBox = (RibbonGroupBox)sender;

            if (this.ItemsSource is null)
            {
                for (var i = 0; i < groupBox.Items.Count; i++)
                {
                    var item = groupBox.Items[0];
                    groupBox.Items.Remove(item);
                    this.Items.Add(item);
                    i--;
                }
            }

            this.IsSnapped = false;
        }

        /// <inheritdoc />
        public bool CanAddToQuickAccessToolBar
        {
            get { return (bool)this.GetValue(CanAddToQuickAccessToolBarProperty); }
            set { this.SetValue(CanAddToQuickAccessToolBarProperty, value); }
        }

        /// Identifies the <see cref="CanAddToQuickAccessToolBar"/> dependency property.
        public static readonly DependencyProperty CanAddToQuickAccessToolBarProperty =
            DependencyProperty.Register(nameof(CanAddToQuickAccessToolBar), typeof(bool), typeof(RibbonGroupBox), new PropertyMetadata(BooleanBoxes.TrueBox, RibbonControl.OnCanAddToQuickAccessToolBarChanged));

        #endregion

        #region Implementation of IKeyTipedControl

        /// <inheritdoc />
        public KeyTipPressedResult OnKeyTipPressed()
        {
            if (this.State == RibbonGroupBoxState.Collapsed
                || this.State == RibbonGroupBoxState.QuickAccess)
            {
                this.IsDropDownOpen = true;

                if (this.DropDownPopup?.Child != null)
                {
                    Keyboard.Focus(this.DropDownPopup.Child);
                    this.DropDownPopup.Child.MoveFocus(new TraversalRequest(FocusNavigationDirection.First));

                    return new KeyTipPressedResult(true, true);
                }

                return new KeyTipPressedResult(false, true);
            }

            return KeyTipPressedResult.Empty;
        }

        /// <inheritdoc />
        public void OnKeyTipBack()
        {
            this.IsDropDownOpen = false;
        }

        #endregion

        /// <inheritdoc />
        void ILogicalChildSupport.AddLogicalChild(object child)
        {
            this.AddLogicalChild(child);
        }

        /// <inheritdoc />
        void ILogicalChildSupport.RemoveLogicalChild(object child)
        {
            this.RemoveLogicalChild(child);
        }

        /// <inheritdoc />
        protected override IEnumerator LogicalChildren
        {
            get
            {
                var baseEnumerator = base.LogicalChildren;
                while (baseEnumerator?.MoveNext() == true)
                {
                    yield return baseEnumerator.Current;
                }

                if (this.Icon != null)
                {
                    yield return this.Icon;
                }

                if (this.LauncherIcon != null)
                {
                    yield return this.LauncherIcon;
                }
            }
        }

        /// <inheritdoc />
        protected override AutomationPeer OnCreateAutomationPeer() => new Fluent.Automation.Peers.RibbonGroupBoxAutomationPeer(this);
    }
}


text:
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

@import url(chrome://global/skin/);

@namespace html "http://www.w3.org/1999/xhtml";

#qa-pass {
  background: #99ff99;
  display: none;
}

/*-------------------------------
               HTML
  -------------------------------*/

#qa_tabbox html|ul, #qa_tabbox html|ol {
  margin: 0;
  padding: 0;
}
#qa_tabbox html|ul li {
  list-style-type: square;
  margin-bottom: 0.4em;
}

#qa_tabbox html|a,
#qa_tabbox html|a:link,
#qa_tabbox html|a:visited {
  font-weight: bold;
  color: #0067ac;
}
#qa_tabbox html|a:focus,
#qa_tabbox html|a:hover,
#qa_tabbox html|a:active {
  color: #333;
}
/*remove bullets for everything but lists contained inside testcase data */
html|li {
  list-style-type: none !important;
}
#qa-tab-litmus html|ul html|li {
	list-style-type: disc !important;
}
#qa-tab-litmus html|ol html|li {
	list-style-type: decimal !important;
}

#qa-tab-litmus html|ul, #qa-tab-litmus html|ol {
	padding-left: 20px;
}

/*-------------------------------
               TABS
  -------------------------------*/
#qa_tabbox #qa_tabrow {
  height: 30px !important;
  padding-top: 5px !important;
}

#qa_tabbox .tab-icon-image {
  list-style-image: none;
  width: 0;
}

#qa_tabbox #qa-tabbar-qmo {
  list-style-image: url(qmo-16px.png);
  text-align: right;
  width: 24px;
}

#qa_tabbox #qa-tabbar-spacer {
  width: 93px;
}

#qa_tabbox tab, #qa_tabbox tabs spacer {
  border-bottom: 1px solid #ACA899 !important;
}

.tabs-left, .tabs-right {
  -moz-border-bottom-colors: #ACA899 !important;
}

#qa_tabbox tab[selected="true"] {
  border-bottom: 1px solid #E8E5D8 !important;
}

tabs {
  border-bottom: 1px solid #E8E5D8;
}

.tab-close-button {
    display: none !important;
}

.tabbrowser-tab.highlight > .tab-image-right {
	background: url("chrome://qa/skin/highlight-start.png") no-repeat !important;
}
.tabbrowser-tab.highlight > .tab-image-left {
	background: url("chrome://qa/skin/highlight-end.png") no-repeat !important;
}
.tabbrowser-tab.highlight > .tab-image-middle {
	background: url("chrome://qa/skin/highlight-mid.png") repeat-x !important;
}

.tabbrowser-tab.highlight:hover > .tab-image-right {
	background: url("chrome://qa/skin/highlight-hover-start.png") no-repeat !important;
}
.tabbrowser-tab.highlight:hover > .tab-image-left {
	background: url("chrome://qa/skin/highlight-hover-end.png") no-repeat !important;
}
.tabbrowser-tab.highlight:hover > .tab-image-middle {
	background: url("chrome://qa/skin/highlight-hover-mid.png") repeat-x !important;
}

/* don't show outline around the middle of selected tabs */
tab:focus > .tab-middle {
  outline: 1px none invert !important;
}

/*-------------------------------
               PANELS
  -------------------------------*/
#qa_tabbox tabpanel {
  line-height: 1.6;
  background-color: white;
}

#qa_tabbox tabpanels {
  background-color: white;
  border-top: 1px solid #ACA899;
  margin-top: 0px;
}

#qa_tabbox groupbox {
  background-color: white;
}
#qa_tabbox caption {
  font: bold 12px helvetica, arial, sans-serif;
  color: #ec891d;
  background-color: white;
  padding: 0;
}

#qa-qmo-help,
#qa-qmo-events,
#qa-qmo-forumposts,
.box-mheight {
}

#qa-qmo-latestbox,
#qa-qmo-latest {

}

/*-------------------------------
               NOTIFY
  -------------------------------*/

#qa-notify {
  right: 18px;
  bottom: 21px;
  position: fixed;
  border: 1px solid grey;
  background-color: white;
  background-image: url("logolight.png");
  background-repeat: no-repeat;
  background-position: center;
}

.qa-notify {
  height: 140px;
  width: 420px;
}

#qa-notify-box {
  padding: 0px 6px 6px 6px;
	display: table;
}

#qa-notify-header {
  font-size: 1.5em;
  font-weight: bold;
}

/*-------------------------------
               GENERAL
  -------------------------------*/

.list {
  padding-left: 10px;
}

redpajama_set_name: RedPajamaGithub


text:
/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

app.controller("AllContentController", function ($scope, $http) {

    var status = "Approved";
    $scope.contents = [];

    $scope.content_id = '';

    $http.get("http://localhost:8086/contents/status/" + status).then(function (response) {
        $scope.contents = response.data;
    });

    function refreshApprovedContents() {
        $http.get("http://localhost:8086/contents/status/" + status).then(function (response) {
            $scope.contents = response.data;
        });
    }

    $scope.resetPayment = function(){
        $scope.payment_method = '';
        $scope.payment_date = '';
        $scope.payment_amount = '';
        $scope.reference_no = '';
    };

    $scope.deleteContent = function (ID) {
        if (confirm("Are you sure you want to delete this ad content?")) {
            var delContent = ID;

            $http.delete("http://localhost:8086/contents/" + delContent).then(function (response) {
                alert("Ad Content Deleted Successfully!");
                refreshApprovedContents();
            }, function (response) {
                alert("Ad Content Deleting Failed !");
            });
        }
    };

    $scope.promoteContent = function (ID) {
        $scope.content_id = ID;

        var newStatus = {
            Status: "Promoted"

        };

        $http.put("http://localhost:8086/contents/" + $scope.content_id, newStatus).then(function (response) {

            alert("Content has been promoted! Please insert the payment information below");
            refreshApprovedContents();
        }, function (response) {
            alert("Promoting Content Failed!");
        });
    };

    $scope.confirmPayment = function () {

        $scope.payments = [];

        var newPayment = {
            ContentID: $scope.content_id,
            Method: $scope.payment_method,
            Date: $scope.payment_date,
            Amount: $scope.payment_amount,
            ReferenceNo: $scope.reference_no
        };
        console.log(newPayment)
        if (confirm("Are you sure you want to add a payment to content of ID " + $scope.content_id)) {

            if (newPayment.Method != null && newPayment.Date != 'mm/dd/yyyy' && newPayment.Amount != null && newPayment.ReferenceNo != null) {
                $http.post("http://localhost:8086/payments", newPayment).then(function (response) {
                    alert("Payment Added Successfully!");
                    refreshApprovedContents();
                    $scope.resetPayment();
                }, function (response) {
                    alert("Payment Adding Failed !");
                });
            } else {
                alert("Inputs are not valid !");
            }
        }
    };
});


text: export { default } from 'ember-fhir/models/operation-definition';


text:
echo building CentOS container with BigFix agent
# build docker image with the evaluation edition of BigFix server (besserver)
cd /vagrant/besclient/CentOS7

# start a docker container running BigFix server (besserver)
/usr/local/bin/docker-compose up -d


text:
package org.apache.kafka.clients.consumer.internals;

import java.io.Serializable;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import org.apache.kafka.common.TopicPartition;

final class Utils {

    final static class PartitionComparator implements Comparator<TopicPartition>, Serializable {
        private static final long serialVersionUID = 1L;
        private Map<String, List<String>> map;

        PartitionComparator(Map<String, List<String>> map) {
            this.map = map;
        }

        @Override
        public int compare(TopicPartition o1, TopicPartition o2) {
            int ret = map.get(o1.topic()).size() - map.get(o2.topic()).size();
            if (ret == 0) {
                ret = o1.topic().compareTo(o2.topic());
                if (ret == 0)
                    ret = o1.partition() - o2.partition();
            }
            return ret;
        }
    }

    final static class TopicPartitionComparator implements Comparator<TopicPartition>, Serializable {
        private static final long serialVersionUID = 1L;

        @Override
        public int compare(TopicPartition topicPartition1, TopicPartition topicPartition2) {
            String topic1 = topicPartition1.topic();
            String topic2 = topicPartition2.topic();

            if (topic1.equals(topic2)) {
                return topicPartition1.partition() - topicPartition2.partition();
            } else {
                return topic1.compareTo(topic2);
            }
        }
    }
}


text:
function unsubscribe(data, next) {

    if(data.roomId  === undefined)
        return this.clientError('Missing roomId in data packet');

    var room = this._server.getRoom(data.roomId);
    var i = this._rooms.indexOf(room);
    if(i !== -1) {
        room.removeSession(this);
        this._rooms.splice(i,1);
    }
    if (room.isEmpty())
        delete this._server._rooms[data.roomId];

    this.clientOkay();
    return next();
};

module.exports = [unsubscribe];


text:
@class ZKUserInfo;

@interface ZKServerSwitchboard : NSObject {
    CFMutableDictionaryRef connections;
    CFMutableDictionaryRef connectionsData;

    NSString    *apiUrl;

	NSString	*clientId;
	NSString	*sessionId;
    NSString    *oAuthRefreshToken;
	NSDate		*sessionExpiry;
    ZKUserInfo	*userInfo;
	NSUInteger  preferredApiVersion;

    BOOL        updatesMostRecentlyUsed;
    BOOL        logXMLInOut;

@private
    NSString    *_username;
    NSString    *_password;

    NSTimer     *_oAuthRefreshTimer;
}

@property (nonatomic, copy) NSString *apiUrl;
@property (nonatomic, copy) NSString *clientId;
@property (nonatomic, copy) NSString *sessionId;
@property (nonatomic, copy) NSString *oAuthRefreshToken;
@property (nonatomic, retain) ZKUserInfo *userInfo;
@property (nonatomic, assign) BOOL updatesMostRecentlyUsed;
@property (nonatomic, assign) BOOL logXMLInOut;

+ (NSString *)baseURL;
+ (ZKServerSwitchboard *)switchboard;
- (NSString *)authenticationUrl;

- (void)setApiUrlFromOAuthInstanceUrl:(NSString *)instanceUrl;
- (void)loginWithUsername:(NSString *)username password:(NSString *)password target:(id)target selector:(SEL)selector;

// Convenience methods that should only really be called from within ZKServerSwitchboard methods
// They're public because categories on ZKServerSwitchboard might need access to them
- (NSDictionary *)contextWrapperDictionaryForTarget:(id)target selector:(SEL)selector context:(id)context;
- (void)unwrapContext:(NSDictionary *)wrapperContext andCallSelectorWithResponse:(id)response error:(NSError *)error;

// Core Calls
- (void)create:(NSArray *)objects target:(id)target selector:(SEL)selector context:(id)context;
- (void)delete:(NSArray *)objectIDs target:(id)target selector:(SEL)selector context:(id)context;
- (void)getDeleted:(NSString *)sObjectType fromDate:(NSDate *)startDate toDate:(NSDate *)endDate target:(id)target selector:(SEL)selector context:(id)context;
- (void)getUpdated:(NSString *)sObjectType fromDate:(NSDate *)startDate toDate:(NSDate *)endDate target:(id)target selector:(SEL)selector context:(id)context;
- (void)query:(NSString *)soqlQuery target:(id)target selector:(SEL)selector context:(id)context;
- (void)queryAll:(NSString *)soqlQuery target:(id)target selector:(SEL)selector context:(id)context;
- (void)queryMore:(NSString *)queryLocator target:(id)target selector:(SEL)selector context:(id)context;
- (void)search:(NSString *)soqlQuery target:(id)target selector:(SEL)selector context:(id)context;
- (void)unDelete:(NSArray *)objectIDs target:(id)target selector:(SEL)selector context:(id)context;
- (void)update:(NSArray *)objects target:(id)target selector:(SEL)selector context:(id)context;

// Apex Calls
- (void)sendApexRequestToURL:(NSString *)webServiceLocation
                    withData:(NSString *)payload
                      target:(id)target
                    selector:(SEL)sel
                     context:(id)context;

@end


text:
"""Launch definitions for paper experiments."""
from typing import Tuple, Dict, Any, Optional

import ml_collections as collections

import experiments.experiment_utils as cpeutils

def get_parameters(
    experiment: str,
    sub_experiment: str,
    config: collections.ConfigDict,
) -> Tuple[collections.ConfigDict, Optional[Dict[str, Any]]]:
  """Get parameters for Fashion-MNIST experiments.

  Args:
    experiment: experiment to run
    sub_experiment: sub experiment, e.g., parameter to tune
    config: experiment configuration

  Returns:
    Training configuration and parameter sweeps
  """
  config.architecture = 'mlp'
  config.mlp.layers = 2
  config.cnn.channels = 128
  config.resnet.version = 18
  parameter_sweep = None

  if experiment == 'models':
    config.learning_rate = 0.05
    config.batch_size = 100
  elif experiment == 'conformal':
    config.mode = 'conformal'
    config.conformal.coverage_loss = 'none'
    config.conformal.loss_transform = 'log'
    config.conformal.size_transform = 'identity'
    config.conformal.rng = False

    if sub_experiment == 'training':
      config.learning_rate = 0.01
      config.batch_size = 100
      config.conformal.temperature = 0.1
      config.conformal.size_loss = 'normal'
      config.conformal.method = 'threshold_logp'
      config.conformal.size_weight = 0.01
    elif sub_experiment == 'confusion_4_6':
      config.learning_rate = 0.01
      config.batch_size = 100
      config.conformal.temperature = 0.1
      config.conformal.coverage_loss = 'classification'
      config.conformal.size_loss = 'valid'
      config.conformal.method = 'threshold_logp'
      config.conformal.size_weight = 0.5

      parameter_sweep = {
          'key': 'conformal.loss_matrix',
          'values': [
              cpeutils.loss_matrix_confusion(4, 6, 0.01, 0.01, 1, 10),
              cpeutils.loss_matrix_confusion(4, 6, 0.05, 0.05, 1, 10),
              cpeutils.loss_matrix_confusion(4, 6, 0.1, 0.1, 1, 10),
              cpeutils.loss_matrix_confusion(4, 6, 0.5, 0.5, 1, 10),
              cpeutils.loss_matrix_confusion(4, 6, 1, 1, 1, 10),
          ],
      }
    elif sub_experiment == 'confusion_2_4_6':
      config.learning_rate = 0.01
      config.batch_size = 100
      config.conformal.temperature = 0.1
      config.conformal.coverage_loss = 'classification'
      config.conformal.size_loss = 'valid'
      config.conformal.method = 'threshold_logp'
      config.conformal.size_weight = 0.5

      parameter_sweep = {
          'key': 'conformal.loss_matrix',
          'values': [
              cpeutils.loss_matrix_confusion_triple(2, 4, 6, 0.01, 1, 10),
              cpeutils.loss_matrix_confusion_triple(2, 4, 6, 0.05, 1, 10),
              cpeutils.loss_matrix_confusion_triple(2, 4, 6, 0.1, 1, 10),
              cpeutils.loss_matrix_confusion_triple(2, 4, 6, 0.5, 1, 10),
              cpeutils.loss_matrix_confusion_triple(2, 4, 6, 1, 1, 10),
          ],
      }
    elif sub_experiment == 'confusion_6':
      config.learning_rate = 0.01
      config.batch_size = 100
      config.conformal.temperature = 0.1
      config.conformal.coverage_loss = 'classification'
      config.conformal.size_loss = 'valid'
      config.conformal.method = 'threshold_logp'
      config.conformal.size_weight = 0.5

      parameter_sweep = {
          'key': 'conformal.loss_matrix',
          'values': [
              cpeutils.loss_matrix_confusion_row(6, 0.01, 1, 10),
              cpeutils.loss_matrix_confusion_row(6, 0.05, 1, 10),
              cpeutils.loss_matrix_confusion_row(6, 0.1, 1, 10),
              cpeutils.loss_matrix_confusion_row(6, 0.5, 1, 10),
              cpeutils.loss_matrix_confusion_row(6, 1, 1, 10),
          ],
      }
    else:
      raise ValueError('Invalid conformal sub experiment.')
  else:
    raise ValueError('Experiment not implemented.')
  return config, parameter_sweep


text:
package org.chromium.build;

import com.android.tools.r8.CompilationFailedException;
import com.android.tools.r8.D8;
import com.android.tools.r8.D8Command;
import com.android.tools.r8.DesugarGraphConsumer;
import com.android.tools.r8.origin.Origin;
import com.android.tools.r8.utils.FlagFile;

import java.io.IOException;
import java.io.PrintWriter;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class CustomD8 {
    private static class CommandLineOrigin extends Origin {
        private CommandLineOrigin() {
            super(root());
        }

        @Override
        public String part() {
            return "Command line";
        }
    }

    private static String parseAndRemoveArg(List<String> args, String name)
            throws CompilationFailedException {
        int idx = args.indexOf(name);
        if (idx == -1) {
            return null;
        }
        if (idx == args.size() - 1) {
            throw new CompilationFailedException("Missing argument to '" + name + "'");
        }
        String value = args.get(idx + 1);
        args.subList(idx, idx + 2).clear();
        return value;
    }

    // Entry point for D8 compilation with support for --desugar-dependencies option
    // as well.
    public static void main(String[] args) throws CompilationFailedException, IOException {
        // Need to expand argfile arg in case our custom command line args are in the file.
        String[] expandedArgs = FlagFile.expandFlagFiles(args, null);
        List<String> argList = new ArrayList<>(Arrays.asList(expandedArgs));
        String desugarDependenciesPath = parseAndRemoveArg(argList, "--desugar-dependencies");
        String fileTmpPrefix = parseAndRemoveArg(argList, "--file-tmp-prefix");

        // Use D8 command line parser to handle the normal D8 command line.
        D8Command.Builder builder =
                D8Command.parse(argList.toArray(new String[0]), new CommandLineOrigin());

        if (desugarDependenciesPath != null) {
            final Path desugarDependencies = Paths.get(desugarDependenciesPath);
            PrintWriter desugarDependenciesPrintWriter =
                    new PrintWriter(Files.newOutputStream(desugarDependencies));
            if (builder.getDesugarGraphConsumer() != null) {
                throw new CompilationFailedException("Too many desugar graph consumers.");
            }
            builder.setDesugarGraphConsumer(new DesugarGraphConsumer() {
                private String formatOrigin(Origin origin) {
                    String path = origin.toString();
                    // Class files are extracted to a temporary directory for incremental dexing.
                    // Remove the prefix of the path corresponding to the temporary directory so
                    // that these paths are consistent between builds.
                    if (fileTmpPrefix != null && path.startsWith(fileTmpPrefix)) {
                        return path.substring(fileTmpPrefix.length());
                    }
                    return path;
                }

                @Override
                public void accept(Origin dependent, Origin dependency) {
                    String dependentPath = formatOrigin(dependent);
                    String dependencyPath = formatOrigin(dependency);
                    synchronized (desugarDependenciesPrintWriter) {
                        desugarDependenciesPrintWriter.println(
                                dependentPath + " -> " + dependencyPath);
                    }
                }

                @Override
                public void finished() {
                    desugarDependenciesPrintWriter.close();
                }
            });
        }

        // Run D8.
        D8.run(builder.build());
    }
}


text:
/*
 *  * Utility Functions
 *   */
exports.setDebug = function(val) {
        debug = !! val;
};

exports.isDebug = function() {
        return debug;
};

exports.dateToArray = function(dateObj) {
        if (typeof dateObj !== 'object')
                dateObj = new Date(dateObj);
        return [
                dateObj.getFullYear(),
                dateObj.getMonth() + 1,
                dateObj.getDate(),
                dateObj.getHours(),
                dateObj.getMinutes(),
                dateObj.getSeconds()
        ];
};


text:
<TS language="de_DE" version="2.1">
<context>
    <name>AddressBookPage</name>
    <message>
        <source>Right-click to edit address or label</source>
        <translation>Rechtsklick um Adresse oder Etikett zu bearbeiten</translation>
    </message>
    <message>
        <source>Create a new address</source>
        <translation>Eine neue Adresse erstellen</translation>
    </message>
    <message>
        <source>&New</source>
        <translation>&Neu</translation>
    </message>
    <message>
        <source>Copy the currently selected address to the system clipboard</source>
        <translation>Ausgewählte Adresse in die Zwischenablage kopieren</translation>
    </message>
    <message>
        <source>&Copy</source>
        <translation>&Kopieren</translation>
    </message>
    <message>
        <source>C&lose</source>
        <translation>Schliessen</translation>
    </message>
    <message>
        <source>Delete the currently selected address from the list</source>
        <translation>Ausgewählte Adresse aus der Liste löschen</translation>
    </message>
    <message>
        <source>Export the data in the current tab to a file</source>
        <translation>Daten des aktiven Fensters exportieren</translation>
    </message>
    <message>
        <source>&Export</source>
        <translation>&Exportieren</translation>
    </message>
    <message>
        <source>&Delete</source>
        <translation>&Löschen</translation>
    </message>
    <message>
        <source>Choose the address to send coins to</source>
        <translation>Wähle die Empfängeradresse</translation>
    </message>
    <message>
        <source>Choose the address to receive coins with</source>
        <translation>Wähle die Empfangsadresse</translation>
    </message>
    <message>
        <source>C&hoose</source>
        <translation>Dies sind deine Litecoin Adressen zum Senden von Zahlungsmitteln.
Überprüfe immer die Menge, sowie die Empfänger-Adresse vor dem Senden von Coins.</translation>
    </message>
    <message>
        <source>Sending addresses</source>
        <translation>Sendeadresse</translation>
    </message>
    <message>
        <source>Receiving addresses</source>
        <translation>Empfangsadresse</translation>
    </message>
    <message>
        <source>&Copy Address</source>
        <translation>&Kopiere Adresse</translation>
    </message>
    <message>
        <source>Copy &Label</source>
        <translation>Kopiere &Etikett</translation>
    </message>
    <message>
        <source>&Edit</source>
        <translation>&Bearbeiten</translation>
    </message>
    <message>
        <source>Export Address List</source>
        <translation>Export Adressliste</translation>
    </message>
    <message>
        <source>Comma separated file (*.csv)</source>
        <translation>Komma getrenntes Dokument (*.csv)</translation>
    </message>
    <message>
        <source>Exporting Failed</source>
        <translation>Export fehlgeschlagen</translation>
    </message>
    </context>
<context>
    <name>AddressTableModel</name>
    <message>
        <source>Label</source>
        <translation>Etikett</translation>
    </message>
    <message>
        <source>Address</source>
        <translation>Adresse</translation>
    </message>
    <message>
        <source>(no label)</source>
        <translation>(kein Etikett)</translation>
    </message>
</context>
<context>
    <name>AskPassphraseDialog</name>
    <message>
        <source>Passphrase Dialog</source>
        <translation>Passwort Dialog</translation>
    </message>
    <message>
        <source>Enter passphrase</source>
        <translation>Passwort eingeben</translation>
    </message>
    <message>
        <source>New passphrase</source>
        <translation>Neues Passwort</translation>
    </message>
    <message>
        <source>Repeat new passphrase</source>
        <translation>Neues Passwort wiederholen</translation>
    </message>
    <message>
        <source>Encrypt wallet</source>
        <translation>Brieftasche verschlüsseln</translation>
    </message>
    <message>
        <source>This operation needs your wallet passphrase to unlock the wallet.</source>
        <translation>Diese Aktion benötigt ihr Passwort zum entsperren der Wallet.</translation>
    </message>
    <message>
        <source>Unlock wallet</source>
        <translation>Brieftasche entriegeln</translation>
    </message>
    <message>
        <source>Decrypt wallet</source>
        <translation>Brieftasche entschlüsseln</translation>
    </message>
    <message>
        <source>Change passphrase</source>
        <translation>Passwort ändern</translation>
    </message>
    <message>
        <source>Confirm wallet encryption</source>
        <translation>Brieftaschenverschlüsselung bestätigen</translation>
    </message>
    <message>
        <source>Wallet encrypted</source>
        <translation>Brieftasche verschlüsselt</translation>
    </message>
    <message>
        <source>Wallet encryption failed</source>
        <translation>Brieftaschenverschlüsselung fehlgeschlagen</translation>
    </message>
    <message>
        <source>Wallet unlock failed</source>
        <translation>Brieftasche öffnen fehlgeschlagen</translation>
    </message>
    <message>
        <source>The passphrase entered for the wallet decryption was incorrect.</source>
        <translation>Inkorrektes Passwort um die Brieftasche zu entschlüsseln</translation>
    </message>
    <message>
        <source>Wallet decryption failed</source>
        <translation>Brieftasche entschlüsseln fehlgeschlagen</translation>
    </message>
    <message>
        <source>Wallet passphrase was successfully changed.</source>
        <translation>Brieftaschen Passwort erfolgreich geändert</translation>
    </message>
    <message>
        <source>Warning: The Caps Lock key is on!</source>
        <translation>Achtung: Die Umschalttaste ist eingeschaltet!</translation>
    </message>
</context>
<context>
    <name>BanTableModel</name>
    <message>
        <source>IP/Netmask</source>
        <translation>IP/Netzmaske</translation>
    </message>
    <message>
        <source>Banned Until</source>
        <translation>Gesperrt bis</translation>
    </message>
</context>
<context>
    <name>BitcoinGUI</name>
    <message>
        <source>Synchronizing with network...</source>
        <translation>Über das Netzwerk abgleichen...</translation>
    </message>
    <message>
        <source>&Overview</source>
        <translation>&Übersicht</translation>
    </message>
    <message>
        <source>Node</source>
        <translation>Knoten</translation>
    </message>
    <message>
        <source>Show general overview of wallet</source>
        <translation>Generelle Übersicht der Brieftasche </translation>
    </message>
    <message>
        <source>&Transactions</source>
        <translation>&Transaktionen</translation>
    </message>
    <message>
        <source>Browse transaction history</source>
        <translation>Zeige Transaktionsverlauf</translation>
    </message>
    <message>
        <source>Quit application</source>
        <translation>Programm beenden</translation>
    </message>
    <message>
        <source>&Options...</source>
        <translation>&Einstellungen...</translation>
    </message>
    <message>
        <source>&Encrypt Wallet...</source>
        <translation>&Brieftasche verschlüsseln...</translation>
    </message>
    <message>
        <source>&Backup Wallet...</source>
        <translation>&Sicherungskopie der Brieftasche...</translation>
    </message>
    <message>
        <source>&Change Passphrase...</source>
        <translation>&Passwort ändern...</translation>
    </message>
    <message>
        <source>&Sending addresses...</source>
        <translation>&Adressen senden...</translation>
    </message>
    <message>
        <source>&Receiving addresses...</source>
        <translation>&Adressen empfangen...</translation>
    </message>
    <message>
        <source>Wallet</source>
        <translation>Brieftasche</translation>
    </message>
    <message>
        <source>&Send</source>
        <translation>&Senden</translation>
    </message>
    <message>
        <source>&Receive</source>
        <translation>&Empfangen</translation>
    </message>
    <message>
        <source>&Settings</source>
        <translation>&Einstellungen</translation>
    </message>
    <message>
        <source>&Help</source>
        <translation>&Hilfe</translation>
    </message>
    <message>
        <source>Show the list of used sending addresses and labels</source>
        <translation>Zeige Liste der benutzten Sendeadressen und -etiketten</translation>
    </message>
    <message>
        <source>Error</source>
        <translation>Fehler</translation>
    </message>
    <message>
        <source>Warning</source>
        <translation>Achtung</translation>
    </message>
    <message>
        <source>Information</source>
        <translation>Information</translation>
    </message>
    <message>
        <source>Sent transaction</source>
        <translation>Überweisung gesendet</translation>
    </message>
    <message>
        <source>Incoming transaction</source>
        <translation>Überweisung empfangen</translation>
    </message>
    </context>
<context>
    <name>CoinControlDialog</name>
    <message>
        <source>Date</source>
        <translation>Datum</translation>
    </message>
    <message>
        <source>Confirmations</source>
        <translation>Bestätigungen</translation>
    </message>
    <message>
        <source>Confirmed</source>
        <translation>Bestätigt</translation>
    </message>
    <message>
        <source>Copy address</source>
        <translation>Adresse kopieren</translation>
    </message>
    <message>
        <source>Copy label</source>
        <translation>Etikett kopieren</translation>
    </message>
    <message>
        <source>Copy amount</source>
        <translation>Betrag kopieren</translation>
    </message>
    <message>
        <source>Copy transaction ID</source>
        <translation>Transaktions ID kopieren</translation>
    </message>
    <message>
        <source>yes</source>
        <translation>Ja</translation>
    </message>
    <message>
        <source>no</source>
        <translation>Nein</translation>
    </message>
    <message>
        <source>(no label)</source>
        <translation>(kein Etikett)</translation>
    </message>
    </context>
<context>
    <name>EditAddressDialog</name>
    <message>
        <source>Edit Address</source>
        <translation>Adresse bearbeiten</translation>
    </message>
    <message>
        <source>&Label</source>
        <translation>&Etikett</translation>
    </message>
    <message>
        <source>&Address</source>
        <translation>&Adresse</translation>
    </message>
    <message>
        <source>New receiving address</source>
        <translation>Neue Empfangsadresse</translation>
    </message>
    <message>
        <source>New sending address</source>
        <translation>Neue Sendeadresse</translation>
    </message>
    <message>
        <source>Edit receiving address</source>
        <translation>Empfangsadresse bearbeiten</translation>
    </message>
    <message>
        <source>Edit sending address</source>
        <translation>Sendeadresse bearbeiten</translation>
    </message>
    </context>
<context>
    <name>FreespaceChecker</name>
    <message>
        <source>name</source>
        <translation>Name</translation>
    </message>
    </context>
<context>
    <name>HelpMessageDialog</name>
    <message>
        <source>version</source>
        <translation>Version</translation>
    </message>
    </context>
<context>
    <name>Intro</name>
    <message>
        <source>Welcome</source>
        <translation>Willkommen</translation>
    </message>
    <message>
        <source>Error</source>
        <translation>Fehler</translation>
    </message>
    </context>
<context>
    <name>ModalOverlay</name>
    <message>
        <source>Form</source>
        <translation>Formular</translation>
    </message>
    <message>
        <source>Unknown...</source>
        <translation>Unbekannt...</translation>
    </message>
    </context>
<context>
    <name>OpenURIDialog</name>
    </context>
<context>
    <name>OptionsDialog</name>
    </context>
<context>
    <name>OverviewPage</name>
    <message>
        <source>Form</source>
        <translation>Formular</translation>
    </message>
    </context>
<context>
    <name>PaymentServer</name>
    </context>
<context>
    <name>PeerTableModel</name>
    </context>
<context>
    <name>QObject</name>
    </context>
<context>
    <name>QObject::QObject</name>
    </context>
<context>
    <name>QRImageWidget</name>
    </context>
<context>
    <name>RPCConsole</name>
    </context>
<context>
    <name>ReceiveCoinsDialog</name>
    <message>
        <source>Copy label</source>
        <translation>Etikett kopieren</translation>
    </message>
    <message>
        <source>Copy amount</source>
        <translation>Betrag kopieren</translation>
    </message>
</context>
<context>
    <name>ReceiveRequestDialog</name>
    <message>
        <source>Address</source>
        <translation>Adresse</translation>
    </message>
    <message>
        <source>Label</source>
        <translation>Etikett</translation>
    </message>
    </context>
<context>
    <name>RecentRequestsTableModel</name>
    <message>
        <source>Date</source>
        <translation>Datum</translation>
    </message>
    <message>
        <source>Label</source>
        <translation>Etikett</translation>
    </message>
    <message>
        <source>(no label)</source>
        <translation>(kein Etikett)</translation>
    </message>
    </context>
<context>
    <name>SendCoinsDialog</name>
    <message>
        <source>Copy amount</source>
        <translation>Betrag kopieren</translation>
    </message>
    <message>
        <source>(no label)</source>
        <translation>(kein Etikett)</translation>
    </message>
</context>
<context>
    <name>SendCoinsEntry</name>
    </context>
<context>
    <name>SendConfirmationDialog</name>
    </context>
<context>
    <name>ShutdownWindow</name>
    </context>
<context>
    <name>SignVerifyMessageDialog</name>
    </context>
<context>
    <name>SplashScreen</name>
    </context>
<context>
    <name>TrafficGraphWidget</name>
    </context>
<context>
    <name>TransactionDesc</name>
    <message>
        <source>Date</source>
        <translation>Datum</translation>
    </message>
    </context>
<context>
    <name>TransactionDescDialog</name>
    </context>
<context>
    <name>TransactionTableModel</name>
    <message>
        <source>Date</source>
        <translation>Datum</translation>
    </message>
    <message>
        <source>Label</source>
        <translation>Etikett</translation>
    </message>
    <message>
        <source>(no label)</source>
        <translation>(kein Etikett)</translation>
    </message>
    </context>
<context>
    <name>TransactionView</name>
    <message>
        <source>Copy address</source>
        <translation>Adresse kopieren</translation>
    </message>
    <message>
        <source>Copy label</source>
        <translation>Etikett kopieren</translation>
    </message>
    <message>
        <source>Copy amount</source>
        <translation>Betrag kopieren</translation>
    </message>
    <message>
        <source>Copy transaction ID</source>
        <translation>Transaktions ID kopieren</translation>
    </message>
    <message>
        <source>Comma separated file (*.csv)</source>
        <translation>Komma getrenntes Dokument (*.csv)</translation>
    </message>
    <message>
        <source>Confirmed</source>
        <translation>Bestätigt</translation>
    </message>
    <message>
        <source>Date</source>
        <translation>Datum</translation>
    </message>
    <message>
        <source>Label</source>
        <translation>Etikett</translation>
    </message>
    <message>
        <source>Address</source>
        <translation>Adresse</translation>
    </message>
    <message>
        <source>Exporting Failed</source>
        <translation>Export fehlgeschlagen</translation>
    </message>
    </context>
<context>
    <name>UnitDisplayStatusBarControl</name>
    </context>
<context>
    <name>WalletFrame</name>
    </context>
<context>
    <name>WalletModel</name>
    </context>
<context>
    <name>WalletView</name>
    <message>
        <source>&Export</source>
        <translation>&Exportieren</translation>
    </message>
    <message>
        <source>Export the data in the current tab to a file</source>
        <translation>Daten des aktiven Fensters exportieren</translation>
    </message>
    </context>
<context>
    <name>bitcoin-core</name>
    <message>
        <source>Information</source>
        <translation>Information</translation>
    </message>
    <message>
        <source>Warning</source>
        <translation>Achtung</translation>
    </message>
    <message>
        <source>This is the minimum transaction fee you pay on every transaction.</source>
        <translation>Das ist die Mindestgebühr jeder Transaktion</translation>
    </message>
    <message>
        <source>This is the transaction fee you will pay if you send a transaction.</source>
        <translation>Das ist die Gebühr für die Überweisung</translation>
    </message>
    <message>
        <source>Transaction amounts must not be negative</source>
        <translation>Überweisungsbetrag kann nicht negativ sein</translation>
    </message>
    <message>
        <source>Transaction must have at least one recipient</source>
        <translation>Überweisung muss mindestens einen Empfänger haben </translation>
    </message>
    <message>
        <source>Insufficient funds</source>
        <translation>Ungenügendes Guthaben</translation>
    </message>
    <message>
        <source>Loading block index...</source>
        <translation>Block Verzeichnis laden...</translation>
    </message>
    <message>
        <source>Loading wallet...</source>
        <translation>Brieftasche laden...</translation>
    </message>
    <message>
        <source>Done loading</source>
        <translation>Laden abgeschlossen</translation>
    </message>
    <message>
        <source>Error</source>
        <translation>Fehler</translation>
    </message>
</context>
</TS>


text:
<?php

use Utils\FileSystem\FileSystemReader;
use Utils\FileSystem\FileSystemWriter;
use PHPUnit\Framework\TestCase;

/**
 * Checks whether \Utils\FileSystemHandler works as expected.
 */
class FileSystemHandlerTest extends TestCase
{
    /** @var FileSystemWriter */
    private $fileSystemHandler;
    /** @var string */
    private $testDirectory;

    private $directorySeparator;

    protected function setUp()
    {
        if (stristr(PHP_OS, "win")) $this->directorySeparator = "\\";
        else $this->directorySeparator = "/";

        $this->testDirectory = __DIR__ . $this->directorySeparator . ".." . $this->directorySeparator . "FileSystemHandlerTest";

        $this->fileSystemHandler = new FileSystemWriter();
        mkdir($this->testDirectory);
    }

    protected function tearDown()
    {
        rmdir($this->testDirectory);
        unset($this->fileSystemHandler);
    }

    /**
     * @dataProvider createDirectoryProvider()
     * @covers \Utils\FileSystem\FileSystemWriter::createDirectory()
     * @covers \Utils\FileSystem\FileSystemWriter::deleteDirectory()
     *
     * @param string $_directoryName    Test directory name
     * @param array $_subDirectories    Sub directories that shall be created
     *
     * @throws \Exception
     */
    public function testCanHandleDirectories(string $_directoryName, array $_subDirectories = array())
    {
        $directoryPath = $this->testDirectory . "/" . $_directoryName;
        $this->assertFalse(file_exists($directoryPath));

        $exceptionOccurred = false;
        try
        {
            $this->fileSystemHandler->createDirectory($directoryPath);
        }
        catch (\Exception $_exception)
        {
            $exceptionOccurred = true;
        }
        $this->assertFalse($exceptionOccurred);
        $this->assertTrue(file_exists($directoryPath));

        foreach ($_subDirectories as $subDirectory)
        {
            $subDirectoryPath = $this->testDirectory . "/" . $_directoryName . "/" . $subDirectory;
            $this->assertFalse(file_exists($subDirectoryPath));

            $exceptionOccurred = false;
            try
            {
                $this->fileSystemHandler->createDirectory($subDirectoryPath);
            }
            catch (\Exception $_exception)
            {
                $exceptionOccurred = true;
            }
            $this->assertFalse($exceptionOccurred);
            $this->assertTrue(file_exists($subDirectoryPath));
        }

        $exceptionOccurred = false;
        try
        {
            $this->fileSystemHandler->deleteDirectory($directoryPath, true);
        }
        catch (\Exception $_exception)
        {
            $exceptionOccurred = true;
        }
        $this->assertFalse($exceptionOccurred);
        $this->assertFalse(file_exists($directoryPath));
    }

    public function createDirectoryProvider()
    {
        return [
            ["mytest"],
            ["atest", ["1", "2", "3", "43"]],
            ["myyyy", ["ertert", "kuhkuihfauisdhf", "dshfuasdfuhadklshfasdkjfhadkshf", "ksjfhkasjdhfkasdjhf"]],
            ["lastDirectory"]
        ];
    }

    /**
     * @covers \Utils\FileSystem\FileSystemWriter::createDirectory()
     * @covers \Utils\FileSystem\FileSystemWriter::deleteDirectory()
     */
    public function testCanDetectExistingDirectory()
    {
        $directoryPath = $this->testDirectory . $this->directorySeparator . "atest";
        $this->assertFalse(file_exists($directoryPath));

        $exceptionOccurred = false;
        try
        {
            $this->fileSystemHandler->createDirectory($directoryPath);
        }
        catch (\Exception $_exception)
        {
            $exceptionOccurred = true;
        }
        $this->assertFalse($exceptionOccurred);
        $this->assertTrue(file_exists($directoryPath));

        // try to create the existing directory again
        $exceptionOccurred = false;
        try
        {
            $this->fileSystemHandler->createDirectory($directoryPath);
        }
        catch (\Exception $_exception)
        {
            $exceptionOccurred = true;
            $this->assertEquals("The directory \"" . $directoryPath . "\" already exists.", $_exception->getMessage());
        }
        $this->assertTrue($exceptionOccurred);

        $exceptionOccurred = false;
        try
        {
            $this->fileSystemHandler->deleteDirectory($directoryPath, true);
        }
        catch (\Exception $_exception)
        {
            $exceptionOccurred = true;
        }
        $this->assertFalse($exceptionOccurred);
        $this->assertFalse(file_exists($directoryPath));
    }

    /**
     * @dataProvider writeFileProvider
     * @covers \Utils\FileSystem\FileSystemWriter::writeFile()
     * @covers \Utils\FileSystem\FileSystemReader::readFile()
     * @covers \Utils\FileSystem\FileSystemWriter::deleteFile()
     *
     * @param string $_fileName         File name of the test file
     * @param string $_content          Content of the test file
     * @param array $_expectedContent   Expected content that is read by FileSystemHandler::readFile()
     */
    public function testCanHandleFiles(string $_fileName, string $_content, array $_expectedContent)
    {
        $outputPath = $this->testDirectory . $this->directorySeparator . $_fileName;
        $this->assertFalse(file_exists($outputPath));
        $fileSystemReader = new FileSystemReader();

        $exceptionOccurred  = false;
        try
        {
            $this->fileSystemHandler->writeFile($this->testDirectory . "/" . $_fileName, $_content);
        }
        catch (\Exception $_exception)
        {
            $exceptionOccurred = true;
        }
        $this->assertFalse($exceptionOccurred);
        $this->assertTrue(file_exists($outputPath));

        $exceptionOccurred = false;
        try
        {
            $fileContent = $fileSystemReader->readFile($outputPath);
        }
        catch (\Exception $_exception)
        {
            $exceptionOccurred = true;
            $fileContent = array();
        }
        $this->assertFalse($exceptionOccurred);
        $this->assertEquals($_expectedContent, $fileContent);

        $exceptionOccurred = false;
        try
        {
            $this->fileSystemHandler->deleteFile($outputPath);
        }
        catch (\Exception $_exception)
        {
            $exceptionOccurred = true;
        }
        $this->assertFalse($exceptionOccurred);
        $this->assertFalse(file_exists($outputPath));

        $exceptionOccurred = false;
        try
        {
            $this->fileSystemHandler->deleteFile("nonExistingFile.notExisting");
        }
        catch (\Exception $_exception)
        {
            $exceptionOccurred = true;
            $this->assertEquals("The file \"nonExistingFile.notExisting\" does not exist.", $_exception->getMessage());
        }
        $this->assertTrue($exceptionOccurred);
    }

    public function writeFileProvider()
    {
        return [
            "Single line of text" => ["mytest.txt", "Hello World!", ["Hello World!"]],
            "Two lines with line break" => ["asecondtest.txt", "My name is \n ...", ["My name is ", " ..."]],
            "Empty line after line break" => ["emptyline.txt", "test\n", ["test"]],
            "Empty line before line break" => ["emptylinefirst.txt", "\ntest", ["test"]],
            "Three lines" => ["threelines.txt", "testst\nteststst\ntserse", ["testst", "teststst", "tserse"]]
        ];
    }

    /**
     * @covers \Utils\FileSystem\FileSystemWriter::writeFile()
     * @covers \Utils\FileSystem\FileSystemReader::readFile()
     * @covers \Utils\FileSystem\FileSystemWriter::deleteFile()
     */
    public function testCanDetectExistingFile()
    {
        $filePath = $this->testDirectory . $this->directorySeparator . "mytest.txt";
        $fileSystemReader = new FileSystemReader();

        $this->assertFalse(file_exists($filePath));

        // Check whether file can be created with content
        $exceptionOccurred = false;
        try
        {
            $this->fileSystemHandler->writeFile($this->testDirectory . "/mytest.txt", "Hello World!");
        }
        catch (\Exception $_exception)
        {
            $exceptionOccurred = true;
        }
        $this->assertFalse($exceptionOccurred);
        $this->assertTrue(file_exists($filePath));

        // Check whether file content can be read
        $exceptionOccurred = false;
        try
        {
            $fileContent = $fileSystemReader->readFile($filePath);
        }
        catch (\Exception $_exception)
        {
            $exceptionOccurred = true;
            $fileContent = array();
        }
        $this->assertFalse($exceptionOccurred);
        $this->assertEquals(array("Hello World!"), $fileContent);

        // Check whether trying to rewrite the file fails
        $exceptionOccurred = false;
        try
        {
            $this->fileSystemHandler->writeFile($this->testDirectory . "/mytest.txt", "Hello universe!");
        }
        catch (\Exception $_exception)
        {
            $this->assertEquals("The file already exists.", $_exception->getMessage());
            $exceptionOccurred = true;
        }
        $this->assertTrue($exceptionOccurred);

        // Check whether content of file changes
        $exceptionOccurred = false;
        try
        {
            $this->fileSystemHandler->writeFile($this->testDirectory . "/mytest.txt", "Hello universe!", false, true);
        }
        catch (\Exception $_exception)
        {
            $exceptionOccurred = true;
        }
        $this->assertFalse($exceptionOccurred);

        $exceptionOccurred = false;
        try
        {
            $fileContent = $fileSystemReader->readFile($filePath);
        }
        catch (\Exception $_exception)
        {
            $exceptionOccurred = true;
            $fileContent = array();
        }
        $this->assertFalse($exceptionOccurred);
        $this->assertEquals(array("Hello universe!"), $fileContent);

        $exceptionOccurred = false;
        try
        {
            $this->fileSystemHandler->deleteFile($filePath);
        }
        catch (\Exception $_exception)
        {
            $exceptionOccurred = true;
        }
        $this->assertFalse($exceptionOccurred);
        $this->assertFalse(file_exists($filePath));
    }

    /**
     * @covers \Utils\FileSystem\FileSystemReader::getFileList()
     */
    public function testCanGetFileList()
    {
        $fileSystemReader = new FileSystemReader();

        $fileNames = array("Hello", "myFile", "myPersonalFile", "myPersonalTest", "thisIsAFile", "ThisIsMyFile");
        sort($fileNames);

        foreach ($fileNames as $index => $fileName)
        {
            touch($this->testDirectory . $this->directorySeparator . $fileName);
        }

        $exceptionOccurred = false;
        try
        {
            $files = $fileSystemReader->getFileList($this->testDirectory . "/*");
        }
        catch (\Exception $_exception)
        {
            $exceptionOccurred = true;
            $files = array();
        }
        $this->assertFalse($exceptionOccurred);

        foreach ($files as $index => $file)
        {
            $fileName = $this->testDirectory . $this->directorySeparator . $fileNames[$index];
            $this->assertEquals($this->testDirectory . $this->directorySeparator . $fileNames[$index], $file);
            unlink($fileName);
        }
    }

    /**
     * Checks whether a file can be found recursive.
     *
     * @param String $_directories
     * @param String $_filePath
     * @param String $_searchFilename
     * @param Bool $_expectsFilePath Indicates whether the FileSystemHadresult will be a filepath or false
     *
     * @dataProvider findFileRecursiveProvider()
     *
     * @covers \Utils\FileSystem\FileSystemReader::findFileRecursive()
     */
    public function testCanFindFileRecursive(String $_directories, String $_filePath, String $_searchFilename, Bool $_expectsFilePath = true)
    {
        $testDirectory = __DIR__ . $this->directorySeparator . "test";
        $testFilePath = $testDirectory . $this->directorySeparator  . $_filePath;

        $fileSystemReader = new FileSystemReader();

        mkdir($testDirectory . $this->directorySeparator . $_directories, 0777, true);
        touch($testFilePath);

        $exceptionOccurred = false;
        try
        {
            $filePath = $fileSystemReader->findFileRecursive($testDirectory, $_searchFilename);
        }
        catch (\Exception $_exception)
        {
            $exceptionOccurred = true;
            $filePath = "";
        }
        $this->assertFalse($exceptionOccurred);

        if ($_expectsFilePath) $this->assertEquals($testFilePath, $filePath);
        else $this->assertEmpty($filePath);

        // Delete the test file
        unlink($testFilePath);

        // Delete the test sub directories
        $directories = explode($this->directorySeparator, $_directories);

        for ($i = count($directories); $i > 0; $i--)
        {
            $removeDirectory = "";

            for ($j = 0; $j < $i; $j++)
            {
                $removeDirectory .= $this->directorySeparator . $directories[$j];
            }

            rmdir($testDirectory . $removeDirectory);
        }

        // Delete the test directory
        rmdir($testDirectory);
    }

    /**
     * DataProvider for FileSystemHandlerTest::testCanFindFileRecursive().
     *
     * @return array Test values in the format array(testDirectoryStructure, filePath, searchFileName, expectsFilePath)
     */
    public function findFileRecursiveProvider()
    {
        if (stristr(PHP_OS, "win")) $directorySeparator = "\\";
        else $directorySeparator = "/";

        return array(
            "Existing file in second sub folder" => array(
                "testing"  . $directorySeparator . "directory" . $directorySeparator . "mytest",
                "testing" . $directorySeparator . "directory" . $directorySeparator . "test.txt",
                "test.txt"
            ),
            "Existing file in first sub folder" => array(
                "testing" . $directorySeparator . "directory" . $directorySeparator . "mytest",
                "testing" . $directorySeparator . "second.txt",
                "second.txt"
            ),
            "Existing file in third sub folder" => array(
                "testing" . $directorySeparator . "directory" . $directorySeparator . "mytest",
                "testing" . $directorySeparator . "directory" . $directorySeparator . "mytest" . $directorySeparator . "thisIsMyTest.txt",
                "thisIsMyTest.txt"
            ),
            "Not existing file" => array(
                "testing" . $directorySeparator . "directory" . $directorySeparator . "mytest",
                "testing" . $directorySeparator . "directory" . $directorySeparator . "mytest" . $directorySeparator . "test.txt",
                "nottest.txt",
                false
            )
        );
    }
}


text:
/**
 * THIS IS THE ENTRY POINT FOR THE CLIENT, JUST LIKE server.js IS THE ENTRY POINT FOR THE SERVER.
 */
import 'babel/polyfill';
import React from 'react';
import BrowserHistory from 'react-router/lib/BrowserHistory';
import Location from 'react-router/lib/Location';
import queryString from 'query-string';
import createStore from 'client/lib/redux/create';
import ApiClient from 'client/lib/ApiClient';
import universalRouter from 'client/lib/universalRouter';
import Immutable from 'immutable';

// Include the GSAP animation library, this will add the modules globally
require('gsap');

let serializedState = window.__data;

// Rehydrate serialized state into Immutable objects
Object
  .keys(serializedState)
  .forEach(key => {
    serializedState[key] = Immutable.fromJS(serializedState[key]);
   });

const history   = new BrowserHistory();
const client    = new ApiClient();

const dest      = document.getElementById('content');
const store     = createStore(client, serializedState);
const search    = document.location.search;
const query     = search && queryString.parse(search);
const location  = new Location(document.location.pathname, query);

universalRouter(location, history, store)
  .then(({component}) => {
    if (__DEVTOOLS__) {
      const { DevTools, DebugPanel, LogMonitor } = require('redux-devtools/lib/react');

      console.info('You will see a "Warning: React attempted to reuse markup in a container but the checksum was' +
        ' invalid." message. That\'s because the redux-devtools are enabled.');

      React.render(<div>
        {component}
        <DebugPanel top right bottom key="debugPanel">
          <DevTools store={store} monitor={LogMonitor}/>
        </DebugPanel>
      </div>, dest);
    }

    else {
      React.render(component, dest);
    }
  }, (error) => {
    console.error(error);
  });

if (process.env.NODE_ENV !== 'production') {
  window.React = React; // enable debugger

  const reactRoot = window.document.getElementById('content');

  if (!reactRoot || !reactRoot.firstChild || !reactRoot.firstChild.attributes || !reactRoot.firstChild.attributes['data-react-checksum']) {
    console.error('Server-side React render was discarded. Make sure that your initial render does not contain any client-side code.');
  }
}