/// <summary>
        /// Recursives the prepare spannable indexes.
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="text">The text.</param>
        /// <param name="size">The size.</param>
        /// <param name="builder">The builder.</param>
        /// <param name="modules">The modules.</param>
        /// <param name="start">The start.</param>
        /// <exception cref="System.ArgumentException">
        /// Unknown resource  + stroke +  in \ + text + \
        /// or
        /// Unknown resource  + stroke +  in \ + text + \
        /// or
        /// Unknown resource  + stroke +  in \ + text + \
        /// or
        /// Unknown resource  + stroke +  in \ + text + \
        /// or
        /// Unknown expression  + stroke +  in \ + text + \
        /// </exception>
        private static void RecursivePrepareSpannableIndexes(Context context, String text, Single size, SpannableStringBuilder builder, IList <IIconModule> modules, Int32 start)
        {
            // Try to find a {...} in the string and extract expression from it
            var stringText = builder.ToString();
            var startIndex = stringText.IndexOf("{", start, StringComparison.Ordinal);

            if (startIndex == -1)
            {
                return;
            }
            var endIndex   = stringText.IndexOf("}", startIndex, StringComparison.Ordinal) + 1;
            var expression = stringText.Substring(startIndex + 1, endIndex - 2);

            // Split the expression and retrieve the icon key
            var strokes = expression.Split(' ');
            var key     = strokes[0];

            // Loop through the descriptors to find a key match
            IIconModule module = null;
            IIcon       icon   = null;

            for (var i = 0; i < modules.Count; i++)
            {
                module = modules[i];
                icon   = module.GetIcon(key);
                if (icon != null)
                {
                    break;
                }
            }

            // If no match, ignore and continue
            if (icon == null)
            {
                RecursivePrepareSpannableIndexes(context, text, size, builder, modules, endIndex);
                return;
            }

            // See if any more stroke within {} should be applied
            var iconSizePx      = spToPx(context, size);
            var iconColor       = Int32.MaxValue;
            var iconSizeRatio   = -1f;
            var spin            = false;
            var baselineAligned = false;

            for (var i = 1; i < strokes.Length; i++)
            {
                var stroke = strokes[i];

                // Look for "spin"
                if (stroke.Equals("spin", StringComparison.OrdinalIgnoreCase))
                {
                    spin = true;
                }

                // Look for "baseline"
                else if (stroke.Equals("baseline", StringComparison.OrdinalIgnoreCase))
                {
                    baselineAligned = true;
                }

                // Look for an icon size
                else if (Regex.IsMatch(stroke, "([0-9]*(\\.[0-9]*)?)dp"))
                {
                    iconSizePx = dpToPx(context, Convert.ToSingle(stroke.Substring(0, stroke.Length - 2)));
                }
                else if (Regex.IsMatch(stroke, "([0-9]*(\\.[0-9]*)?)sp"))
                {
                    iconSizePx = spToPx(context, Convert.ToSingle(stroke.Substring(0, stroke.Length - 2)));
                }
                else if (Regex.IsMatch(stroke, "([0-9]*)px"))
                {
                    iconSizePx = Convert.ToInt32(stroke.Substring(0, stroke.Length - 2));
                }
                else if (Regex.IsMatch(stroke, "@dimen/(.*)"))
                {
                    iconSizePx = GetPxFromDimen(context, context.PackageName, stroke.Substring(7));
                    if (iconSizePx < 0)
                    {
                        throw new ArgumentException("Unknown resource " + stroke + " in \"" + text + "\"");
                    }
                }
                else if (Regex.IsMatch(stroke, "@android:dimen/(.*)"))
                {
                    iconSizePx = GetPxFromDimen(context, ANDROID_PACKAGE_NAME, stroke.Substring(15));
                    if (iconSizePx < 0)
                    {
                        throw new ArgumentException("Unknown resource " + stroke + " in \"" + text + "\"");
                    }
                }
                else if (Regex.IsMatch(stroke, "([0-9]*(\\.[0-9]*)?)%"))
                {
                    iconSizeRatio = Convert.ToSingle(stroke.Substring(0, stroke.Length - 1)) / 100f;
                }

                // Look for an icon color
                else if (Regex.IsMatch(stroke, "#([0-9A-Fa-f]{6}|[0-9A-Fa-f]{8})"))
                {
                    iconColor = Color.ParseColor(stroke);
                }
                else if (Regex.IsMatch(stroke, "@color/(.*)"))
                {
                    iconColor = GetColorFromResource(context, context.PackageName, stroke.Substring(7));
                    if (iconColor == Int32.MaxValue)
                    {
                        throw new ArgumentException("Unknown resource " + stroke + " in \"" + text + "\"");
                    }
                }
                else if (Regex.IsMatch(stroke, "@android:color/(.*)"))
                {
                    iconColor = GetColorFromResource(context, ANDROID_PACKAGE_NAME, stroke.Substring(15));
                    if (iconColor == Int32.MaxValue)
                    {
                        throw new ArgumentException("Unknown resource " + stroke + " in \"" + text + "\"");
                    }
                }
                else
                {
                    throw new ArgumentException("Unknown expression " + stroke + " in \"" + text + "\"");
                }
            }

            // Replace the character and apply the typeface
            builder = (SpannableStringBuilder)builder.Replace(startIndex, endIndex, "" + icon.Character);
            builder.SetSpan(new CustomTypefaceSpan(icon, module.ToTypeface(context), iconSizePx, iconSizeRatio, iconColor, spin, baselineAligned), startIndex, startIndex + 1, SpanTypes.InclusiveExclusive);
            RecursivePrepareSpannableIndexes(context, text, size, builder, modules, startIndex);
        }