gt:     protected GwtConfigComponent getUpdatedConfiguration() {
context: /*******************************************************************************
   * Copyright (c) 2016, 2017 Eurotech and/or its affiliates and others
   *
   * All rights reserved. This program and the accompanying materials
   * are made available under the terms of the Eclipse Public License v1.0
   * which accompanies this distribution, and is available at
   * http://www.eclipse.org/legal/epl-v10.html
   *
   * Contributors:
   *  Eurotech
   *  Amit Kumar Mondal
   *
   *******************************************************************************/
  /**
   * Render the Content in the Wire Component Properties Panel based on Service (GwtBSConfigComponent) selected in Wire graph
   *
   * Fields are rendered based on their type (Password(Input), Choice(Dropboxes) etc. with Text fields rendered
   * for both numeric and other textual field with validate() checking if value in numeric fields is numeric
   */
  package org.eclipse.kura.web.client.ui.wires;
  
  import static org.eclipse.kura.web.shared.AssetConstants.CHANNEL_PROPERTY_SEPARATOR;
  
  import java.util.ArrayList;
  import java.util.Arrays;
  import java.util.HashMap;
  import java.util.HashSet;
  import java.util.Iterator;
  import java.util.List;
  import java.util.Map;
  import java.util.Set;
  import java.util.logging.Level;
  
  import org.eclipse.kura.web.client.ui.AbstractServicesUi;
  import org.eclipse.kura.web.client.ui.EntryClassUi;
  import org.eclipse.kura.web.client.util.FailureHandler;
  import org.eclipse.kura.web.shared.AssetConstants;
  import org.eclipse.kura.web.shared.model.GwtChannelInfo;
  import org.eclipse.kura.web.shared.model.GwtConfigComponent;
  import org.eclipse.kura.web.shared.model.GwtConfigParameter;
  import org.eclipse.kura.web.shared.model.GwtConfigParameter.GwtConfigParameterType;
  import org.eclipse.kura.web.shared.model.GwtWiresChannelType;
  import org.eclipse.kura.web.shared.model.GwtWiresDataType;
  import org.eclipse.kura.web.shared.model.GwtXSRFToken;
  import org.eclipse.kura.web.shared.service.GwtSecurityTokenService;
  import org.eclipse.kura.web.shared.service.GwtSecurityTokenServiceAsync;
  import org.eclipse.kura.web.shared.service.GwtWireService;
  import org.eclipse.kura.web.shared.service.GwtWireServiceAsync;
  import org.gwtbootstrap3.client.ui.Alert;
  import org.gwtbootstrap3.client.ui.Button;
  import org.gwtbootstrap3.client.ui.FieldSet;
  import org.gwtbootstrap3.client.ui.FormGroup;
  import org.gwtbootstrap3.client.ui.FormLabel;
  import org.gwtbootstrap3.client.ui.Modal;
  import org.gwtbootstrap3.client.ui.Panel;
  import org.gwtbootstrap3.client.ui.TextBox;
  import org.gwtbootstrap3.client.ui.gwt.CellTable;
  import org.gwtbootstrap3.client.ui.html.Strong;
  import org.gwtbootstrap3.client.ui.html.Text;
  
  import com.google.gwt.cell.client.FieldUpdater;
  import com.google.gwt.cell.client.SelectionCell;
  import com.google.gwt.cell.client.TextCell;
  import com.google.gwt.core.client.GWT;
  import com.google.gwt.event.dom.client.ClickEvent;
  import com.google.gwt.event.dom.client.ClickHandler;
  import com.google.gwt.event.dom.client.KeyUpEvent;
  import com.google.gwt.event.dom.client.KeyUpHandler;
  import com.google.gwt.uibinder.client.UiBinder;
  import com.google.gwt.uibinder.client.UiField;
  import com.google.gwt.user.cellview.client.Column;
  import com.google.gwt.user.cellview.client.DefaultHeaderOrFooterBuilder;
  import com.google.gwt.user.cellview.client.SimplePager;
  import com.google.gwt.user.cellview.client.TextHeader;
  import com.google.gwt.user.client.rpc.AsyncCallback;
  import com.google.gwt.user.client.ui.Widget;
  import com.google.gwt.view.client.ListDataProvider;
  import com.google.gwt.view.client.SelectionChangeEvent;
  import com.google.gwt.view.client.SingleSelectionModel;
  
  public class PropertiesUi extends AbstractServicesUi {
  
      interface ServicesUiUiBinder extends UiBinder<Widget, PropertiesUi> {
      }
  
      @UiField
      Button btnAdd;
      @UiField
      Button btnRemove;
      @UiField
      Button btnDownload;
      @UiField
      Button btnUpload;
  
      @UiField
      SimplePager channelPager;
      @UiField
      Panel channelPanel;
  
      @UiField
      CellTable<GwtChannelInfo> channelTable;
  
      @UiField
      Strong channelTitle;
      @UiField
      FieldSet fields;
  
      @UiField
      Alert incompleteFields;
  
      @UiField
      Modal incompleteFieldsModal;
  
      @UiField
      Text incompleteFieldsText;
  
      @UiField
      Modal newChannelModal;
      @UiField
      FormLabel newChannelNameLabel;
      @UiField
      FormLabel newChannelNameError;
      @UiField
      TextBox newChannelNameInput;
      @UiField
      Button btnCreateNewChannel;
      @UiField
      Button btnCancelCreatingNewChannel;
  
      private static final String INVALID_CLASS_NAME = "error-text-box";
  
      private static final int MAXIMUM_PAGE_SIZE = 5;
  
      private static ServicesUiUiBinder uiBinder = GWT.create(ServicesUiUiBinder.class);
  
      private final GwtWireServiceAsync gwtWireService = GWT.create(GwtWireService.class);
  
      private final GwtSecurityTokenServiceAsync gwtXSRFService = GWT.create(GwtSecurityTokenService.class);
  
      private final ListDataProvider<GwtChannelInfo> channelsDataProvider = new ListDataProvider<>();
  
      private final SingleSelectionModel<GwtChannelInfo> selectionModel = new SingleSelectionModel<>();
  
      private final String pid;
  
      private final Set<String> nonValidatedCells;
  
      private boolean dirty;
      private boolean isWireAsset = false;
  
      private GwtConfigComponent baseDriverDescriptor;
      private GwtConfigComponent driverDescriptor;
  
      private boolean nonValidated;
  
      public PropertiesUi(final GwtConfigComponent addedItem, final String pid) {
          initWidget(uiBinder.createAndBindUi(this));
          this.pid = pid;
          this.configurableComponent = addedItem;
          this.fields.clear();
  
          this.channelPager.setPageSize(MAXIMUM_PAGE_SIZE);
          this.channelPager.setDisplay(this.channelTable);
          this.channelTable.setSelectionModel(this.selectionModel);
          this.channelsDataProvider.addDataDisplay(this.channelTable);
          this.channelPanel.setVisible(false);
          this.btnRemove.setEnabled(false);
  
          this.nonValidatedCells = new HashSet<>();
          this.isWireAsset = this.configurableComponent.getFactoryId() != null
                  && this.configurableComponent.getFactoryId().contains("WireAsset");
  
          if (this.isWireAsset) {
              PropertiesUi.this.channelTitle.setText(MSGS.channelTableTitle(
                      PropertiesUi.this.configurableComponent.get(AssetConstants.ASSET_DRIVER_PROP.value()).toString()));
          }
  
          this.btnDownload.addClickHandler(new ClickHandler() {
  
              @Override
              public void onClick(final ClickEvent event) {
                  for (final GwtChannelInfo info : PropertiesUi.this.channelsDataProvider.getList()) {
                      logger.log(Level.SEVERE, info.getName());
                      for (final Map.Entry<String, Object> entry : info.getProperties().entrySet()) {
                          final String key = entry.getKey();
                          final String value = String.valueOf(entry.getValue());
                          logger.log(Level.SEVERE, key + "<==>" + value);
                      }
                  }
  
              }
          });
  
          this.btnAdd.addClickHandler(new ClickHandler() {
  
              @Override
              public void onClick(final ClickEvent event) {
                  PropertiesUi.this.newChannelNameInput.setText(getNewChannelName());
                  PropertiesUi.this.newChannelModal.show();
              }
          });
  
          this.selectionModel.addSelectionChangeHandler(new SelectionChangeEvent.Handler() {
  
              @Override
              public void onSelectionChange(final SelectionChangeEvent event) {
                  PropertiesUi.this.btnRemove.setEnabled(PropertiesUi.this.selectionModel.getSelectedObject() != null);
              }
          });
  
          renderForm();
          initInvalidDataModal();
          initNewChannelModal();
  
          setDirty(false);
      }
  
      public GwtConfigComponent getConfiguration() {
          return this.configurableComponent;
      }
  
      @Override
      public boolean isDirty() {
          return this.dirty;
      }
  
      public boolean isNonValidated() {
          return this.nonValidated;
      }
  
      // TODO: Separate render methods for each type (ex: Boolean, String,
      // Password, etc.). See latest org.eclipse.kura.web code.
      // Iterates through all GwtConfigParameter in the selected
      // GwtConfigComponent
      @Override
      public void renderForm() {
          this.fields.clear();
          for (final GwtConfigParameter param : this.configurableComponent.getParameters()) {
              final String[] tokens = param.getId().split(CHANNEL_PROPERTY_SEPARATOR.value());
              boolean isChannelData = tokens.length == 2;
              final boolean isDriverField = param.getId().equals(AssetConstants.ASSET_DRIVER_PROP.value());
  
              isChannelData = isChannelData && this.isWireAsset;
              if (!isChannelData && !isDriverField) {
                  if (param.getCardinality() == 0 || param.getCardinality() == 1 || param.getCardinality() == -1) {
                      final FormGroup formGroup = new FormGroup();
                      renderConfigParameter(param, true, formGroup);
                  } else {
                      renderMultiFieldConfigParameter(param);
                  }
              }
          }
  
          if (this.isWireAsset) {
              EntryClassUi.showWaitModal();
              this.gwtXSRFService.generateSecurityToken(new GetAssetDataCallback());
          }
  
      }
  
      private abstract class BaseAsyncCallback<T> implements AsyncCallback<T> {
  
          @Override
          public void onFailure(Throwable caught) {
              EntryClassUi.hideWaitModal();
              FailureHandler.handle(caught);
          }
      }
  
      private final class GetAssetDataCallback extends BaseAsyncCallback<GwtXSRFToken> {
  
          @Override
          public void onSuccess(GwtXSRFToken result) {
              PropertiesUi.this.gwtWireService.getGwtBaseChannelDescriptor(result,
                      new BaseAsyncCallback<GwtConfigComponent>() {
  
                          @Override
                          public void onSuccess(GwtConfigComponent result) {
                              PropertiesUi.this.baseDriverDescriptor = result;
                              PropertiesUi.this.gwtXSRFService
                                      .generateSecurityToken(new BaseAsyncCallback<GwtXSRFToken>() {
  
                                          @Override
                                          public void onSuccess(final GwtXSRFToken result) {
                                              PropertiesUi.this.gwtWireService.getGwtChannelDescriptor(result,
                                                      PropertiesUi.this.configurableComponent
                                                              .get(AssetConstants.ASSET_DRIVER_PROP.value()).toString(),
                                                      new BaseAsyncCallback<GwtConfigComponent>() {
  
                                                          @Override
                                                          public void onSuccess(final GwtConfigComponent result) {
                                                              PropertiesUi.this.driverDescriptor = result;
                                                              PropertiesUi.this.addDefaultColumns();
                                                              for (final GwtConfigParameter param : result
                                                                      .getParameters()) {
                                                                  PropertiesUi.this.channelTable.addColumn(
                                                                          PropertiesUi.this.getColumnFromParam(param),
                                                                          new TextHeader(param.getName()));
                                                              }
  
                                                              PropertiesUi.this.gwtXSRFService.generateSecurityToken(
                                                                      new GetChannelDataCallback());
                                                          }
                                                      });
                                          }
                                      });
                          }
  
                      });
          }
      }
  
      private final class GetChannelDataCallback extends BaseAsyncCallback<GwtXSRFToken> {
  
          @Override
          public void onSuccess(final GwtXSRFToken result) {
              PropertiesUi.this.gwtWireService.getGwtChannels(result, PropertiesUi.this.driverDescriptor,
                      PropertiesUi.this.configurableComponent, new BaseAsyncCallback<List<GwtChannelInfo>>() {
  
                          @Override
                          public void onSuccess(List<GwtChannelInfo> result) {
                              for (GwtChannelInfo channelInfo : result) {
                                  channelInfo.setUnescaped(true);
                              }
                              PropertiesUi.this.channelsDataProvider.getList().clear();
                              PropertiesUi.this.channelsDataProvider.getList().addAll(result);
                              PropertiesUi.this.channelsDataProvider.refresh();
                              PropertiesUi.this.channelPanel.setVisible(true);
                              EntryClassUi.hideWaitModal();
                          }
                      });
          }
      }
  
      @Override
      public void setDirty(final boolean flag) {
          this.dirty = flag;
          if (flag) {
              WiresPanelUi.propertiesPanelHeader.setText(
                      WiresPanelUi.getFormattedPid(this.configurableComponent.getFactoryId()) + " - " + this.pid + "*");
              WiresPanelUi.setDirty(true);
          } else {
              WiresPanelUi.propertiesPanelHeader.setText(
                      WiresPanelUi.getFormattedPid(this.configurableComponent.getFactoryId()) + " - " + this.pid);
          }
      }
  
      public void setNonValidated(final boolean flag) {
          this.nonValidated = flag;
          if (flag) {
              WiresPanelUi.propertiesPanelHeader.setText(
                      WiresPanelUi.getFormattedPid(this.configurableComponent.getFactoryId()) + " - " + this.pid + "*");
              WiresPanelUi.btnSave.setEnabled(false);
          } else if (this.nonValidatedCells.isEmpty()) {
              WiresPanelUi.propertiesPanelHeader.setText(
                      WiresPanelUi.getFormattedPid(this.configurableComponent.getFactoryId()) + " - " + this.pid);
              WiresPanelUi.btnSave.setEnabled(true);
          }
      }
  
      // Get updated parameters
  