@Override
  public void saveCurrentNode() {
    if (view.getPopupNode() != null) {
      // First loop through all the properties in the popup
      view.getProfilePropertyBoxes().forEach(this::savePropertyFromBox);

      List<Property> userDefinedProperties = new ArrayList<>();
      // Then loop through all the user defined properties in the popup and save them to package
      // state
      // The user checked the URI box but didn't enter a URI this should never happen with
      // validation, but fix it here
      view.getUserDefinedPropertyBoxes()
          .stream()
          .filter(
              userDefinedPropertyBox ->
                  userDefinedPropertyBox.getUserDefinedPropertyType() != null
                      && userDefinedPropertyBox.getUserDefinedPropertyValues() != null
                      && !userDefinedPropertyBox.getUserDefinedPropertyValues().isEmpty())
          .forEach(
              userDefinedPropertyBox -> {
                PropertyType propertyType = userDefinedPropertyBox.getUserDefinedPropertyType();

                // The user checked the URI box but didn't enter a URI this should never happen with
                // validation, but fix it here
                userDefinedPropertyBox
                    .getUserDefinedPropertyValues()
                    .stream()
                    .filter(
                        propertyBox ->
                            propertyBox.getValueAsString() != null
                                && !propertyBox.getValueAsString().isEmpty())
                    .forEach(
                        propertyBox -> {
                          Property newProperty = new Property(propertyType);

                          if (propertyType.getPropertyValueType() != null
                              && propertyType
                                  .getPropertyValueType()
                                  .equals(PropertyValueType.URI)) {
                            Validator uriValidator =
                                ValidatorFactory.getValidator(PropertyValueHint.URI);
                            if (uriValidator == null
                                || uriValidator.isValid(propertyBox.getValueAsString())) {
                              try {
                                newProperty.setUriValue(new URI(propertyBox.getValueAsString()));
                              } catch (URISyntaxException e) {
                                // The user checked the URI box but didn't enter a URI this should
                                // never happen with validation, but fix it here
                                newProperty
                                    .getPropertyType()
                                    .setPropertyValueType(PropertyValueType.STRING);
                                newProperty.setStringValue(propertyBox.getValueAsString());
                              }
                            }
                          } else {
                            newProperty.setStringValue(propertyBox.getValueAsString());
                          }

                          userDefinedProperties.add(newProperty);
                        });
              });

      if (controller.getPackageState().getUserSpecifiedProperties() == null) {
        controller.getPackageState().setUserSpecifiedProperties(new HashMap<>());
      }
      controller
          .getPackageState()
          .getUserSpecifiedProperties()
          .put(view.getPopupNode().getIdentifier(), userDefinedProperties);

      // apply metadata inheritance
      applyMetadataInheritance(view.getPopupNode());
    }
  }
  private List<Property> getPropertiesFromBox(ProfilePropertyBox propertyBox) {
    List<Property> properties = new ArrayList<>();
    if (propertyBox.getPropertyConstraint().getPropertyType().getPropertyValueType()
        != PropertyValueType.COMPLEX) {

      propertyBox
          .getValues()
          .stream()
          .filter(value -> value != null)
          .forEach(
              value -> {
                if (propertyBox.getPropertyConstraint().getPropertyType().getPropertyValueType()
                    != null) {
                  switch (propertyBox
                      .getPropertyConstraint()
                      .getPropertyType()
                      .getPropertyValueType()) {
                    case DATE_TIME:
                      Property newProperty =
                          new Property(propertyBox.getPropertyConstraint().getPropertyType());
                      newProperty.setDateTimeValue(
                          new DateTime(
                              ((LocalDate) value).getYear(),
                              ((LocalDate) value).getMonthValue(),
                              ((LocalDate) value).getDayOfMonth(),
                              0,
                              0,
                              0));
                      properties.add(newProperty);
                      break;
                    case LONG:
                      newProperty =
                          new Property(propertyBox.getPropertyConstraint().getPropertyType());
                      newProperty.setLongValue((Long) value);
                      properties.add(newProperty);
                      break;
                    default:
                      if (!((String) value).isEmpty()) {
                        // Only save valid properties
                        Validator validator = null;
                        if (propertyBox.getPropertyConstraint().getPropertyType() != null
                            && propertyBox
                                    .getPropertyConstraint()
                                    .getPropertyType()
                                    .getPropertyValueHint()
                                != null) {
                          validator =
                              ValidatorFactory.getValidator(
                                  propertyBox
                                      .getPropertyConstraint()
                                      .getPropertyType()
                                      .getPropertyValueHint());
                        }
                        if (validator == null || validator.isValid((String) value)) {
                          newProperty =
                              propertyFormatService.parsePropertyValue(
                                  propertyBox.getPropertyConstraint().getPropertyType(),
                                  (String) value);
                          properties.add(newProperty);
                        }
                      }
                  }
                } else {
                  if (value instanceof String) {
                    if (!((String) value).isEmpty()) {
                      // Only save valid properties
                      Validator validator = null;
                      if (propertyBox.getPropertyConstraint().getPropertyType() != null
                          && propertyBox
                                  .getPropertyConstraint()
                                  .getPropertyType()
                                  .getPropertyValueHint()
                              != null) {
                        validator =
                            ValidatorFactory.getValidator(
                                propertyBox
                                    .getPropertyConstraint()
                                    .getPropertyType()
                                    .getPropertyValueHint());
                      }
                      if (validator == null || validator.isValid((String) value)) {
                        Property newProperty =
                            propertyFormatService.parsePropertyValue(
                                propertyBox.getPropertyConstraint().getPropertyType(),
                                (String) value);
                        properties.add(newProperty);
                      }
                    }
                  }
                }
              });
    }

    return properties;
  }