More fun with case-(very)-sensitive strings Inspired by this challenge (or, more specifically, by misreading it), I've come up with the following challenge:
Given an input string S, reverse the order of all uppercase characters, and all lowercase characters. Leave all non-letter characters in place. For instance:

Note that the uppercase W (the first uppercase letter) was replaced with H (the last). Same goes for the lowercase letters: 'd' (the first) is swapped with e (the last), l (second) gets replaced with l (pen-ultimate) ... All the non-letter characters are left in place.
Input

Input is a string with only ASCII characters in the range 32-126.
Input is guaranteed to be at least 1 character long, and won't exceed your language's limit.

Output

That same string, with the characters swapped as described.

Additional rules

Standard loopholes are forbidden
Answer must be a full program or a function, not a snippet or a REPL-entry.
code-golf, shortest answer in bytes wins.

Test cases
A
A

Ok
Ok

OK
KO

Hello, World!
Wdlro, Holle!

0123456789
0123456789

The quick brown Fox jumps over the lazy doge
Feg odyza lehtr Tev ospmu jxon wor bkci uqeh

odd
ddo

racecar
racecar

EtOn Em OsN R AaToNsIsIhT!!1!
ThIs Is NoT A RaNsOmEnOtE!!1!
Retina, 19 bytes

Retina doesn't have a direct way to reverse a string, but we can do it by exploiting the sorting stage:

O^#`[a-z]
O^#`[A-Z]


Sort (O), reading them as numbers (#), and then reverse the ordering (^), of all the strings matching the given regex (lowercase letters for the first line, and uppercase letters for the second).

This works because when we try to read strings without numeric characters as numbers they get treated as 0, so all the characters have the same value for sorting. Since sorting is stable they are left in the same order, and reversing them returns the original string reversed.

Try it online!