private PropertyInspector() {
    super(APPLICATION_NAME, ICE_RELAY_PROPERTIES_FILE, ICE_DIRECT_CONNECT_PROPERTIES_FILE);
    setGUIClientHelperEventHandler(
        new GUIClientHelperEventHandlerAdapter() {
          public void executeAfterEstablishingConnectionToQwerk(final String qwerkUserId) {
            updateViewPropertiesTable();
          }

          public void toggleGUIElementState(final boolean isEnabled) {
            toggleGUIElements(isEnabled);
          }
        });

    // CONFIGURE GUI ELEMENTS
    // ========================================================================================

    this.setFocusTraversalPolicy(new MyFocusTraversalPolicy());
    createPropertyButton.addActionListener(new CreatePropertyAction());
    final Map<String, String> tempServiceNameToTypeIdMap = new HashMap<String, String>();
    tempServiceNameToTypeIdMap.put(SERVICE_NAME_ANALOG, AnalogInputsService.TYPE_ID);
    tempServiceNameToTypeIdMap.put(SERVICE_NAME_AUDIO, AudioService.TYPE_ID);
    tempServiceNameToTypeIdMap.put(SERVICE_NAME_DIGITAL_IN, DigitalInService.TYPE_ID);
    tempServiceNameToTypeIdMap.put(SERVICE_NAME_DIGITAL_OUT, DigitalOutService.TYPE_ID);
    tempServiceNameToTypeIdMap.put(SERVICE_NAME_LED, LEDService.TYPE_ID);
    tempServiceNameToTypeIdMap.put(SERVICE_NAME_MOTOR, BackEMFMotorService.TYPE_ID);
    tempServiceNameToTypeIdMap.put(SERVICE_NAME_SERIAL, SerialIOService.TYPE_ID);
    tempServiceNameToTypeIdMap.put(SERVICE_NAME_SERVO, ServoService.TYPE_ID);
    tempServiceNameToTypeIdMap.put(SERVICE_NAME_VIDEO, VideoStreamService.TYPE_ID);
    serviceNameToTypeIdMap = Collections.unmodifiableMap(tempServiceNameToTypeIdMap);

    viewPropertiesServiceComboBox.addItemListener(
        new ItemListener() {
          public void itemStateChanged(final ItemEvent itemEvent) {
            updateViewPropertiesTable();
          }
        });

    reloadPropertiesButton.addActionListener(
        new ActionListener() {
          public void actionPerformed(final ActionEvent actionEvent) {
            updateViewPropertiesTable();
          }
        });

    final JScrollPane propertiesTableScrollPane = new JScrollPane(propertiesTable);
    propertiesTableScrollPane.setMinimumSize(TABLE_DIMENSIONS);
    propertiesTableScrollPane.setMaximumSize(TABLE_DIMENSIONS);
    propertiesTableScrollPane.setPreferredSize(TABLE_DIMENSIONS);

    toggleGUIElements(false);
    propertyKeyTextField.addKeyListener(propertyKeyKeyListener);

    // LAYOUT GUI ELEMENTS
    // ===========================================================================================

    // create a panel to hold the connect/disconnect button and the connection state labels
    final JPanel connectionPanel = new JPanel(new SpringLayout());
    connectionPanel.add(connectOrDisconnectButton);
    connectionPanel.add(getConnectionStatePanel());
    SpringLayoutUtilities.makeCompactGrid(
        connectionPanel,
        1,
        2, // rows, cols
        0,
        0, // initX, initY
        10,
        10); // xPad, yPad

    final JPanel createPropertyPanel = new JPanel(new SpringLayout());
    createPropertyPanel.setBorder(
        BorderFactory.createTitledBorder(RESOURCES.getString("border.title.create-property")));
    createPropertyPanel.add(GUIConstants.createLabel(RESOURCES.getString("label.service")));
    createPropertyPanel.add(createPropertyServiceComboBox);
    createPropertyPanel.add(createPropertyButton);
    createPropertyPanel.add(GUIConstants.createLabel(RESOURCES.getString("label.key")));
    createPropertyPanel.add(propertyKeyTextField);
    createPropertyPanel.add(Box.createGlue());
    createPropertyPanel.add(GUIConstants.createLabel(RESOURCES.getString("label.value")));
    createPropertyPanel.add(propertyValueTextField);
    createPropertyPanel.add(Box.createGlue());
    SpringLayoutUtilities.makeCompactGrid(
        createPropertyPanel,
        3,
        3, // rows, cols
        5,
        5, // initX, initY
        5,
        5); // xPad, yPad

    final JPanel serviceChooserPanel = new JPanel(new SpringLayout());
    serviceChooserPanel.add(GUIConstants.createLabel(RESOURCES.getString("label.service")));
    serviceChooserPanel.add(viewPropertiesServiceComboBox);
    serviceChooserPanel.add(reloadPropertiesButton);
    SpringLayoutUtilities.makeCompactGrid(
        serviceChooserPanel,
        1,
        3, // rows, cols
        5,
        5, // initX, initY
        5,
        5); // xPad, yPad

    final JPanel viewPropertiesPanel = new JPanel(new SpringLayout());
    viewPropertiesPanel.setBorder(
        BorderFactory.createTitledBorder(RESOURCES.getString("border.title.view-propertes")));
    viewPropertiesPanel.add(serviceChooserPanel);
    viewPropertiesPanel.add(propertiesTableScrollPane);
    SpringLayoutUtilities.makeCompactGrid(
        viewPropertiesPanel,
        2,
        1, // rows, cols
        5,
        5, // initX, initY
        5,
        5); // xPad, yPad

    // Layout the main content pane using SpringLayout
    getMainContentPane().setLayout(new SpringLayout());
    getMainContentPane().add(connectionPanel);
    getMainContentPane().add(createPropertyPanel);
    getMainContentPane().add(viewPropertiesPanel);
    SpringLayoutUtilities.makeCompactGrid(
        getMainContentPane(),
        3,
        1, // rows, cols
        10,
        10, // initX, initY
        10,
        10); // xPad, yPad

    pack();
    setLocationRelativeTo(null); // center the window on the screen
    setVisible(true);
  }