User autocomplete: Add the class autocompletes-user for easier selecting later

This is nice because it means you can select/iterate all user
autocompleters using basic jQuery / CSS.

For the bespoke implementations, I add the class from JS so that if JS
doesn't run, the elements aren't tagged incorrectly.  That really only
matters if you're selecting elements with CSS (since your custom JS
won't be running either).
User autocomplete: Override the item render to conditionally use HTML from the server

Combined with the recent ModifySuggestion callback for
/Helpers/Autocomplete/Users, this lets customizers fully affect
rendering of the autocomplete suggestions.
Quote replies properly when re-wrapping

When re-wrapping text that already has email quoting, the
quoting should be maintained in the newly re-wrapped text.
See:

http://issues.bestpractical.com/Ticket/Display.html?id=16857
When wrapping, keep existing line breaks

When wrapping, honor existing line breaks and only wrap within
a line. This avoids combining intentional multi-line text into
a single paragraph.
/Ticket/Graphs/ requires the GraphViz module; skip tests if not installed
Instantiate new sessions on logout as well as deleting the old one

Although the stored session is deleted by tied(%session)->delete, the
tied object and all data still remains present in memory.  When %session
goes out of scope at the end of the request, the Apache::Session DESTROY
block attempts to save the session one last time.  On database session
stores (MySQL and Pg), the update silently fails because the row has
been deleted (and no error checking is done).  When using
Apache::Session::File, however, session updates autovivify the file,
essentially reverting the deletion.  The autovivified session contained
an empty current user, since the CU is replaced after the delete, but
all other user-specific session data still existed and was in the
session of the unauthenticated client.  This lead to incorrect behaviour
in extensions outside of core RT.

The old session id in the client's cookie is now immediately replaced
with a new session id.  Previously it was replaced it on the very next
request (meta-refresh to the login page) when the old id could not be
loaded.  Under Apache::Session::File, the old session was not replaced
at all until a successful login.
Instantiate a new session if the session doesn't match the ID we loaded it by

The replaced code was a no-op since the refactor in 64f65d8.  Before the
64f65d8, deleting from the parsed cookie data was enough to set a new
cookie.  The new cookie contained the found session id, regardless of if
it matched the loaded session id.

A safer, more conservative approach is to abandon the old session and
force a new one if the session cookie value loads a session with a
different id.  This should never happen but indicates corrupt session
data or malicious activity if it does.  There is no harm in the extra
protection.
Report better errors when unable to parse or execute TicketSQL

Tell the user that their query failed and provide the reason trimmed of
any stack trace.  Additionally, record any unparseable query in the logs
for the admin.

Previously parse errors were silent to the user and simply didn't return
any results.  Only the advanced query page reported errors.
Ensure that filenames in inline image attributes are HTML-escaped
Deny direct access to callbacks

Callbacks are meant to be called from the context of an core Mason
component, and do not expect to receive arbitrary input from query
parameters.  As such, deny access to them from the top-level request.
Protect calls to $m->comp with user input in ColumnMap

$Class may leak in from the user, which would allow calling arbitrary
components.  Protect it by using ComponentPathIsSafe, extended to ensure
that the path cannot be truncated early by way of embedded nulls.
Remove filename= suggesions from Content-Disposition lines

No supported standard exists for escaping of the "filename" attribute of
Content-Disposition.  This opens the possibility of various injection
attacks through carefully-crafted filenames if AlwaysDownloadAttachments
is enabled.

As the download endpoint is a dhandler, and most locations already
supply the filename after the final /, browsers will assume the correct
filename even if none is supplied to Content-Disposition.  Hence, remove
the filename= parameter entirely.
Ensure consistent escaping of filenames in attachment URIs

<% $value |u %> still applies HTML escaping before URI escaping, which
is incorrect, as it leads to files named «a"test".txt» being linked with
URIs like «a%26%2334%3Btest%26%2334%3B.txt» -- the URI-escaped version
of «a&#34;test&#34;.txt».

Ensure that these URIs are only URI-escaped (yilding «a%22test%22.txt»
in this example), such that browsers correctly parse the intended
filename from the URI.
Ensure that URLs placed in HTML attributes are escaped correctly, to prevent XSS injection
Ensure that the default replacement does not pass through unescaped content

This is only relevant in the case of a MakeClicky misconfiguration.
Use File::Temp for non-predictable temporary filenames

Previously, RT wrote to /tmp/rt.form.$$, which is a semi-predictable
filename.  A malicious user could symlink a file of their choosing into
that location, which a privileged user running bin/rt would then
overwrite.  While this race condition would be difficult to exploit, as
it leaves the attacker with no control over the contents of the file,
and relies on beating the race condition, it is still potentially
dangerous.

Use File::Temp to atomically generate a non-predictable filename and
open it for writing.
reset RT::SearchBuilder internal flags

DBIx::SearchBuilder ::CleanSlate reset a search's query, but RT::SearchBulder
has internal state that is recorded for searches also. This commit clears the
internal flags so that a completely clean search can run.

See [issues #23895]
Canonicalize on lower-case for statuses, which are now case-insensitive

Prior to the merge of lifecycles (in 2ad74ba), statuses were fully
case-sensitive.  This meant that attempts to set the status to 'OPEN'
would fail, as the case did not match the supported 'open' status.
Lifecycles made checks for _validation_ of statuses case-insensitive,
but did not spread that property to many other parts of the system --
including rights, transitions, and searching.

Canonicalize all statuses to lower-case in the database, and make the
remaining entry points into the API lower-case as well.  This also
requires checking that all statuses described in lifecycles are
correctly in lower-case.  While using perl 5.16's "fc" operator would be
more correct in this case, this is not possible on all versions of Perl
that RT currently runs on.
Merge two loops over %LIFECYCLES_CACHE into one
Force statuses to lower-case in lifecycles, to match ticket statuses

Ticket statuses are now forced to be stored in lower-case; normalize all
existing lifecycles to lower-case as well, to ensure that that existing
workflows (including transitions and rights) continue to work on
unmodified Lifecycle configurations.

This does not resolve any scrips or other custom code which rely upon
$ticket->Status eq "SomethingUpperCase", which still fail.