public function parse($source, array $options = []) {
		$mode = isset($options[self::OPTION_MODE])
			? (string) $options[self::OPTION_MODE]
			: self::SECTIONS_ROOT;
		
		// Parse with sections ignore
		if ($mode === self::SECTIONS_IGNORE) {
			return $this->parseData(parse_ini_string($source));
		}
		
		// Parse with sections as the root of an array
		if ($mode === self::SECTIONS_ROOT) {
			return array_map([$this, 'parseData'], parse_ini_string($source, true));
		}
		
		// Parse with section(s) specify
		if ($mode === self::SECTIONS_PICK) {
			if (! isset($options[self::OPTION_SECTION])) {
				throw new OptionsError('Section(s) must be spicified for the "pick" mode; you should use the "section" option');
			}
			
			$sections    = parse_ini_string($source, true);
			$inheritance = isset($options[self::OPTION_INHERITANCE])
				? (bool) $options[self::OPTION_INHERITANCE]
				: false;
			
			// Many of sections
			if (is_array($options[self::OPTION_SECTION])) {
				$data = [];

				foreach ($options[self::OPTION_SECTION] as $part) {
					$dataRaw = $this->getSection($sections, $part, $inheritance);
					$data[]  = $this->parseData($dataRaw);
				}

				return call_user_func_array('array_replace_recursive', $data);
			}
			
			// Single section
			$dataRaw = $this->getSection($sections, $options[self::OPTION_SECTION], $inheritance);
			return $this->parseData($dataRaw);
		}
		
		throw new OptionsError('Unknown mode "' . $mode . '"');
	}