public function parseFormatFromCldr(Locale $locale, $formatType, $formatLength)
    {
        self::validateFormatType($formatType);
        self::validateFormatLength($formatLength);

        if (isset($this->parsedFormatsIndices[(string)$locale][$formatType][$formatLength])) {
            return $this->parsedFormats[$this->parsedFormatsIndices[(string)$locale][$formatType][$formatLength]];
        }

        $model = $this->cldrRepository->getModelForLocale($locale);

        if ($formatLength === 'default') {
            // the default thing only has an attribute. ugly fetch code. was a nice three-liner before 2011-11-21
            $formats = $model->getRawArray('dates/calendars/calendar[@type="gregorian"]/' . $formatType . 'Formats');
            foreach (array_keys($formats) as $k) {
                $realFormatLength = CldrModel::getAttributeValue($k, 'choice');
                if ($realFormatLength !== false) {
                    break;
                }
            }
        } else {
            $realFormatLength = $formatLength;
        }

        $format = $model->getElement('dates/calendars/calendar[@type="gregorian"]/' . $formatType . 'Formats/' . $formatType . 'FormatLength[@type="' . $realFormatLength . '"]/' . $formatType . 'Format/pattern');

        if (empty($format)) {
            throw new Exception\UnableToFindFormatException('Date / time format was not found. Please check whether CLDR repository is valid.', 1280218994);
        }

        if ($formatType === 'dateTime') {
            // DateTime is a simple format like this: '{0} {1}' which denotes where to insert date and time
            $parsedFormat = $this->prepareDateAndTimeFormat($format, $locale, $formatLength);
        } else {
            $parsedFormat = $this->parseFormat($format);
        }

        $this->parsedFormatsIndices[(string)$locale][$formatType][$formatLength] = $format;
        return $this->parsedFormats[$format] = $parsedFormat;
    }