def build_widgets(self):

        if self.charm_class.allow_multi_units:
            machine_string = "machines"
            plural_string = "s"
        else:
            machine_string = "a machine"
            plural_string = ""
        instructions = Text("Select {} to host {}".format(machine_string, self.charm_class.display_name))

        self.service_widget = ServiceWidget(
            self.charm_class, self.controller, show_constraints=True, show_placements=True
        )

        all_actions = [
            (AssignmentType.BareMetal, "Add as Bare Metal", self.do_select_baremetal),
            (AssignmentType.LXC, "Add as LXC", self.do_select_lxc),
            (AssignmentType.KVM, "Add as KVM", self.do_select_kvm),
        ]

        actions = [
            (label, func) for atype, label, func in all_actions if atype in self.charm_class.allowed_assignment_types
        ]

        constraints = self.charm_class.constraints
        # NOTE: show_assignments=False is a WORKAROUND for #194
        self.machines_list = MachinesList(
            self.controller, actions, constraints=constraints, show_hardware=True, show_assignments=False
        )
        self.machines_list.update()
        close_button = AttrMap(Button("X", on_press=self.close_pressed), "button_secondary", "button_secondary focus")
        p = Pile(
            [
                GridFlow([close_button], 5, 1, 0, "right"),
                instructions,
                Divider(),
                self.service_widget,
                Divider(),
                self.machines_list,
            ]
        )

        return LineBox(p, title="Select Machine{}".format(plural_string))
class MachineChooser(WidgetWrap):

    """Presents list of machines to assign a service to.
    Supports multiple selection if the service does.
    """

    def __init__(self, controller, charm_class, parent_widget):
        self.controller = controller
        self.charm_class = charm_class
        self.parent_widget = parent_widget
        w = self.build_widgets()
        super().__init__(w)

    def build_widgets(self):

        if self.charm_class.allow_multi_units:
            machine_string = "machines"
            plural_string = "s"
        else:
            machine_string = "a machine"
            plural_string = ""
        instructions = Text("Select {} to host {}".format(machine_string, self.charm_class.display_name))

        self.service_widget = ServiceWidget(
            self.charm_class, self.controller, show_constraints=True, show_placements=True
        )

        all_actions = [
            (AssignmentType.BareMetal, "Add as Bare Metal", self.do_select_baremetal),
            (AssignmentType.LXC, "Add as LXC", self.do_select_lxc),
            (AssignmentType.KVM, "Add as KVM", self.do_select_kvm),
        ]

        actions = [
            (label, func) for atype, label, func in all_actions if atype in self.charm_class.allowed_assignment_types
        ]

        constraints = self.charm_class.constraints
        # NOTE: show_assignments=False is a WORKAROUND for #194
        self.machines_list = MachinesList(
            self.controller, actions, constraints=constraints, show_hardware=True, show_assignments=False
        )
        self.machines_list.update()
        close_button = AttrMap(Button("X", on_press=self.close_pressed), "button_secondary", "button_secondary focus")
        p = Pile(
            [
                GridFlow([close_button], 5, 1, 0, "right"),
                instructions,
                Divider(),
                self.service_widget,
                Divider(),
                self.machines_list,
            ]
        )

        return LineBox(p, title="Select Machine{}".format(plural_string))

    def do_select_baremetal(self, sender, machine):
        self.do_select(sender, machine, AssignmentType.BareMetal)

    def do_select_lxc(self, sender, machine):
        self.do_select(sender, machine, AssignmentType.LXC)

    def do_select_kvm(self, sender, machine):
        self.do_select(sender, machine, AssignmentType.KVM)

    def do_select(self, sender, machine, atype):
        self.controller.assign(machine, self.charm_class, atype)
        self.machines_list.update()
        self.service_widget.update()
        self.parent_widget.remove_overlay(self)

    def close_pressed(self, sender):
        self.parent_widget.remove_overlay(self)