private void propagateDatas(boolean isExecute) {
    String baseConnectorForCurrentNode =
        node.getConnectorFromName(currentConnector).getBaseSchema();

    // Propagate :
    if (outputdataContainer != null
        && (!outputdataContainer.getInputs().isEmpty()
            || !outputdataContainer.getOuputs().isEmpty())) {
      for (IODataComponent currentIO : outputdataContainer.getInputs()) {
        INode sourceNode = currentIO.getSource();
        if (currentIO.hasChanged()
            && (sourceNode
                .getConnectorFromName(currentIO.getConnection().getConnectorName())
                .getBaseSchema()
                .equals(baseConnectorForCurrentNode))) {
          sourceNode.metadataOutputChanged(currentIO, currentIO.getName());
          if (isExecute) {
            currentIO.setTable(oldInputMetadata);
            currentIO.setColumnNameChanged(null);
          } else {
            currentIO.setTable(newInputMetadata);
            currentIO.setColumnNameChanged(null);
          }
        }
      }
      for (IODataComponent currentIO : outputdataContainer.getOuputs()) {
        INodeConnector nodeConnector = null;
        String baseConnector = null;

        Node sourceNode = (Node) currentIO.getSource();
        nodeConnector =
            sourceNode.getConnectorFromName(currentIO.getConnection().getConnectorName());
        baseConnector = nodeConnector.getBaseSchema();

        INode targetNode = currentIO.getTarget();

        boolean sourceIsBuiltIn =
            ((Node) currentIO.getSource())
                .getConnectorFromType(currentIO.getConnection().getLineStyle())
                .isMultiSchema();

        boolean targetIsBuiltIn =
            ((Node) targetNode)
                .getConnectorFromType(currentIO.getConnection().getLineStyle())
                .isMultiSchema();
        boolean isJoblet = ((Node) targetNode).isJoblet();
        if (!isJoblet
            && baseConnector.equals(baseConnectorForCurrentNode)
            && (targetIsBuiltIn
                || (targetNode.getMetadataFromConnector(baseConnector) != null
                    && !targetNode
                        .getMetadataFromConnector(baseConnector)
                        .sameMetadataAs(newOutputMetadata)))) {

          targetNode.metadataInputChanged(currentIO, currentIO.getUniqueName());
          if (isExecute) {
            if (targetNode instanceof Node) {
              if (((Node) targetNode).getComponent().isSchemaAutoPropagated()
                  && getPropagate()
                  && targetNode.getMetadataList().size() > 0) {
                IMetadataTable tmpClone;
                if (sourceIsBuiltIn) {
                  IMetadataTable tab =
                      node.getMetadataTable(
                          currentIO.getConnection().getMetadataTable().getTableName());
                  if (tab == null && node.getJobletNode() != null) {
                    tab =
                        node.getJobletNode()
                            .getMetadataTable(
                                currentIO.getConnection().getMetadataTable().getTableName());
                  }
                  tmpClone = tab.clone(true);
                } else {
                  IMetadataTable tab =
                      node.getMetadataFromConnector(currentIO.getConnection().getConnectorName());
                  if (tab == null && node.getJobletNode() != null) {
                    tab =
                        node.getJobletNode()
                            .getMetadataFromConnector(currentIO.getConnection().getConnectorName());
                  }
                  tmpClone = tab.clone(true);
                }
                IMetadataTable toCopy = newOutputMetadata.clone();

                // wzhang modify to add feature 7611

                String dbmsId = null;
                IMetadataTable copy;
                if (((Node) targetNode).getMetadataFromConnector(baseConnector) != null) {
                  dbmsId = targetNode.getMetadataFromConnector(baseConnector).getDbms();
                  MetadataToolHelper.copyTable(dbmsId, toCopy, tmpClone);
                  toCopy = tmpClone;

                  // only if the target node have exactly the same connector
                  copy = ((Node) targetNode).getMetadataFromConnector(baseConnector).clone(true);
                } else {
                  final String mainConnector =
                      "FLOW"; // can only be FLOW right now for this case. //$NON-NLS-1$

                  dbmsId = targetNode.getMetadataFromConnector(mainConnector).getDbms();
                  MetadataToolHelper.copyTable(dbmsId, toCopy, tmpClone);
                  toCopy = tmpClone;
                  // if don't have the same connector, take the main connector of the component.

                  copy = ((Node) targetNode).getMetadataFromConnector(mainConnector).clone(true);
                }
                // MetadataTool.copyTable(toCopy, copy);
                // wzhang modify to add feature 7611
                MetadataToolHelper.copyTable(dbmsId, toCopy, copy);
                ChangeMetadataCommand cmd =
                    new ChangeMetadataCommand(targetNode, null, null, copy, inputSchemaParam);
                if (outputdataContainer.getOuputs().size() > 0) {
                  List<ColumnNameChanged> columnNameChanged =
                      outputdataContainer.getOuputs().get(0).getColumnNameChanged();
                  for (IODataComponent dataComp : cmd.outputdataContainer.getOuputs()) {
                    dataComp.setColumnNameChanged(columnNameChanged);
                  }
                }
                cmd.execute(true);
                propagatedChange.add(cmd);
              }
            }
            currentIO.setTable(oldOutputMetadata);
            currentIO.setColumnNameChanged(null);
          } else {
            if (targetNode instanceof Node) {
              if (!targetIsBuiltIn && getPropagate()) {
                if (((Node) targetNode).getComponent().isSchemaAutoPropagated()) {
                  if (outputdataContainer.getOuputs().size() > 0) {
                    List<ColumnNameChanged> columnNameChanged =
                        outputdataContainer.getOuputs().get(0).getColumnNameChanged();
                    for (ChangeMetadataCommand cmd : propagatedChange) {
                      for (IODataComponent dataComp : cmd.outputdataContainer.getOuputs()) {
                        dataComp.setColumnNameChanged(columnNameChanged);
                      }
                    }
                  }
                }
              }
            }

            currentIO.setTable(newOutputMetadata);
            currentIO.setColumnNameChanged(null);
          }
        }
      }
    } else if (dataComponent != null) {
      for (IConnection outgoingConnection : node.getOutgoingConnections()) {
        if (outgoingConnection.getConnectorName().equals(currentConnector)) {
          outgoingConnection
              .getTarget()
              .metadataInputChanged(dataComponent, outgoingConnection.getName());
        }
      }
    } else {
      if (!node.getOutgoingConnections().isEmpty()) {
        IMetadataTable relativeOldOutputMetadata = null;
        IMetadataTable relativeNewOutputMetadata = null;
        if (isExecute) {
          relativeOldOutputMetadata = oldOutputMetadata;
          relativeNewOutputMetadata = newOutputMetadata;
        } else {
          relativeOldOutputMetadata = newOutputMetadata;
          relativeNewOutputMetadata = oldOutputMetadata;
        }
        for (IConnection outgoingConnection : node.getOutgoingConnections()) {
          final Node target = (Node) outgoingConnection.getTarget();
          if (target != null && target.getExternalNode() != null) {
            List<IMetadataColumn> oldListColumns = relativeOldOutputMetadata.getListColumns();
            List<IMetadataColumn> newListColumns = relativeNewOutputMetadata.getListColumns();
            List<ColumnNameChanged> columnNameChanges = new ArrayList<ColumnNameChanged>();
            int size = oldListColumns.size();
            int newSize = newListColumns.size();
            if (newSize < size) {
              size = newSize;
            }
            IODataComponent output =
                new IODataComponent(outgoingConnection, relativeNewOutputMetadata);
            if (newListColumns != null) {
              List<ColumnNameChanged> newColumnsList = output.getNewMetadataColumns();
              // new added columns list
              Set<String> newAddedColumns = new HashSet<String>();
              // newest columns after user changed
              Set<String> newestColumns = new HashSet<String>();

              // init
              if (newColumnsList != null) {
                for (ColumnNameChanged columnChanged : newColumnsList) {
                  newAddedColumns.add(columnChanged.getNewName());
                }
              }
              for (IMetadataColumn metadataColumn : newListColumns) {
                newestColumns.add(metadataColumn.getLabel());
              }

              // check
              for (int i = 0; i < size; i++) {
                IMetadataColumn oldMetadataColumn = oldListColumns.get(i);
                String columnName = oldMetadataColumn.getLabel();
                // if this column(before changing) is not exists in the new columns(after changing),
                // there are two possible truth: 1. this column has been renamed; 2. this column has
                // been removed
                if (!newestColumns.contains(columnName)) {
                  IMetadataColumn newMetadataColumn = newListColumns.get(i);
                  String newColumnNameAtThisIndex = newMetadataColumn.getLabel();
                  // if the column at the same position in new table is a new column(two possible
                  // truth: 1. an old column's name has been changed; 2. user add a new column);
                  // For now, Seems it is very hard to judge whether it is a renamed column or a new
                  // column, so we suppose the more possible truth is that it is a renamed column
                  if (newAddedColumns.contains(newColumnNameAtThisIndex)) {
                    columnNameChanges.add(
                        new ColumnNameChanged(columnName, newColumnNameAtThisIndex));
                  }
                }
              }
            }

            if (GlobalServiceRegister.getDefault().isServiceRegistered(IXmlMapService.class)) {
              final IXmlMapService service =
                  (IXmlMapService)
                      GlobalServiceRegister.getDefault().getService(IXmlMapService.class);
              if (service.isXmlMapComponent(target.getExternalNode())) {
                output.setColumnNameChanged(columnNameChanges);
                target.metadataInputChanged(output, outgoingConnection.getName());
              }
            }
            if (GlobalServiceRegister.getDefault().isServiceRegistered(ISparkMapService.class)) {
              final ISparkMapService service =
                  (ISparkMapService)
                      GlobalServiceRegister.getDefault().getService(ISparkMapService.class);
              if (service.isSparkMapComponent(target.getExternalNode())) {
                output.setColumnNameChanged(columnNameChanges);
                target.metadataInputChanged(output, outgoingConnection.getName());
              }
            }

            if (GlobalServiceRegister.getDefault().isServiceRegistered(IDbMapService.class)) {
              final IDbMapService service =
                  (IDbMapService)
                      GlobalServiceRegister.getDefault().getService(IDbMapService.class);
              if (service.isDbMapComponent(target.getExternalNode())) {
                // TDI-25307:should setColumNameChanged here for ELtDbMap in case the propagate
                // schema
                // does not affect it.
                output.setColumnNameChanged(columnNameChanges);
                target.metadataInputChanged(output, outgoingConnection.getName());
              }
            }
          }
        }
      }
    }

    if (inputdataContainer != null) {
      for (IODataComponent currentIO : inputdataContainer.getOuputs()) {
        if (currentIO.hasChanged()
            && (currentIO
                .getSource()
                .getConnectorFromName(currentIO.getConnection().getConnectorName())
                .getBaseSchema()
                .equals(currentConnector))) {
          INode targetNode = currentIO.getTarget();
          targetNode.metadataInputChanged(currentIO, currentIO.getUniqueName());
          if (isExecute) {
            currentIO.setTable(oldInputMetadata);
            currentIO.setColumnNameChanged(null);
          } else {
            currentIO.setTable(newInputMetadata);
            currentIO.setColumnNameChanged(null);
          }
        }
      }
    }
    // End propagate
  }
  @Override
  public String getDescription() {

    StringBuilder sb = new StringBuilder();

    String separator = " - "; // $NON-NLS-1$
    if (entry instanceof TreeNode) {

      TreeNode inputEntry = (TreeNode) entry;
      IMetadataColumn metadataColumn = null;
      if (inputEntry.eContainer() instanceof InputXmlTree) {
        InputXmlTree tree = (InputXmlTree) inputEntry.eContainer();
        List<IODataComponent> inputs =
            mapperManager.getMapperComponent().getIODataComponents().getInputs();
        IMetadataTable table = null;
        for (int i = 0; i < inputs.size(); i++) {
          IODataComponent ioDataComponent = inputs.get(i);
          if (tree.getName() != null
              && tree.getName().equals(ioDataComponent.getConnection().getName())) {
            table = ioDataComponent.getTable();
            break;
          }
        }
        if (table != null && table.getListColumns() != null) {
          for (IMetadataColumn column : table.getListColumns()) {
            if (inputEntry.getName().equals(column.getLabel())) {
              metadataColumn = column;
            }
          }
        }
      }
      sb.append(Messages.getString("EntryContentProposal.metadataColumn"))
          .append(" '")
          .append(inputEntry.getName()) // $NON-NLS-1$ //$NON-NLS-2$
          .append("' "); // $NON-NLS-1$
      sb.append(
          Messages.getString(
              "EntryContentProposal.properties")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
                                                   // //$NON-NLS-4$
      sb.append(CARRIAGE_RETURN);
      sb.append(separator)
          .append(Messages.getString("EntryContentProposal.column"))
          .append(inputEntry.getName()); // $NON-NLS-1$
      sb.append(CARRIAGE_RETURN);
      sb.append(separator)
          .append(Messages.getString("EntryContentProposal.key"))
          .append(inputEntry.isKey()); // $NON-NLS-1$
      sb.append(CARRIAGE_RETURN);
      sb.append(separator)
          .append(Messages.getString("EntryContentProposal.type"))
          .append(format(inputEntry.getType())); // $NON-NLS-1$
      if (metadataColumn != null) {
        sb.append(CARRIAGE_RETURN);
        sb.append(separator)
            .append(Messages.getString("EntryContentProposal.length")); // $NON-NLS-1$
        if (metadataColumn.getLength() != null && metadataColumn.getLength() > 0) {
          sb.append(format(metadataColumn.getLength()));
        }

        sb.append(CARRIAGE_RETURN);
        sb.append(separator)
            .append(Messages.getString("EntryContentProposal.precision")); // $NON-NLS-1$
        if (metadataColumn.getPrecision() != null && metadataColumn.getPrecision() > 0) {
          sb.append(format(metadataColumn.getPrecision()));
        }
        sb.append(CARRIAGE_RETURN);
        sb.append(separator)
            .append(Messages.getString("EntryContentProposal.default"))
            .append(format(metadataColumn.getDefault())); // $NON-NLS-1$
        sb.append(CARRIAGE_RETURN);
        sb.append(separator)
            .append(Messages.getString("EntryContentProposal.comment"))
            .append(format(metadataColumn.getComment())); // $NON-NLS-1$
      }
      sb.append(CARRIAGE_RETURN);
      if (inputEntry.eContainer() instanceof TreeNode) {
        sb.append(separator)
            .append(Messages.getString("EntryContentProposal.xPath"))
            .append(inputEntry.getXpath()); // $NON-NLS-1$
        sb.append(CARRIAGE_RETURN);
      }
      sb.append(separator)
          .append(Messages.getString("EntryContentProposal.expressionKey")); // $NON-NLS-1$
      sb.append(CARRIAGE_RETURN);
      sb.append(format(entry.getExpression()));
      sb.append(CARRIAGE_RETURN);

    } else if (entry instanceof VarNode) {
      sb.append(Messages.getString("EntryContentProposal.variable"))
          .append(" '")
          .append(entry.getName())
          .append("' :"); // $NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$
      sb.append(CARRIAGE_RETURN);
      sb.append(separator)
          .append(Messages.getString("EntryContentProposal.expressionKey")); // $NON-NLS-1$
      sb.append(CARRIAGE_RETURN);
      sb.append(format(entry.getExpression()));
    }
    return sb.toString();
  }