/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
package org.apache.myfaces.extensions.validator.beanval.util;

import org.apache.myfaces.extensions.validator.beanval.ExtValBeanValidationContext;
import org.apache.myfaces.extensions.validator.beanval.payload.ViolationSeverity;
import org.apache.myfaces.extensions.validator.beanval.annotation.BeanValidation;
import org.apache.myfaces.extensions.validator.beanval.annotation.ModelValidation;
import org.apache.myfaces.extensions.validator.beanval.annotation.extractor.DefaultGroupControllerScanningExtractor;
import org.apache.myfaces.extensions.validator.beanval.storage.ModelValidationEntry;
import org.apache.myfaces.extensions.validator.core.el.ELHelper;
import org.apache.myfaces.extensions.validator.core.el.ValueBindingExpression;
import org.apache.myfaces.extensions.validator.core.metadata.MetaDataEntry;
import org.apache.myfaces.extensions.validator.core.property.PropertyDetails;
import org.apache.myfaces.extensions.validator.core.property.PropertyInformation;
import org.apache.myfaces.extensions.validator.core.validation.message.FacesMessageHolder;
import org.apache.myfaces.extensions.validator.internal.UsageCategory;
import org.apache.myfaces.extensions.validator.internal.UsageInformation;
import org.apache.myfaces.extensions.validator.internal.ToDo;
import org.apache.myfaces.extensions.validator.internal.Priority;
import org.apache.myfaces.extensions.validator.util.ExtValUtils;
import org.apache.myfaces.extensions.validator.util.ReflectionUtils;
import org.apache.myfaces.extensions.validator.util.ProxyUtils;

import javax.faces.application.FacesMessage;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.validator.ValidatorException;
import javax.validation.ConstraintViolation;
import javax.validation.Payload;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.logging.Logger;

/**
 * @author Gerhard Petracek
 * @since x.x.3
 */
@UsageInformation(UsageCategory.INTERNAL)
class ExtValBeanValidationMetaDataInternals
{
    private Logger logger;
    private LabeledMessageInternals labeledMessageInternals = new LabeledMessageInternals();
    private ELHelper elHelper;

    ExtValBeanValidationMetaDataInternals(Logger logger, ELHelper elHelper)
    {
        this.logger = logger;
        this.elHelper = elHelper;
    }

    void extractExtValBeanValidationMetaData(PropertyDetails propertyDetails,
                                             boolean processModelValidation,
                                             String[] key,
                                             Object firstBean,
                                             List<Class> foundGroupsForPropertyValidation,
                                             List<Class> restrictedGroupsForPropertyValidation,
                                             List<ModelValidationEntry> modelValidationEntryList,
                                             List<Class> restrictedGroupsForModelValidation,
                                             String activeViewId)
    {
        inspectFirstBean(processModelValidation,
                firstBean,
                foundGroupsForPropertyValidation,
                restrictedGroupsForPropertyValidation,
                modelValidationEntryList,
                restrictedGroupsForModelValidation,
                activeViewId);

        inspectFirstProperty(processModelValidation,
                key,
                firstBean,
                foundGroupsForPropertyValidation,
                restrictedGroupsForPropertyValidation,
                modelValidationEntryList,
                restrictedGroupsForModelValidation,
                activeViewId,
                key.length == 2);

        inspectBaseOfProperty(propertyDetails,
                processModelValidation,
                foundGroupsForPropertyValidation,
                restrictedGroupsForPropertyValidation,
                modelValidationEntryList,
                restrictedGroupsForModelValidation,
                activeViewId);

        inspectLastProperty(propertyDetails,
                processModelValidation,
                foundGroupsForPropertyValidation,
                restrictedGroupsForPropertyValidation,
                modelValidationEntryList,
                restrictedGroupsForModelValidation,
                activeViewId);
    }

    void processExtValBeanValidationMetaData(UIComponent component,
                                             PropertyDetails propertyDetails,
                                             List<Class> foundGroupsForPropertyValidation,
                                             List<Class> restrictedGroupsForPropertyValidation,
                                             List<ModelValidationEntry> modelValidationEntryList,
                                             List<Class> restrictedGroupsForModelValidation,
                                             String activeViewId)
    {
        ExtValBeanValidationContext extValBeanValidationContext = ExtValBeanValidationContext.getCurrentInstance();

        String clientId = component.getClientId(FacesContext.getCurrentInstance());

        processFoundGroups(extValBeanValidationContext, activeViewId, clientId,
                foundGroupsForPropertyValidation);

        processRestrictedGroups(extValBeanValidationContext, activeViewId, clientId,
                restrictedGroupsForPropertyValidation);

        initModelValidation(extValBeanValidationContext, component, propertyDetails,
                modelValidationEntryList, restrictedGroupsForModelValidation);
    }

    private void inspectFirstBean(boolean processModelValidation,
                                  Object firstBean,
                                  List<Class> foundGroupsForPropertyValidation,
                                  List<Class> restrictedGroupsForPropertyValidation,
                                  List<ModelValidationEntry> modelValidationEntryList,
                                  List<Class> restrictedGroupsForModelValidation,
                                  String activeViewId)
    {
        processClass(firstBean,
                foundGroupsForPropertyValidation,
                restrictedGroupsForPropertyValidation,
                modelValidationEntryList,
                restrictedGroupsForModelValidation,
                activeViewId,
                processModelValidation);
    }

    private void inspectFirstProperty(boolean processModelValidation,
                                      String[] key,
                                      Object firstBean,
                                      List<Class> foundGroupsForPropertyValidation,
                                      List<Class> restrictedGroupsForPropertyValidation,
                                      List<ModelValidationEntry> modelValidationEntryList,
                                      List<Class> restrictedGroupsForModelValidation,
                                      String activeViewId,
                                      boolean isLastProperty)
    {
        processFieldsAndProperties(key[0] + "." + key[1],
                firstBean,
                key[1],
                foundGroupsForPropertyValidation,
                restrictedGroupsForPropertyValidation,
                modelValidationEntryList,
                restrictedGroupsForModelValidation,
                activeViewId,
                processModelValidation,
                isLastProperty);
    }

    private void inspectBaseOfProperty(PropertyDetails propertyDetails,
                                       boolean processModelValidation,
                                       List<Class> foundGroupsForPropertyValidation,
                                       List<Class> restrictedGroupsForPropertyValidation,
                                       List<ModelValidationEntry> modelValidationEntryList,
                                       List<Class> restrictedGroupsForModelValidation,
                                       String activeViewId)
    {
        processClass(propertyDetails.getBaseObject(),
                foundGroupsForPropertyValidation,
                restrictedGroupsForPropertyValidation,
                modelValidationEntryList,
                restrictedGroupsForModelValidation,
                activeViewId,
                processModelValidation);
    }

    private void inspectLastProperty(PropertyDetails propertyDetails,
                                     boolean processModelValidation,
                                     List<Class> foundGroupsForPropertyValidation,
                                     List<Class> restrictedGroupsForPropertyValidation,
                                     List<ModelValidationEntry> modelValidationEntryList,
                                     List<Class> restrictedGroupsForModelValidation,
                                     String activeViewId)
    {
        processFieldsAndProperties(
                propertyDetails.getKey(),
                propertyDetails.getBaseObject(),
                propertyDetails.getProperty(),
                foundGroupsForPropertyValidation,
                restrictedGroupsForPropertyValidation,
                modelValidationEntryList,
                restrictedGroupsForModelValidation,
                activeViewId,
                processModelValidation,
                true);
    }

    private void processClass(Object objectToInspect,
                              List<Class> foundGroupsForPropertyValidation,
                              List<Class> restrictedGroupsForPropertyValidation,
                              List<ModelValidationEntry> modelValidationEntryList,
                              List<Class> restrictedGroupsForModelValidation,
                              String activeViewId,
                              boolean processModelValidation)
    {
        Class classToInspect = ProxyUtils.getUnproxiedClass(objectToInspect.getClass());

        while (!Object.class.getName().equals(classToInspect.getName()))
        {
            transferGroupValidationInformationToFoundGroups(objectToInspect,
                    foundGroupsForPropertyValidation,
                    restrictedGroupsForPropertyValidation,
                    modelValidationEntryList,
                    restrictedGroupsForModelValidation,
                    activeViewId,
                    processModelValidation);

            processInterfaces(objectToInspect.getClass(), objectToInspect,
                    foundGroupsForPropertyValidation,
                    restrictedGroupsForPropertyValidation,
                    modelValidationEntryList,
                    restrictedGroupsForModelValidation,
                    activeViewId,
                    processModelValidation);

            classToInspect = classToInspect.getSuperclass();
        }
    }

    private void processFieldsAndProperties(String key,
                                            Object base,
                                            String property,
                                            List<Class> foundGroupsForPropertyValidation,
                                            List<Class> restrictedGroupsForPropertyValidation,
                                            List<ModelValidationEntry> modelValidationEntryList,
                                            List<Class> restrictedGroupsForModelValidation,
                                            String activeViewId,
                                            boolean processModelValidation,
                                            boolean isLastProperty)
    {
        PropertyInformation propertyInformation = new DefaultGroupControllerScanningExtractor()
                .extract(FacesContext.getCurrentInstance(), new PropertyDetails(key, base, property));

        for (MetaDataEntry metaDataEntry : propertyInformation.getMetaDataEntries())
        {
            if (metaDataEntry.getValue() instanceof BeanValidation)
            {
                tryToProcessMetaData((BeanValidation) metaDataEntry.getValue(),
                        tryToCreateNewTarget(base, property, isLastProperty),
                        foundGroupsForPropertyValidation,
                        restrictedGroupsForPropertyValidation,
                        modelValidationEntryList,
                        restrictedGroupsForModelValidation,
                        activeViewId,
                        processModelValidation);
            }
            else if (metaDataEntry.getValue() instanceof BeanValidation.List)
            {
                for (BeanValidation currentBeanValidation : ((BeanValidation.List) metaDataEntry.getValue()).value())
                {
                    tryToProcessMetaData(currentBeanValidation,
                            tryToCreateNewTarget(base, property, isLastProperty),
                            foundGroupsForPropertyValidation,
                            restrictedGroupsForPropertyValidation,
                            modelValidationEntryList,
                            restrictedGroupsForModelValidation,
                            activeViewId,
                            processModelValidation);
                }
            }
        }
    }

    private Object tryToCreateNewTarget(Object base, String property, boolean isLastProperty)
    {
        if(isLastProperty)
        {
            return base;
        }

        Object result = getValueOfProperty(base, property);

        if (result == null)
        {
            return base;
        }

        return result;
    }

    private Object getValueOfProperty(Object base, String property)
    {
        property = property.substring(0, 1).toUpperCase() + property.substring(1, property.length());

        Class targetClass = ProxyUtils.getUnproxiedClass(base.getClass());

        Method targetMethod = ReflectionUtils.tryToGetMethod(targetClass, "get" + property);

        if (targetMethod == null)
        {
            targetMethod = ReflectionUtils.tryToGetMethod(targetClass, "is" + property);
        }

        if (targetMethod == null)
        {
            throw new IllegalStateException(
                    "class " + targetClass + " has no public get/is " + property.toLowerCase());
        }
        return ReflectionUtils.tryToInvokeMethod(base, targetMethod);
    }

    private void processFoundGroups(ExtValBeanValidationContext extValBeanValidationContext,
                                    String currentViewId,
                                    String clientId,
                                    List<Class> foundGroupsForPropertyValidation)
    {
        /*
         * add found groups to context
         */
        for (Class currentGroupClass : foundGroupsForPropertyValidation)
        {
            extValBeanValidationContext.addGroup(currentGroupClass, currentViewId, clientId);
        }
    }

    private void processRestrictedGroups(ExtValBeanValidationContext extValBeanValidationContext,
                                         String currentViewId,
                                         String clientId,
                                         List<Class> restrictedGroupsForPropertyValidation)
    {
        /*
         * add restricted groups
         */
        for (Class currentGroupClass : restrictedGroupsForPropertyValidation)
        {
            extValBeanValidationContext.restrictGroup(currentGroupClass, currentViewId, clientId);
        }
    }

    private void initModelValidation(ExtValBeanValidationContext extValBeanValidationContext,
                                     UIComponent component,
                                     PropertyDetails propertyDetails,
                                     List<ModelValidationEntry> modelValidationEntryList,
                                     List<Class> restrictedGroupsForModelValidation)
    {
        /*
         * add model validation entry list
         */
        for (ModelValidationEntry modelValidationEntry : modelValidationEntryList)
        {
            for (Class restrictedGroup : restrictedGroupsForModelValidation)
            {
                modelValidationEntry.removeGroup(restrictedGroup);
            }

            if (modelValidationEntry.getGroups().length > 0)
            {
                if (modelValidationEntry.getValidationTargets().isEmpty())
                {
                    modelValidationEntry.addValidationTarget(propertyDetails.getBaseObject());
                }
                modelValidationEntry.setComponent(component);
                extValBeanValidationContext.addModelValidationEntry(modelValidationEntry);
            }
        }
    }

    @ToDo(value = Priority.MEDIUM, description = "test proxy support")
    private void transferGroupValidationInformationToFoundGroups(
            Object objectToInspect,
            List<Class> foundGroupsForPropertyValidation,
            List<Class> restrictedGroupsForPropertyValidation,
            List<ModelValidationEntry> modelValidationEntryList,
            List<Class> restrictedGroupsForModelValidation,
            String activeViewId,
            boolean processModelValidation)
    {
        if (objectToInspect.getClass().isAnnotationPresent(BeanValidation.class))
        {
            tryToProcessMetaData(objectToInspect.getClass().getAnnotation(BeanValidation.class),
                    objectToInspect,
                    foundGroupsForPropertyValidation,
                    restrictedGroupsForPropertyValidation,
                    modelValidationEntryList,
                    restrictedGroupsForModelValidation,
                    activeViewId,
                    processModelValidation);
        }
        else if (objectToInspect.getClass().isAnnotationPresent(BeanValidation.List.class))
        {
            for (BeanValidation currentBeanValidation :
                    (objectToInspect.getClass().getAnnotation(BeanValidation.List.class)).value())
            {
                tryToProcessMetaData(currentBeanValidation,
                        objectToInspect,
                        foundGroupsForPropertyValidation,
                        restrictedGroupsForPropertyValidation,
                        modelValidationEntryList,
                        restrictedGroupsForModelValidation,
                        activeViewId,
                        processModelValidation);
            }
        }
    }

    private void processInterfaces(Class currentClass,
                                   Object metaDataSourceObject,
                                   List<Class> foundGroupsForPropertyValidation,
                                   List<Class> restrictedGroupsForPropertyValidation,
                                   List<ModelValidationEntry> modelValidationEntryList,
                                   List<Class> restrictedGroupsForModelValidation,
                                   String activeViewId,
                                   boolean processModelValidation)
    {
        for (Class currentInterface : currentClass.getInterfaces())
        {
            transferGroupValidationInformationToFoundGroups(metaDataSourceObject,
                    foundGroupsForPropertyValidation,
                    restrictedGroupsForPropertyValidation,
                    modelValidationEntryList,
                    restrictedGroupsForModelValidation,
                    activeViewId,
                    processModelValidation);

            processInterfaces(currentInterface, metaDataSourceObject,
                    foundGroupsForPropertyValidation,
                    restrictedGroupsForPropertyValidation,
                    modelValidationEntryList,
                    restrictedGroupsForModelValidation,
                    activeViewId,
                    processModelValidation);
        }
    }

    private void tryToProcessMetaData(BeanValidation beanValidation,
                                      Object metaDataSourceObject,
                                      List<Class> foundGroupsForPropertyValidation,
                                      List<Class> restrictedGroupsForPropertyValidation,
                                      List<ModelValidationEntry> modelValidationEntryList,
                                      List<Class> restrictedGroupsForModelValidation,
                                      String activeViewId,
                                      boolean processModelValidation)
    {
        for (String currentViewId : beanValidation.viewIds())
        {
            if (useMetaDataForViewId(beanValidation, currentViewId, activeViewId))
            {
                processMetaData(beanValidation,
                        metaDataSourceObject,
                        foundGroupsForPropertyValidation,
                        restrictedGroupsForPropertyValidation,
                        modelValidationEntryList,
                        restrictedGroupsForModelValidation,
                        processModelValidation);
                break;
            }
        }
    }

    private boolean useMetaDataForViewId(BeanValidation beanValidation, String viewId, String activeViewId)
    {
        return (viewId.equals(activeViewId) ||
                viewId.equals("*")) && isValidationPermitted(beanValidation);
    }

    private void processMetaData(BeanValidation beanValidation,
                                 Object metaDataSourceObject,
                                 List<Class> foundGroupsForPropertyValidation,
                                 List<Class> restrictedGroupsForPropertyValidation,
                                 List<ModelValidationEntry> modelValidationEntryList,
                                 List<Class> restrictedGroupsForModelValidation,
                                 boolean processModelValidation)
    {
        if (processModelValidation && isModelValidation(beanValidation))
        {
            addModelValidationEntry(
                    beanValidation, metaDataSourceObject,
                    modelValidationEntryList, restrictedGroupsForModelValidation);
        }
        else if (!isModelValidation(beanValidation))
        {
            processGroups(
                    beanValidation, foundGroupsForPropertyValidation, restrictedGroupsForPropertyValidation);
        }
    }

    private boolean isValidationPermitted(BeanValidation beanValidation)
    {
        FacesContext facesContext = FacesContext.getCurrentInstance();
        for (String condition : beanValidation.conditions())
        {
            if (elHelper.isELTermWellFormed(condition) &&
                    elHelper.isELTermValid(facesContext, condition))
            {
                if (Boolean.TRUE.equals(elHelper.getValueOfExpression(
                        facesContext, new ValueBindingExpression(condition))))
                {
                    return true;
                }
            }
            else
            {
                this.logger.severe("an invalid condition is used: " + condition);
            }
        }
        return false;
    }

    private boolean isModelValidation(BeanValidation beanValidation)
    {
        return beanValidation.modelValidation().isActive();
    }

    private void addModelValidationEntry(BeanValidation beanValidation,
                                         Object metaDataSourceObject,
                                         List<ModelValidationEntry> modelValidationEntryList,
                                         List<Class> restrictedGroupsForModelValidation)
    {
        ModelValidationEntry modelValidationEntry = new ModelValidationEntry();

        modelValidationEntry.setGroups(Arrays.asList(beanValidation.useGroups()));
        modelValidationEntry.setDisplayMessageInline(beanValidation.modelValidation().displayInline());
        modelValidationEntry.setCustomMessage(beanValidation.modelValidation().message());
        modelValidationEntry.setMetaDataSourceObject(metaDataSourceObject);

        Object validationTarget;
        for (String validationTargetExpression : beanValidation.modelValidation().validationTargets())
        {
            if (ModelValidation.DEFAULT.equals(validationTargetExpression))
            {
                continue;
            }

            validationTarget = tryToResolveValidationTargetExpression(validationTargetExpression);
            if (validationTarget != null)
            {
                modelValidationEntry.addValidationTarget(validationTarget);
            }
        }

        if (beanValidation.restrictGroups().length > 0)
        {
            restrictedGroupsForModelValidation.addAll(Arrays.asList(beanValidation.restrictGroups()));
        }

        if (modelValidationEntry.getValidationTargets().isEmpty())
        {
            modelValidationEntry.addValidationTarget(metaDataSourceObject);
        }

        modelValidationEntryList.add(modelValidationEntry);
    }

    private Object tryToResolveValidationTargetExpression(String validationTargetExpression)
    {
        ValueBindingExpression valueBindingExpression = new ValueBindingExpression(validationTargetExpression);
        return this.elHelper.getValueOfExpression(FacesContext.getCurrentInstance(), valueBindingExpression);
    }

    private void processGroups(BeanValidation beanValidation,
                               List<Class> foundGroupsForPropertyValidation,
                               List<Class> restrictedGroupsForPropertyValidation)
    {
        foundGroupsForPropertyValidation.addAll(Arrays.asList(beanValidation.useGroups()));

        if (beanValidation.restrictGroups().length > 0)
        {
            restrictedGroupsForPropertyValidation.addAll(Arrays.asList(beanValidation.restrictGroups()));
        }
    }

    String createLabeledMessage(String violationMessage, boolean isDetailMessage)
    {
        return this.labeledMessageInternals.createLabeledMessage(violationMessage, isDetailMessage);
    }

    FacesMessage.Severity calcSeverity(ConstraintViolation<Object> violation)
    {
        for (Class<? extends Payload> payload : violation.getConstraintDescriptor().getPayload())
        {
            if (ExtValUtils.getValidationParameterClassFor(ViolationSeverity.Warn.class).isAssignableFrom(payload))
            {
                return FacesMessage.SEVERITY_WARN;
            }
            else if (ExtValUtils
                    .getValidationParameterClassFor(ViolationSeverity.Info.class).isAssignableFrom(payload))
            {
                return FacesMessage.SEVERITY_INFO;
            }
            else if (ExtValUtils
                    .getValidationParameterClassFor(ViolationSeverity.Fatal.class).isAssignableFrom(payload))
            {
                return FacesMessage.SEVERITY_FATAL;
            }
        }
        return FacesMessage.SEVERITY_ERROR;
    }

    void processFacesMessage(FacesContext facesContext, UIComponent uiComponent,
                             List<FacesMessageHolder> facesMessageHolderList, FacesMessage facesMessage)
    {
        FacesMessageHolder facesMessageHolder = new FacesMessageHolder(facesMessage);

        facesMessageHolder.setClientId(uiComponent.getClientId(facesContext));

        facesMessageHolderList.add(facesMessageHolder);
    }

    boolean executeAfterThrowingInterceptors(UIComponent uiComponent,
                                             Object convertedObject,
                                             ValidatorException validatorException)
    {
        return ExtValUtils.executeAfterThrowingInterceptors(
                uiComponent,
                null,
                convertedObject,
                validatorException,
                null);
    }

    boolean isMessageTextUnchanged(
            ValidatorException validatorException, String violationSummaryMessage, String violationDetailMessage)
    {
        return violationSummaryMessage.equals(validatorException.getFacesMessage().getSummary()) &&
                violationDetailMessage.equals(validatorException.getFacesMessage().getDetail());
    }

    ValidatorException createValidatorException(
            String violationSummaryMessage, String violationDetailMessage, FacesMessage.Severity severity)
    {
        return new ValidatorException(
                ExtValUtils.createFacesMessage(severity, violationSummaryMessage, violationDetailMessage));
    }

    List<FacesMessageHolder> getFacesMessageListWithLowSeverity(
            List<FacesMessageHolder> violationMessages)
    {
        List<FacesMessageHolder> result = new ArrayList<FacesMessageHolder>();

        for (FacesMessageHolder facesMessageHolder : violationMessages)
        {
            if (FacesMessage.SEVERITY_WARN.equals(facesMessageHolder.getFacesMessage().getSeverity()) ||
                    FacesMessage.SEVERITY_INFO.equals(facesMessageHolder.getFacesMessage().getSeverity()))
            {
                result.add(facesMessageHolder);
            }
        }
        return result;
    }

    List<FacesMessageHolder> getFacesMessageListWithHighSeverity(
            List<FacesMessageHolder> violationMessageHolderList)
    {
        List<FacesMessageHolder> result = new ArrayList<FacesMessageHolder>();

        for (FacesMessageHolder facesMessageHolder : violationMessageHolderList)
        {
            if (FacesMessage.SEVERITY_ERROR.equals(facesMessageHolder.getFacesMessage().getSeverity()) ||
                    FacesMessage.SEVERITY_FATAL.equals(facesMessageHolder.getFacesMessage().getSeverity()))
            {
                result.add(facesMessageHolder);
            }
        }
        return result;
    }

    void addMessages(List<FacesMessageHolder> facesMessageHolderListWithLowSeverity)
    {
        for (FacesMessageHolder facesMessageHolder : facesMessageHolderListWithLowSeverity)
        {
            ExtValUtils.tryToAddViolationMessageForComponentId(
                    facesMessageHolder.getClientId(), facesMessageHolder.getFacesMessage());
        }
    }
}
