def transform_to_chomsky_normal_form(grammar, inplace=False):
    # type: (Grammar, bool) -> Grammar
    """
    Transform grammar to Chomsky Normal Form.
    :param grammar: Grammar to transform.
    :param inplace: True if transformation should be performed in place. False by default.
    :return: Grammar in Chomsky Normal Form.
    """
    # Copy if required
    if inplace is False:
        grammar = copy(grammar)
    # Create nonterminals rewritable to the terminal.
    # They will be inserted into the grammar as needed.
    fill = TerminalsFilling(grammar)
    to_process = Queue()
    for r in grammar.rules:
        to_process.put(r)
    while not to_process.empty():
        rule = to_process.get()  # type: Type[Rule]
        # Check, if rule must be split
        if len(rule.right) > 2:
            grammar.rules.remove(rule)
            # create nonterm that represent group on the right
            created_nonterm = type("ChomskyGroup[" + rule.__name__ + "]",
                                   (ChomskyGroupNonterminal,),
                                   ChomskyGroupNonterminal.__dict__.copy())  # type: Type[ChomskyGroupNonterminal]
            created_nonterm.group = rule.right[1:]
            # create rule that replace current
            created_left_rule = type("ChomskySplit[" + rule.__name__ + "]",
                                     (ChomskySplitRule,),
                                     ChomskySplitRule.__dict__.copy())  # type: Type[ChomskySplitRule]
            created_left_rule.rule = ([rule.fromSymbol], [rule.right[0], created_nonterm])
            created_left_rule.from_rule = rule
            # create rule with symbols on the right
            created_right_rule = type("ChomskyRest[" + rule.__name__ + "]",
                                      (ChomskyRestRule,),
                                      ChomskyRestRule.__dict__.copy())  # type: Type[ChomskyRestRule]
            created_right_rule.rule = ([created_nonterm], rule.right[1:])
            created_right_rule.from_rule = rule
            # add it to the grammar
            grammar.nonterminals.add(created_nonterm)
            grammar.rules.add(created_left_rule, created_right_rule)
            to_process.put(created_left_rule)
            to_process.put(created_right_rule)
        # check, if must replace terminal
        elif len(rule.right) == 2:
            if rule.right[0] in grammar.terminals:
                # first symbol is terminal
                # remove rule from grammar
                grammar.rules.remove(rule)
                # get nonterminal rewritable to the terminal and add that rules into the grammar implicitly
                symb = fill.get(rule.right[0])
                # create rule replacing the original one
                created = type("ChomskyLeft[" + rule.__name__ + "]",
                               (ChomskyTerminalReplaceRule,),
                               ChomskyTerminalReplaceRule.__dict__.copy())  # type: Type[ChomskyTerminalReplaceRule]
                created.rule = ([rule.fromSymbol], [symb, rule.right[1]])
                created.from_rule = rule
                created.replaced_index = 0
                # add it into the grammar
                grammar.rules.add(created)
                to_process.put(created)
            elif rule.right[1] in grammar.terminals:
                # second symbol is terminal
                # remove rule from grammar
                grammar.rules.remove(rule)
                # get nonterminal rewritable to the terminal and add that rules into the grammar implicitly
                symb = fill.get(rule.right[1])
                # create rule replacing the original one
                created = type("ChomskyRight[" + rule.__name__ + "]",
                               (ChomskyTerminalReplaceRule,),
                               ChomskyTerminalReplaceRule.__dict__.copy())
                created.rule = ([rule.fromSymbol], [rule.right[0], symb])
                created.from_rule = rule
                created.replaced_index = 1
                # add it into the grammar
                grammar.rules.add(created)
                to_process.put(created)
    return grammar