*order the projects within this taskpaper object via a list of tags*

         The order of the tags in the list dictates the order of the sort - first comes first*

        **Key Arguments:**
            - ``workflowTags`` -- a string of space/comma seperated tags.

        **Return:**
            - ``None``

        **Usage:**

            To recursively sort the projects within a taskpaper document with the following order:

            1. *@due*
            2. *@flag*
            3. *@hold*
            4. *@next*
            5. *@someday*
            6. *@wait*

            use the following:

            .. code-block:: python

                doc.sort_projects("@due, @flag, @hold, @next, @someday, @wait")

def sort_projects(
            self,
            workflowTags):
        """*order the projects within this taskpaper object via a list of tags*

         The order of the tags in the list dictates the order of the sort - first comes first*

        **Key Arguments:**
            - ``workflowTags`` -- a string of space/comma seperated tags.

        **Return:**
            - ``None``

        **Usage:**

            To recursively sort the projects within a taskpaper document with the following order:

            1. *@due*
            2. *@flag*
            3. *@hold*
            4. *@next*
            5. *@someday*
            6. *@wait*

            use the following:

            .. code-block:: python

                doc.sort_projects("@due, @flag, @hold, @next, @someday, @wait")
        """
        self.refresh
        if not isinstance(workflowTags, list):
            workflowTagsLists = workflowTags.strip().replace(",", "").replace("@", "")
            workflowTagsLists = workflowTagsLists.split(" ")
        else:
            workflowTagsLists = []
            workflowTagsLists[:] = [l.replace("@", "") for l in workflowTags]
        matchedProjects = collections.OrderedDict()
        unmatchedProjects = []
        for wt in workflowTagsLists:
            matchedProjects[wt.lower()] = []
        for p in self.projects:
            matched = False
            for pt in p.tags:
                if matched:
                    break
                for wt in workflowTagsLists:
                    thisTag = pt.lower()
                    if "(" not in wt:
                        thisTag = pt.split("(")[0].lower()
                    if thisTag == wt.lower() and matched == False:
                        matchedProjects[wt.lower()].append(p)
                        matched = True
                        break
            if matched == False:
                unmatchedProjects.append(p)

        sortedProjects = []
        for k, v in matchedProjects.iteritems():
            sortedProjects += v

        sortedProjects += unmatchedProjects
        self.projects = sortedProjects

        self.content = self.to_string(
            title=False, projects=sortedProjects, indentLevel=0)

        for p in self.projects:
            p.projects = p.sort_projects(workflowTags)

        # ADD DIRECTLY TO CONTENT IF THE PROJECT IS BEING ADDED SPECIFICALLY TO
        # THIS OBJECT
        oldContent = self.to_string(indentLevel=1)
        newContent = self.to_string(
            indentLevel=1, projects=sortedProjects)

        if self.parent:
            self.parent._update_document_tree(
                oldContent=oldContent,
                newContent=newContent
            )

        self.content = self.content.replace(self.to_string(indentLevel=0, title=False), self.to_string(
            indentLevel=0, title=False, projects=sortedProjects))

        self.refresh

        return sortedProjects