def parse_mapping(self, map_path, source=None, dotfiles=None):
include_re = r
        include_re = re.compile(include_re, re.I)
mapping_re = r
        mapping_re = re.compile(mapping_re)
        filename = None
        map_path = path.realpath(path.expanduser(map_path))
        if path.isfile(map_path):
            filename = map_path
        elif path.isdir(map_path):
            for map_name in '.dotfiles', 'dotfiles':
                candidate = path.join(map_path, map_name)
                if path.isfile(candidate):
                    filename = candidate
                    break
        if filename is None:
            raise ValueError('No dotfile mapping found in %s' % map_path)
        if source is None:
            source = path.dirname(map_path)
        if dotfiles is None:
            dotfiles = OrderedDict()
        lineno = 0
        with open(filename) as fh:
            for line in fh:
                lineno += 1
                content = line.strip()
                match = include_re.match(content)
                if match:
                    include_path = match.group(1).strip('\'"')
                    if (include_path.startswith('/') or
                            include_path.startswith('~')):
                        include_path = path.realpath(
                            path.expanduser(include_path))
                    else:
                        include_path = path.join(path.dirname(filename),
                                                 include_path)
                    if path.exists(include_path):
                        self.log.debug('Recursively parsing mapping in %s',
                                       include_path)
                        dotfiles = self.parse_mapping(include_path,
                                                      dotfiles=dotfiles)
                    else:
                        self.log.warning('Include command points to file or '
                                         'directory that does not exist, "%s",'
                                         ' on line %d', include_path, lineno)
                if not content or content.startswith('
                    continue
                match = mapping_re.match(content)
                if match:
                    source_path, target_path = match.groups()
                    source_path = path.join(source, source_path.strip('\'"'))
                    if source_path in dotfiles:
                        self.log.warning('Duplicate dotfile source "%s" '
                                         'on line
                        continue
                    if target_path is None:
                        target_path = source_path
                    dotfiles[source_path] = target_path
                else:
                    self.log.warning('Dotfile mapping regex failed on line '
                                     '
        return dotfiles