public static String betweenOuterPair(String text, char before, char after) {
        if (text == null) {
            return null;
        }

        int pos = -1;
        int pos2 = -1;
        int count = 0;
        int count2 = 0;

        boolean singleQuoted = false;
        boolean doubleQuoted = false;
        for (int i = 0; i < text.length(); i++) {
            char ch = text.charAt(i);
            if (!doubleQuoted && ch == '\'') {
                singleQuoted = !singleQuoted;
            } else if (!singleQuoted && ch == '\"') {
                doubleQuoted = !doubleQuoted;
            }
            if (singleQuoted || doubleQuoted) {
                continue;
            }

            if (ch == before) {
                count++;
            } else if (ch == after) {
                count2++;
            }

            if (ch == before && pos == -1) {
                pos = i;
            } else if (ch == after) {
                pos2 = i;
            }
        }

        if (pos == -1 || pos2 == -1) {
            return null;
        }

        // must be even paris
        if (count != count2) {
            return null;
        }

        return text.substring(pos + 1, pos2);
    }
@Test
    public void testBetweenOuterPair() {
        assertEquals("bar(baz)123", StringHelper.betweenOuterPair("foo(bar(baz)123)", '(', ')'));
        assertNull(StringHelper.betweenOuterPair("foo(bar(baz)123))", '(', ')'));
        assertNull(StringHelper.betweenOuterPair("foo(bar(baz123", '(', ')'));
        assertNull(StringHelper.betweenOuterPair("foo)bar)baz123", '(', ')'));
        assertEquals("bar", StringHelper.betweenOuterPair("foo(bar)baz123", '(', ')'));
        assertEquals("'bar', 'baz()123', 123", StringHelper.betweenOuterPair("foo('bar', 'baz()123', 123)", '(', ')'));

        assertTrue(StringHelper.betweenOuterPair("foo(bar)baz123", '(', ')', "bar"::equals).orElse(false));
        assertFalse(StringHelper.betweenOuterPair("foo[bar)baz123", '(', ')', "bar"::equals).orElse(false));
    }