/// <overloads>
        /// Adds one row for each variable of the specified <see cref="Entity"/> or <see
        /// cref="EntityClass"/>.</overloads>
        /// <summary>
        /// Adds one row for each variable of the specified <see cref="Entity"/>.</summary>
        /// <param name="entity">
        /// The <see cref="Entity"/> whose variables to show.</param>
        /// <param name="category">
        /// The <see cref="EntityCategory"/> whose variables to show.</param>
        /// <exception cref="InvalidEnumArgumentException">
        /// <paramref name="category"/> is neither <see cref="VariableCategory.Attribute"/> nor <see
        /// cref="VariableCategory.Resource"/>.</exception>
        /// <remarks>
        /// <b>CreateVariableRows</b> adds one row for each basic value and modifier value defined
        /// by the specified <paramref name="entity"/>. The <see cref="PropertyListItem.Tag"/> of
        /// each row holds the corresponding <see cref="VariableClass"/>.</remarks>

        private void CreateVariableRows(Entity entity, VariableCategory category)
        {
            string categoryLabel = "";
            VariableClassDictionary   variables = null;
            VariableList              basics    = null;
            VariableModifierContainer modifiers = null;

            // retrieve variable collections for category
            if (category == VariableCategory.Attribute)
            {
                categoryLabel = Global.Strings.LabelAttribute;
                variables     = MasterSection.Instance.Variables.Attributes;
                basics        = entity.Attributes.Variables;
                modifiers     = entity.AttributeModifiers;
            }
            else if (category == VariableCategory.Resource)
            {
                categoryLabel = Global.Strings.LabelResource;
                variables     = MasterSection.Instance.Variables.Resources;
                basics        = entity.Resources.Variables;
                modifiers     = entity.ResourceModifiers;
            }
            else
            {
                ThrowHelper.ThrowInvalidEnumArgumentException(
                    "category", (int)category, typeof(VariableCategory));
            }

            Unit unit       = entity as Unit;
            int  firstIndex = Items.Count;

            // insert separator before first attribute?
            bool addSeparator = (firstIndex > 0);

            // add modifier row, preceded by separator if required
            Action <VariableClass, Int32, ModifierTarget, Int32>
            addRow = (variable, value, target, range) => {
                if (addSeparator)
                {
                    ApplicationUtility.AddSeparator(this);
                    addSeparator = false;
                    ++firstIndex;
                }

                string column = variable.Format(value, target, range);
                Items.Add(new PropertyListItem(categoryLabel, variable.Name, column, variable));
            };

            // process all variables defined by the scenario
            foreach (var pair in variables)
            {
                string id = pair.Key;

                // format basic value and self-modifier, if present
                string basicValue = FormatVariable(basics, id);
                string modSelf    = FormatVariable(modifiers.Self, id);

                string column = (basicValue == null ? modSelf :
                                 (modSelf == null ? basicValue : String.Format(
                                      ApplicationInfo.Culture, "{0} {1}", basicValue, modSelf)));

                if (column != null)
                {
                    // insert separator if required
                    if (addSeparator)
                    {
                        ApplicationUtility.AddSeparator(this);
                        addSeparator = false;
                        ++firstIndex;
                    }

                    var item = new PropertyListItem(categoryLabel, pair.Value.Name, column, pair.Value);

                    // show color bar for partially depleted resources
                    Variable resource;
                    if (basics.TryGetValue(id, out resource) && resource.IsDepletableResource)
                    {
                        item.Background = MediaObjects.GetBrush(MediaObjects.DangerFadeBrushes,
                                                                resource.Value, resource.Minimum, resource.Maximum);
                    }

                    // show unit strength resource as first entry
                    if (unit != null && unit.UnitClass.StrengthResource == id)
                    {
                        Items.Insert(firstIndex, item);
                    }
                    else
                    {
                        Items.Add(item);
                    }
                }

                // determine which additional modifiers are present
                Variable modOwner, modUnits, modUnitsRanged, modOwnerUnits, modOwnerUnitsRanged;
                modifiers.Units.TryGetValue(id, out modUnits);
                modifiers.UnitsRanged.TryGetValue(id, out modUnitsRanged);
                modifiers.OwnerUnits.TryGetValue(id, out modOwnerUnits);
                modifiers.OwnerUnitsRanged.TryGetValue(id, out modOwnerUnitsRanged);

                int range = entity.EntityClass.ModifierRange;
                if (modifiers.Owner.TryGetValue(id, out modOwner))
                {
                    addRow(pair.Value, modOwner.Value, ModifierTarget.Owner, range);
                }

                // always show Units & UnitsRanged modifiers
                if (modifiers.Units.TryGetValue(id, out modUnits))
                {
                    addRow(pair.Value, modUnits.Value, ModifierTarget.Units, range);
                }
                if (modifiers.UnitsRanged.TryGetValue(id, out modUnitsRanged))
                {
                    addRow(pair.Value, modUnitsRanged.Value, ModifierTarget.UnitsRanged, range);
                }

                // show OwnerUnits modifier only if different from Units modifier
                if (modifiers.OwnerUnits.TryGetValue(id, out modOwnerUnits))
                {
                    if (modUnits == null || modUnits.Value != modOwnerUnits.Value)
                    {
                        addRow(pair.Value, modOwnerUnits.Value, ModifierTarget.OwnerUnits, range);
                    }
                }
                else if (modUnits != null && modUnits.Value != 0)
                {
                    addRow(pair.Value, 0, ModifierTarget.OwnerUnits, range);
                }

                // show OwnerUnitsRanged modifier only if different from UnitsRanged modifier
                if (modifiers.OwnerUnitsRanged.TryGetValue(id, out modOwnerUnitsRanged))
                {
                    if (modUnitsRanged == null || modUnitsRanged.Value != modOwnerUnitsRanged.Value)
                    {
                        addRow(pair.Value, modOwnerUnitsRanged.Value, ModifierTarget.OwnerUnitsRanged, range);
                    }
                }
                else if (modUnitsRanged != null && modUnitsRanged.Value != 0)
                {
                    addRow(pair.Value, 0, ModifierTarget.OwnerUnitsRanged, range);
                }
            }
        }