protected static Organisation[] GetChildren(ref DataTable dt, string query, int level)
    {
        DataRow[]      foundRows = dt.Select(query, "name");
        Organisation[] children  = new Organisation[foundRows.Length];
        for (int i = 0; i < foundRows.Length; i++)
        {
            Organisation org = OrganisationDB.LoadAll(foundRows[i]);
            org.TreeDataRow  = foundRows[i];
            org.TreeLevel    = level;
            org.TreeChildren = GetChildren(ref dt, "parent_organisation_id = " + org.OrganisationID.ToString(), level + 1);
            children[i]      = org;
        }

        return(children);
    }
    public static Organisation[] GetFlattenedTree(DataTable dt = null, bool showDeleted = false, int organisationID = 0, bool onlyLowerBranches = false, string org_type_ids = "")
    {
        if (dt == null)
        {
            dt = OrganisationDB.GetDataTable(0, showDeleted, true, false, false, true, true, "", false, org_type_ids);
        }
        dt.Columns.Add("tree_level", typeof(Int32));

        Organisation[] tree = GetChildren(ref dt, "parent_organisation_id is NULL", 0);

        if (organisationID != 0)
        {
            for (int i = 0; i < tree.Length; i++)
            {
                if (tree[i].OrganisationID == organisationID || Contains(tree[i].TreeChildren, organisationID))
                {
                    if (!onlyLowerBranches)
                    {
                        tree = new Organisation[] { tree[i] }
                    }
                    ;
                    else
                    {
                        tree = new Organisation[] { GetNode(new Organisation[] { tree[i] }, organisationID) }
                    };
                }
            }
        }

        DataTable newTable = dt.Clone();

        Flatten(tree, ref newTable);

        if (onlyLowerBranches && newTable.Rows.Count > 0)  // if taking only sub-tree, then reset the level to zero for the base node(s)
        {
            int levelAdjustment = Convert.ToInt32(newTable.Rows[0]["tree_level"]);
            for (int i = 0; i < newTable.Rows.Count; i++)
            {
                newTable.Rows[i]["tree_level"] = Convert.ToInt32(newTable.Rows[i]["tree_level"]) - levelAdjustment;
            }
        }

        ArrayList newList = new ArrayList();
        Hashtable orgHash = new Hashtable();

        for (int i = 0; i < newTable.Rows.Count; i++)
        {
            Organisation org = OrganisationDB.LoadAll(newTable.Rows[i]);
            org.TreeLevel = Convert.ToInt32(newTable.Rows[i]["tree_level"]);
            orgHash[org.OrganisationID] = org;
            newList.Add(org);
        }

        Organisation[] list = (Organisation[])newList.ToArray(typeof(Organisation));

        for (int i = 0; i < list.Length; i++)
        {
            if (list[i].ParentOrganisation != null)
            {
                list[i].ParentOrganisation = (Organisation)orgHash[list[i].ParentOrganisation.OrganisationID];
            }
        }

        return(list);
    }