/// <summary>
        /// Parses the specified card text.
        /// </summary>
        /// <param name="inputText">The input text.</param>
        /// <param name="allCards">All cards.</param>
        /// <returns></returns>
        /// <exception cref="System.InvalidOperationException">This exception will be thrown when the input text couldn't be matched.</exception>
        public static IEnumerable<CardData> Parse(
            string inputText,
            IEnumerable<CardData> allCards)
        {
            var result = new List<CardData>();

            if (string.IsNullOrEmpty(inputText))
            {
                return result;
            }

            var regex = new Regex(
                RegularExpressions.AnalyzeCards,
                RegexOptions.CultureInvariant | RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace | RegexOptions.Multiline | RegexOptions.Singleline);

            var match = regex.Match(inputText);
            if (!match.Success)
            {
                throw new InvalidOperationException(Localization.ParseErrorGeneral);
            }

            var numberGroups = match.Groups["Number"].Captures;
            var cardGroups = match.Groups["Card"].Captures;

            if (numberGroups.Count != cardGroups.Count)
            {
                var details = string.Format(
                    CultureInfo.CurrentUICulture,
                    Localization.ParseErrorLineMismatch,
                    numberGroups.Count,
                    cardGroups.Count);

                throw new InvalidOperationException(details);
            }

            for (int index = 0; index < numberGroups.Count; ++index)
            {
                var card = new CardData()
                {
                    Name = cardGroups[index].Value.ToString().Trim(),
                    Count = Convert.ToInt32(numberGroups[index].Value, CultureInfo.InvariantCulture),
                };

                var found = allCards.Where(c => c.Name.Equals(card.Name)).FirstOrDefault();
                if (found != null)
                {
                    card.CardType = found.CardType;
                }

                result.Add(card);
            }

            return result.OrderBy(c => c.CardType).ThenBy(c => c.Name).ToList();
        }
        /// <summary>
        /// Reads the specified card models.
        /// </summary>
        /// <param name="gameId">The game id.</param>
        /// <param name="cardModels">The card models.</param>
        /// <returns></returns>
        public IEnumerable<CardData> Read(
            string gameId,
            IEnumerable<CardModel> cardModels)
        {
            var result = new List<CardData>();

            foreach (var item in cardModels)
            {
                var card = new CardData()
                {
                    Id = item.Id.ToString(),
                    Name = item.Name,
                    GameId = gameId,
                    CardType = item.GetCardType(),
                };

                result.Add(card);
            }

            return result.OrderBy(c => c.CardType).ThenBy(c => c.Name).ToList();
        }
        /// <summary>
        /// Parses the specified card text.
        /// </summary>
        /// <param name="inputText">The input text.</param>
        /// <param name="allCards">All cards.</param>
        /// <returns></returns>
        public static ParseResult Parse(
            string inputText,
            IEnumerable<CardData> allCards)
        {
            var result = new ParseResult();
            var foundCards = new List<CardData>();

            if (string.IsNullOrEmpty(inputText))
            {
                return result;
            }

            var options = RegexOptions.CultureInvariant | RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace | RegexOptions.Multiline | RegexOptions.Singleline;

            var splitRegex = new Regex(
                RegularExpressions.SplitLines,
                options);

            var splitMatch = splitRegex.Match(inputText);
            if (!splitMatch.Success)
            {
                throw new InvalidOperationException(Localization.ParseErrorGeneral);
            }

            var lines = new List<string>();
            var lineCaptures = splitMatch.Groups["Line"].Captures;
            for (int index = 0; index < lineCaptures.Count; ++index)
            {
                lines.AddRange(lineCaptures[index].Value.Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries));
            }

            lines = lines.Where(l => !string.IsNullOrWhiteSpace(l)).ToList();

            var errnousLines = new List<string>();

            var regex = new Regex(
                RegularExpressions.AnalyzeCards,
                options);

            foreach (var line in lines)
            {
                var match = regex.Match(line);
                if (!match.Success)
                {
                    errnousLines.Add(line);
                }

                var numberGroups = match.Groups["Number"].Captures;
                var cardGroups = match.Groups["Card"].Captures;

                if (numberGroups.Count != cardGroups.Count)
                {
                    lines.Add(line);
                    continue;
                }

                for (int index = 0; index < numberGroups.Count; ++index)
                {
                    var name = cardGroups[index].Value
                        .ToString()
                        .Trim()
                        .Replace("’", "'");

                    name = SelectedCardGame.Instance.TranslationTable.TranslateDeToEn(name);
                    var quantity = Convert.ToInt32(numberGroups[index].Value, CultureInfo.InvariantCulture);

                    var foundCard = foundCards.Where(c => c.Name == name).Cast<CardData>().FirstOrDefault();

                    if (foundCard == null)
                    {
                        var card = new CardData()
                        {
                            Name = name,
                            Count = quantity,
                        };

                        var found = allCards.Where(c => c.Name.Equals(card.Name)).FirstOrDefault();
                        if (found != null)
                        {
                            card.CardType = found.CardType;
                        }

                        foundCards.Add(card);
                    }
                    else
                    {
                        foundCard.Count += quantity;
                    }
                }
            }

            ////if (errnousLines.Any())
            ////{
            ////    throw new InvalidOperationException(Localization.ParseErrorGeneral + Environment.NewLine + string.Join(",", errnousLines));
            ////}

            result.ParsedCards = foundCards.OrderBy(c => c.CardType).ThenBy(c => c.Name).ToList();
            result.ErrnousLines = errnousLines;

            return result;
        }