class StandardAtomGenerator {

    AtomSymbol generatePseudoSymbol(String label, HydrogenPosition position, RendererModel model) {

        final Font stylisedFont;
        if (model != null && model.get(PseudoFontStyle.class) != 0) {
            Integer style = model.get(PseudoFontStyle.class);
            stylisedFont = font.deriveFont(style);
        } else {
            stylisedFont = font;
        }

        List<TextOutline> outlines = new ArrayList<>(3);

        int beg = 0;
        int pos = 0;
        int len = label.length();

        // upper case followed by lower case
        while (pos < len && isUpperCase(label.charAt(pos)))
            pos++;
        if (label.charAt(0) != 'R') // Ar is not A^r but 'Ra' is R^a etc
            while (pos < len && isLowerCase(label.charAt(pos)))
                pos++;

        if (pos > beg) {
            outlines.add(new TextOutline(label.substring(beg, pos), stylisedFont));
            beg = pos;
            // 2a etc.
            while (pos < len && isDigit(label.charAt(pos)))
                pos++;
            while (pos < len && isLowerCase(label.charAt(pos)))
                pos++;

            if (pos > beg) {
                TextOutline outline = new TextOutline(label.substring(beg, pos), stylisedFont);
                outline = outline.resize(scriptSize, scriptSize);
                outline = positionSuperscript(outlines.get(0), outline);
                outlines.add(outline);
            }

            int numPrimes = 0;
            PRIMES:
            while (pos < len) {
                switch (label.charAt(pos)) {
                    case '\'': numPrimes++; break;
                    case '`': numPrimes++;  break;
                    case '‘': numPrimes++;  break;
                    case '’': numPrimes++;  break;
                    case '‛': numPrimes++;  break;
                    case '“': numPrimes+=2; break;
                    case '”': numPrimes+=2; break;
                    case '′': numPrimes++;  break;
                    case '″': numPrimes+=2; break;
                    case '‴': numPrimes+=3; break;
                    case '⁗': numPrimes+=4; break;
                    case '‵': numPrimes++;  break;
                    case '‶': numPrimes+=2; break;
                    case '‷': numPrimes+=3; break;
                    case '´': numPrimes++;  break;
                    case 'ˊ': numPrimes++;  break;
                    case '́': numPrimes++;  break;
                    case '˝': numPrimes+=2; break;
                    case '̋': numPrimes+=2; break;
                    default: break PRIMES;
                }
                pos++;
            }

            if (pos < len) {
                return new AtomSymbol(new TextOutline(label, stylisedFont), Collections.<TextOutline>emptyList());
            } else {
                TextOutline outline = null;
                TextOutline ref = outlines.get(outlines.size()-1);
                switch (numPrimes) {
                    case 0: break;
                    case 1: outline = new TextOutline("′", font); break;
                    case 2: outline = new TextOutline("″", font); break;
                    case 3: outline = new TextOutline("‴", font); break;
                    default:
                        String lab = "";
                        while (numPrimes-->0)
                            lab += "′";
                        outline = new TextOutline(lab, font);
                        break;
                }
                if (outline != null) {
                    if (outlines.size() > 1)
                        outline = outline.resize(scriptSize, scriptSize);
                    outline = positionSuperscript(ref, outline);
                    outlines.add(outline);
                }
            }

            // line up text
            for (int i = 1; i < outlines.size(); i++) {
                TextOutline ref = outlines.get(i - 1);
                TextOutline curr = outlines.get(i);
                outlines.set(i, positionAfter(ref, curr));
            }

            return new AtomSymbol(outlines.get(0),
                                  outlines.subList(1, outlines.size()));
        } else {
            return new AtomSymbol(new TextOutline(label, stylisedFont), Collections.<TextOutline>emptyList());
        }
    }

      StandardAtomGenerator(Font font);
    private  StandardAtomGenerator(Font font, double adjunctSpacing, double scriptSize);

}