'The main parse method for the parser. This method is run upon assignment to the
:py:attr:`full_name` attribute or instantiation.
Basic flow is to hand off to :py:func:`pre_process` to handle nicknames. It
then splits on commas and chooses a code path depending on the number of commas.
:py:func:`parse_pieces` then splits those parts on spaces and
:py:func:`join_on_conjunctions` joins any pieces next to conjunctions.'

def parse_full_name(self):

    self.title_list = []
    self.first_list = []
    self.middle_list = []
    self.last_list = []
    self.suffix_list = []
    self.nickname_list = []
    self.unparsable = True
    if (not isinstance(self._full_name, text_type)):
        self._full_name = u(self._full_name, self.ENCODING)
    self.pre_process()
    self._full_name = self.collapse_whitespace(self._full_name)
    parts = [x.strip() for x in self._full_name.split(u',')]
    log.debug(u'full_name:    {0}'.format(self._full_name))
    log.debug(u'parts:    {0}'.format(parts))
    if (len(parts) == 1):
        pieces = self.parse_pieces(parts)
        for (i, piece) in enumerate(pieces):
            try:
                nxt = pieces[(i + 1)]
            except IndexError:
                nxt = None
            if (self.is_title(piece) and (nxt or (len(pieces) == 1))):
                self.title_list.append(piece)
                continue
            if (not self.first):
                self.first_list.append(piece)
                continue
            if self.are_suffixes(pieces[(i + 1):]):
                self.last_list.append(piece)
                self.suffix_list += pieces[(i + 1):]
                break
            if (not nxt):
                self.last_list.append(piece)
                continue
            self.middle_list.append(piece)
    elif self.are_suffixes(parts[1].split(u'    ')):
        self.suffix_list += parts[1:]
        pieces = self.parse_pieces(parts[0].split(u'    '))
        log.debug(u'pieces:    {0}'.format(u(pieces)))
        for (i, piece) in enumerate(pieces):
            try:
                nxt = pieces[(i + 1)]
            except IndexError:
                nxt = None
            if (self.is_title(piece) and (nxt or (len(pieces) == 1))):
                self.title_list.append(piece)
                continue
            if (not self.first):
                self.first_list.append(piece)
                continue
            if self.are_suffixes(pieces[(i + 1):]):
                self.last_list.append(piece)
                self.suffix_list = (pieces[(i + 1):] + self.suffix_list)
                break
            if (not nxt):
                self.last_list.append(piece)
                continue
            self.middle_list.append(piece)
    else:
        pieces = self.parse_pieces(parts[1].split(u'    '), 1)
        log.debug(u'pieces:    {0}'.format(u(pieces)))
        lastname_pieces = self.parse_pieces(parts[0].split(u'    '), 1)
        for piece in lastname_pieces:
            if (self.is_suffix(piece) and (len(self.last_list) > 0)):
                self.suffix_list.append(piece)
            else:
                self.last_list.append(piece)
        for (i, piece) in enumerate(pieces):
            try:
                nxt = pieces[(i + 1)]
            except IndexError:
                nxt = None
            if (self.is_title(piece) and (nxt or (len(pieces) == 1))):
                self.title_list.append(piece)
                continue
            if (not self.first):
                self.first_list.append(piece)
                continue
            if self.is_suffix(piece):
                self.suffix_list.append(piece)
                continue
            self.middle_list.append(piece)
        try:
            if parts[2]:
                self.suffix_list += parts[2:]
        except IndexError:
            pass
    if (len(self) < 0):
        log.info((u'Unparsable    full_name:    ' + self._full_name))
    else:
        self.unparsable = False
        self.post_process()
