There's no guarantee that BP with PoolSize=1 would process messages in enqueued order. That is only true for BOs, for BPs it's only true that message processing would start in the enqueued order. That might be (or might be not) a good enough guarantee for you depending on your use case.

An approach I saw used to guarantee FIFO for BP is to add an intermediate BP with PoolSize=1 which sends a sync request to your target BP and waits for an answer.  

Can you elaborate on a Message key, please? Is it a random or a categorical division? Why three specifically and not some other number?

What we were considering doing is increasing the pool size to 3 and programmatically creating a BPL on each thread that processes messages that would be directed to it, rather than having to create multiple BPLs into the production.

What do you want to achieve with that change?

%Library.RoutineMgr_StudioOpenDialog is a useful query!

Originally I started writing something similar, but went into %Dictionary package instead, which of course created issues for me about System and Mapped classes, so I decided to go a different way (ended with what's presented in this article).

With your approach I'll advice first building a list of classes to delete and then passing it to $SYSTEM.OBJ.Delete - it will be faster than deleting classes one by one. That said usually deletions are small in number (or at least in frequency) so speed does not really matter here.

Here's how to do it (sample code to transfer files over iris connection):

/// Get IRIS connection object
/// set iris = ##class().GetIRIS()
ClassMethod GetIRIS() As %Net.DB.Iris
{
    Set host = "host"
    Set port = 1972
    Set ns = "%SYS"
    Set user = "_SYSTEM"
    Set pass = "***"
    Set connection = ##class(%Net.DB.DataSource).CreateConnection(host, port, ns, user, pass)
    Set iris = connection.CreateIris()
    Quit iris
}

/// Transfer one file from sourceFile to targetFile on iris connection.
ClassMethod Transfer(iris As %Net.DB.Iris, sourceFile As %String, targetFile As %String) As %Status
{
    Set sc = $$$OK
    Try {
        Set stream = ##class(%Stream.FileBinary).%New()
        Do stream.LinkToFile(sourceFile)
        Set var = "%stream"
        Do iris.ClassMethodVoid($classname(), "InitStream", var, targetFile)
        While 'stream.AtEnd {
            Set chunk = stream.Read($$$MaxStringLength-1000)
            Do iris.ClassMethodVoid($classname(), "WriteStream", var, chunk)
        }
        Do iris.ClassMethodVoid($classname(), "SaveStream", var, ##class(%File).Attributes(sourceFile))
    }
    Catch ex{
        Do ##class(%SYS.System).WriteToConsoleLog("SuperServer Copy failure in Transfer:" _ ex.DisplayString())
        Throw ex

    }

    Quit sc
}

/// Initialize stream for subsequent write requests and place it in var.
/// var must be a global variable (start form %) 
/// file is created or truncated if already exists
ClassMethod InitStream(var As %String, file As %String)
{
    Try {
        Do ##class(%File).Truncate(file)
        Set stream = ##class(%Stream.FileBinary).%New()
        Do stream.LinkToFile(file)
        Set @var = stream
    } Catch ex{
        Do ##class(%SYS.System).WriteToConsoleLog("SuperServer Copy failure in InitStream: " _ ex.DisplayString())
        Throw ex
    }
}

/// Wrile string into a stream initialized by InitStream 
ClassMethod WriteStream(var As %String, string As %String)
{
    Try {
        Do $method(@var, "Write", string)
    } Catch ex{
        Do ##class(%SYS.System).WriteToConsoleLog("SuperServer Copy failure in WriteStream: " _ ex.DisplayString())
        Throw ex
    }
}

/// Save stream initialized by InitStream. 
/// Optionally sets file attributes.
ClassMethod SaveStream(var As %String, attributes As %String = "")
{
    Try {
        Set sc = $method(@var, "%Save")
        Set file = $property(@var, "Id")
        Kill @var
        Do:attributes'="" ##class(%File).SetAttributes(file, attributes)
    } catch ex {
        Do ##class(%SYS.System).WriteToConsoleLog("SuperServer Copy failure in Savetream: " _ ex.DisplayString())
        Throw ex
    }
}

Use ClassMethodValue to get a scalar value back. Use json for complex type transfer as objects are not supported. There are other methods corresponding to APIs in other languages.

Also please note that this class (technically only the callee *Stream methods but save yourself a headache and just copy the entire class) needs to be present on both nodes.

Finally, remember that callee methods must produce no stdout/stderr writes, since the io is bound to the iris connection itself and it cannot disambiguate stdout.