/*******************************************************************************
 * Copyright (c) 2001, 2004 IBM Corporation 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:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/

package org.eclipse.wst.wsdl.validation.internal.wsdl11;

import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.ResourceBundle;
import java.util.Vector;

import javax.wsdl.Binding;
import javax.wsdl.BindingFault;
import javax.wsdl.BindingInput;
import javax.wsdl.BindingOperation;
import javax.wsdl.BindingOutput;
import javax.wsdl.Definition;
import javax.wsdl.Fault;
import javax.wsdl.Input;
import javax.wsdl.Message;
import javax.wsdl.Operation;
import javax.wsdl.Output;
import javax.wsdl.Part;
import javax.wsdl.Port;
import javax.wsdl.PortType;
import javax.wsdl.Service;
import javax.wsdl.Types;
import javax.wsdl.extensions.ExtensibilityElement;
import javax.xml.namespace.QName;

import org.apache.xerces.xs.XSModel;
import org.eclipse.wst.wsdl.validation.internal.util.MessageGenerator;
import org.eclipse.wst.wsdl.validation.internal.wsdl11.xsd.SchemaAttributeTable;
import org.eclipse.wst.wsdl.validation.internal.wsdl11.xsd.XSDValidator;

import com.ibm.wsdl.Constants;
/**
 * Validate the elements defined in a WSDL 1.1 Document.
 */
public class WSDL11BasicValidator implements IWSDL11Validator
{
  protected final String NAMESPACES_FEATURE_ID = "http://xml.org/sax/features/namespaces";
  protected final String VALIDATION_FEATURE_ID = "http://xml.org/sax/features/validation";
  protected final String SCHEMA_VALIDATION_FEATURE_ID = "http://apache.org/xml/features/validation/schema";
  protected final String SCHEMA_FULL_CHECKING_FEATURE_ID =
    "http://apache.org/xml/features/validation/schema-full-checking";
  protected final String CONTINUE_AFTER_FATAL_ERROR_ID = "http://apache.org/xml/features/continue-after-fatal-error";
  protected final String SOAP_ENCODING_URI = "http://schemas.xmlsoap.org/soap/encoding/";
  
  // Error and Warning Keys
  private final String _PORT_NAME_NOT_UNIQUE = "_PORT_NAME_NOT_UNIQUE";
  private final String _NO_BINDING_FOR_PORT = "_NO_BINDING_FOR_PORT";
  private final String _NO_ADDRESS_PORT = "_NO_ADDRESS_PORT";
  private final String _MORE_THEN_ONE_ADDRESS_PORT = "_MORE_THEN_ONE_ADDRESS_PORT"; //TODO should be _MORE_THAN_ONE_ADDRESS_PORT, not THEN
  private final String _PORTTYPE_UNDEFINED_FOR_BINDING = "_PORTTYPE_UNDEFINED_FOR_BINDING";
  private final String _OPERATION_UNDEFINED_FOR_PORTTYPE = "_OPERATION_UNDEFINED_FOR_PORTTYPE";
  private final String _OPERATION_NO_INPUT_OR_OUTPUT = "_OPERATION_NO_INPUT_OR_OUTPUT";
  private final String _INPUT_NAME_NOT_UNIQUE = "_INPUT_NAME_NOT_UNIQUE";
  private final String _MESSAGE_UNDEFINED_FOR_INPUT = "_MESSAGE_UNDEFINED_FOR_INPUT";
  private final String _OUTPUT_NAME_NOT_UNIQUE = "_OUTPUT_NAME_NOT_UNIQUE";
  private final String _MESSAGE_UNDEFINED_FOR_OUTPUT = "_MESSAGE_UNDEFINED_FOR_OUTPUT";
  private final String _MESSAGE_UNDEFINED_FOR_FAULT = "_MESSAGE_UNDEFINED_FOR_FAULT";
  private final String _PART_NO_ELEMENT_OR_TYPE = "_PART_NO_ELEMENT_OR_TYPE";
  private final String _PART_BOTH_ELEMENT_AND_TYPE = "_PART_BOTH_ELEMENT_AND_TYPE";
  private final String _PART_INVALID_ELEMENT = "_PART_INVALID_ELEMENT";
  private final String _PART_INVALID_TYPE = "_PART_INVALID_TYPE";
  private final String _WARN_SOAPENC_IMPORTED_PART = "_WARN_SOAPENC_IMPORTED_PART";

  private final int ELEMENT = 0;
  private final int TYPE = 1;
  
  private final String REQUEST = "Request";
  private final String RESPONSE = "Response";
  private final String QUOTE = "'";
  private final String EMPTY_STRING = "";
  

  //protected WSDL11ValidatorController validatorcontroller;
  protected MessageGenerator messagegenerator;

  /**
   * @see org.eclipse.wst.wsdl.validation.internal.wsdl11.IWSDL11Validator#validate(java.lang.Object, java.util.List, org.eclipse.wsdl.validate.wsdl11.IWSDL11ValidationInfo)
   */
  public void validate(Object element, List parents, IWSDL11ValidationInfo valInfo)
  {
    //this.validatorcontroller = validatorcontroller;
    //setDefaultResourceBundleIfNeeded(validatorcontroller);
    Definition wsdlDefinition = (Definition)element;
    validateTypes(wsdlDefinition, valInfo);
    validateServices(wsdlDefinition, valInfo);
    validateBindings(wsdlDefinition, valInfo);
    validatePortTypes(wsdlDefinition, valInfo);
    validateMessages(wsdlDefinition, valInfo);

  }

  /**
   * Takes a list of ExtensibilityElements and checks if there's a validator 
   * associated with each element and if so calls the validator.
   * 
   * @param parents The list of parents of the elements.
   * @param extensibilityElements The list of elements to validate.
   * @param validatorcontroller The validator controller.
   * @param wsdlDefinition The defnintions element for this document.
   */
  protected void validateExtensibilityElementList(
    List parents,
    List extensibilityElements,
    IWSDL11ValidationInfo valInfo)
  {
    ValidatorRegistry ver = ValidatorRegistry.getInstance();
    Iterator extElems = extensibilityElements.iterator();
    while (extElems.hasNext())
    {
      ExtensibilityElement element = (ExtensibilityElement)extElems.next();
      String namespace = element.getElementType().getNamespaceURI();
      IWSDL11Validator val = ver.queryValidatorRegistry(namespace);
      if (val != null)
       {
        val.validate(element, parents, valInfo);
      }
//      else
//       {
//        valInfo.addNamespaceWithNoValidator(namespace);
//      }
    }
  }

  /**
   * If the resourcebundle hasn't been set, set it to the one registered with the ValidatorController.
   * 
   * @param validatorcontroller The validator controller to get the resource bundle from.
   */
  //  protected void setDefaultResourceBundleIfNeeded(WSDL11ValidatorController validatorcontroller)
  //  {
  //    if (messagegenerator == null)
  //    {
  //      setResourceBundle(validatorcontroller.getResourceBundle());
  //    }
  //  }

  /**
   * Set the resourcebundle to the one specified.
   * 
   * @param rb The resource bundle to set.
   */
  public void setResourceBundle(ResourceBundle rb)
  {
    messagegenerator = new MessageGenerator(rb);
  }

  /**
   * Ensure that the Types element is correct. 
   * 
   * @param wsdlDefinition The definitions element from the current document.
   */

  protected void validateTypes(Definition wsdlDefinition, IWSDL11ValidationInfo valInfo)
  {
    Types types = wsdlDefinition.getTypes();
    // ensure that types is defined
    if (types != null)
    {
      List parents = new Vector();
      parents.add(wsdlDefinition);
      parents.add(0, types);
      validateExtensibilityElementList(parents, types.getExtensibilityElements(), valInfo);
      parents.remove(0);
    }
  }

  /**
   * Validates all of the declared services for the definition.
   * 
   * @param wsdlDefinition The WSDL definitions element.
   */
  protected void validateServices(Definition wsdlDefinition, IWSDL11ValidationInfo valInfo)
  {
    if (wsdlDefinition.getServices() == null)
      return;
    Object services[] = wsdlDefinition.getServices().values().toArray();
    List parents = new Vector();
    parents.add(wsdlDefinition);
    Hashtable allPorts = new Hashtable();

    //TODO: check that ports in other imported files don't conflict with ports in this one
    //    // register all of the imported ports
    //    Iterator imports = wsdlDefinition.getImports().values().iterator();
    //    while(imports.hasNext())
    //    {
    //      Iterator impservices = ((Import)imports.next()).getDefinition().getServices().values().iterator();
    //      while(impservices.hasNext())
    //      {
    //        Iterator impports = ((Service)impservices.next()).getPorts().values().iterator();
    //        while(impports.hasNext())
    //        {
    //          Port tempP = (Port)impports.next();
    //          allPorts.put(tempP.getName(),tempP);	
    //        }
    //      }
    //    }
    for (int i = 0; i < services.length; i++)
    {
      Service s = (Service)services[i];
      parents.add(0, s);
      Object ports[] = s.getPorts().values().toArray();
      for (int j = 0; j < ports.length; j++)
      {
        Port p = (Port)ports[j];
        parents.add(0, p);
        // a Port name must be unique within the entire WDSL document
        if (allPorts.contains(p.getName()))
        {  String[] args = {p.getName()};
          
          valInfo.addError(messagegenerator.getString(_PORT_NAME_NOT_UNIQUE, QUOTE + args[0] + QUOTE),
                            p, _PORT_NAME_NOT_UNIQUE, args);
        }
        else
        {
          allPorts.put(p.getName(), p);

          // get the binding for this port and see if the PortType for the binding
          // is defined
          if (p.getBinding() == null || p.getBinding().isUndefined())
          {
            String bindingName = EMPTY_STRING;
            if (p.getBinding() != null)
            {
              bindingName = p.getBinding().getQName().getLocalPart();
            }
            String args[] = {p.getName()};
            valInfo.addError(
              messagegenerator.getString(_NO_BINDING_FOR_PORT, QUOTE + args[0] + QUOTE, QUOTE + bindingName + QUOTE),
              p, _NO_BINDING_FOR_PORT, args);
          }
          else
          {
            // TODO: Check that the output of one port isn't the input of another and vice versa
            // extensibility elements the port
            // there can only be one and must be one extensibility element defined for a port
            List extelems = p.getExtensibilityElements();
            if (extelems.size() < 1)
            { String args[]= {p.getName()};
              valInfo.addError(messagegenerator.getString(_NO_ADDRESS_PORT, QUOTE + args[0] + QUOTE),
                  p, _NO_ADDRESS_PORT, args);
            }
            else if (extelems.size() > 1)
            {
              for (int k = 1; k < extelems.size(); k++)
              {
                String[] args = {p.getName()};
                valInfo.addError(
                  messagegenerator.getString(_MORE_THEN_ONE_ADDRESS_PORT, QUOTE + args[0] + QUOTE),
                  extelems.get(k), _MORE_THEN_ONE_ADDRESS_PORT, args);
              }
            }
            validateExtensibilityElementList(parents, p.getExtensibilityElements(), valInfo);
          }
        }

        parents.remove(0);
      }
      // extensibility elements for the service
      validateExtensibilityElementList(parents, s.getExtensibilityElements(), valInfo);
      parents.remove(0);
    }
  }

  /**
   * Checks that the bindings refer to valid PortTypes and all of the operations
  // in a given binding refer to a defined operation within the corresponding
  // PortType.
   * 
   * @param wsdlDefinition The WSDL definitions element.
   */
  protected void validateBindings(Definition wsdlDefinition, IWSDL11ValidationInfo valInfo)
  {
    if (wsdlDefinition.getBindings() == null)
      return;
    Object bindings[] = wsdlDefinition.getBindings().values().toArray();
    List parents = new Vector();
    parents.add(wsdlDefinition);
    for (int i = 0; i < bindings.length; i++)
    {
      Binding b = (Binding)bindings[i];
      parents.add(0, b);
      PortType portType = b.getPortType();

      if (portType == null)
      {
        continue;
      }
      // the PortType is not defined so don't bother checking the operations
      if (portType.isUndefined())
      { String[] args = {portType.getQName().getLocalPart(), b.getQName().getLocalPart()};
        valInfo.addError(
          messagegenerator.getString(
            _PORTTYPE_UNDEFINED_FOR_BINDING,
            QUOTE + args[0] + QUOTE,
            QUOTE + args[1] + QUOTE),
          b, _PORTTYPE_UNDEFINED_FOR_BINDING, args);
      }
      else
      {
        // the PortType is defined so now we have to check that the operations are defined
        Object bindingOperations[] = b.getBindingOperations().toArray();

        // check if the operation is defined for each BindingOperation
        for (int k = 0; k < bindingOperations.length; k++)
        {
          BindingOperation bo = (BindingOperation)bindingOperations[k];
          parents.add(0, bo);
          if (bo.getOperation() == null || bo.getOperation().isUndefined())
          {
            String[] args = {b.getQName().getLocalPart(), portType.getQName().getLocalPart()};
            valInfo.addError(
              messagegenerator.getString(
                _OPERATION_UNDEFINED_FOR_PORTTYPE,
                QUOTE + args[0] + QUOTE,
                QUOTE + args[1] + QUOTE),
              bo, _OPERATION_UNDEFINED_FOR_PORTTYPE, args);
            // nice idea to add suggestions to other elements to fix the error
            // but it doesn't work with multipe files like this
            //addValidationMessage(warningList,portType,portType.getQName().getLocalPart() + "Define an operation here to correspond with the operation in: " + bo.getName());
          }
          // take care of all the extensibility elements in the binding operation, binding inputs, outputs and faults
          else
          {
            BindingInput binput = bo.getBindingInput();
            if (binput != null)
            {
              parents.add(0, binput);
              // extensibility elements for binding operation input
              validateExtensibilityElementList(
                parents,
                bo.getBindingInput().getExtensibilityElements(),
                valInfo);
              parents.remove(0);
            }
            BindingOutput boutput = bo.getBindingOutput();
            if (boutput != null)
            {
              parents.add(0, boutput);
              // extensibility elements for binding operation output
              validateExtensibilityElementList(
                parents,
                bo.getBindingOutput().getExtensibilityElements(),
                valInfo);
              parents.remove(0);
            }
            // no input or output has been defined for the operation
            if (binput == null && boutput == null)
            { String[] args = { bo.getName() };
              valInfo.addError(
                messagegenerator.getString(_OPERATION_NO_INPUT_OR_OUTPUT, QUOTE + args[0] + QUOTE),
                bo, _OPERATION_NO_INPUT_OR_OUTPUT, args);
            }
            // extensibility elements for each binding operation fault
            Iterator faults = bo.getBindingFaults().values().iterator();
            while (faults.hasNext())
            {
              BindingFault bf = (BindingFault)faults.next();
              parents.add(0, bf);
              validateExtensibilityElementList(parents, bf.getExtensibilityElements(), valInfo);
              parents.remove(0);
            }
          }
          // extensibility elements for binding operation
          validateExtensibilityElementList(parents, bo.getExtensibilityElements(), valInfo);
          parents.remove(0);
        }
      }
      // extensibility elements for the binding
      validateExtensibilityElementList(parents, b.getExtensibilityElements(), valInfo);
      parents.remove(0);
    }

  }

  /**
   * Check that all of the PortTypes have valid messages associated with their
  // operation input, output and fault types.
   * 
   * @param wsdlDefinition The WSDL definitions element.
   */
  protected void validatePortTypes(Definition wsdlDefinition, IWSDL11ValidationInfo valInfo)
  {
    if (wsdlDefinition.getPortTypes() == null)
      return;
    Object porttypes[] = wsdlDefinition.getPortTypes().values().toArray();

    for (int i = 0; i < porttypes.length; i++)
    {
      PortType p = (PortType)porttypes[i];
      Object operations[] = p.getOperations().toArray();
      List inAndOutNames = new Vector();
      for (int j = 0; j < operations.length; j++)
      {
        Operation o = (Operation)operations[j];
        if (o == null || o.isUndefined())
        {
          continue;
        }

        // check that the messages are defined for the input, output and faults
        Message m;
        Input input = o.getInput();
        if (input != null)
        {
          String inputName = input.getName();
          // if the name isn't defined it defaults to this
          if (inputName == null)
          {
            inputName = o.getName() + REQUEST;
          }
          if (inAndOutNames.contains(inputName))
          { String[] args = {inputName, p.getQName().getLocalPart() };
            valInfo.addError(
              messagegenerator.getString(
                _INPUT_NAME_NOT_UNIQUE,
                QUOTE + args[0] + QUOTE,
                QUOTE + args[1] + QUOTE),
              input, _INPUT_NAME_NOT_UNIQUE, args);
          }
          else
          {
            inAndOutNames.add(inputName);
          }

          m = input.getMessage();
          if (m != null && m.isUndefined())
          {
            String messName = EMPTY_STRING;
            QName messQName = m.getQName();
            if (messQName != null)
            {
              messName = messQName.getLocalPart();
            }
            String[] args = {messName};
            valInfo.addError(messagegenerator.getString(_MESSAGE_UNDEFINED_FOR_INPUT, QUOTE + args[0] + QUOTE),
                input, _MESSAGE_UNDEFINED_FOR_INPUT, args);
          }
        }
        Output output = o.getOutput();
        if (output != null)
        {
          String outputName = output.getName();
          // if the name isn't defined it defaults to this
          if (outputName == null)
          {
            outputName = o.getName() + RESPONSE;
          }

          if (inAndOutNames.contains(outputName))
          {
            String[] args = {outputName, p.getQName().getLocalPart()};
            
            valInfo.addError(
              messagegenerator.getString(
                _OUTPUT_NAME_NOT_UNIQUE,
                QUOTE + args[0] + QUOTE,
                QUOTE + args[1] + QUOTE),
              output, _OUTPUT_NAME_NOT_UNIQUE, args);
          }
          else
          {
            inAndOutNames.add(outputName);
          }

          m = output.getMessage();
          if (m != null && m.isUndefined())
          {
            String messName = EMPTY_STRING;
            QName messQName = m.getQName();
            if (messQName != null)
            {
              messName = messQName.getLocalPart();
            }
            String[] args = {messName};
            valInfo.addError(messagegenerator.getString(_MESSAGE_UNDEFINED_FOR_OUTPUT, QUOTE + args[0] + QUOTE),
                output, _MESSAGE_UNDEFINED_FOR_OUTPUT, args);
          }
        }

        Object faults[] = o.getFaults().values().toArray();

        //List faultNames = new Vector();
        for (int k = 0; k < faults.length; k++)
        {
          Fault f = (Fault)faults[k];
          m = f.getMessage();
          if (m != null && m.isUndefined())
          {
            String messName = EMPTY_STRING;
            QName messQName = m.getQName();
            if (messQName != null)
            {
              messName = messQName.getLocalPart();
            }
            String args[] = {messName};
            valInfo.addError(messagegenerator.getString(_MESSAGE_UNDEFINED_FOR_FAULT, QUOTE + args[0] + QUOTE),
                f, _MESSAGE_UNDEFINED_FOR_FAULT, args);
          }
        }
      }
    }
  }

  /**
   * Check that all the messages defined in the WSDL document are valid.
   * 
   * @param wsdlDefinition The WSDL definitions element.
   */
  protected void validateMessages(Definition wsdlDefinition, IWSDL11ValidationInfo valInfo)
  {
    if (wsdlDefinition.getMessages() == null)
      return;
    Iterator messages = wsdlDefinition.getMessages().values().iterator();

    while (messages.hasNext())
    {
      Message m = (Message)messages.next();
      if (!m.isUndefined())
      {
        // if the message has a part (and it doesn't have to)
        // ensure each message part has either an element or a type
        if (!m.getParts().isEmpty())
        {
          Iterator parts = m.getParts().values().iterator();
          while (parts.hasNext())
          {
            Part p = (Part)parts.next();
            QName elementName = p.getElementName();
            QName typeName = p.getTypeName();
            Map extAtts = p.getExtensionAttributes();
            // TODO:This will have to be extended as parts can have extensibility elements
            //ensure the part has a type or an element defined
            if (elementName == null && typeName == null && (extAtts == null || extAtts.isEmpty()))
            { String[] args = { p.getName()};
              valInfo.addError(messagegenerator.getString(_PART_NO_ELEMENT_OR_TYPE, QUOTE + args[0] + QUOTE),
                  p, _PART_NO_ELEMENT_OR_TYPE, args);
            }
            //here the part has both the element and type defined and it can only have one defined	
            else if (elementName != null && typeName != null)
            { String[] args = {p.getName()};
              valInfo.addError(messagegenerator.getString(_PART_BOTH_ELEMENT_AND_TYPE, QUOTE + args[0] + QUOTE),
                  p, _PART_BOTH_ELEMENT_AND_TYPE, args);
            }
            else if (elementName != null)
            {
              if (!checkPartConstituent(elementName.getNamespaceURI(),
                elementName.getLocalPart(),
                ELEMENT,
                p,
                valInfo))
              { String[] args = {p.getName(), elementName.getLocalPart()};
                valInfo.addError(
                  messagegenerator.getString(
                    _PART_INVALID_ELEMENT,
                    QUOTE + args[0] + QUOTE,
                    QUOTE + args[1] + QUOTE),
                  p, _PART_INVALID_ELEMENT, args);
              }
            }
            else if (typeName != null)
            {
              // check that the type itself is defined properly
              if (!checkPartConstituent(typeName.getNamespaceURI(), typeName.getLocalPart(), TYPE, p, valInfo))
              { String[] args = {p.getName(), typeName.getLocalPart() }; 
                valInfo.addError(
                  messagegenerator.getString(
                    _PART_INVALID_TYPE,
                    QUOTE + args[0] + QUOTE,
                    QUOTE + args[1] + QUOTE),
                  p, _PART_INVALID_TYPE, args);
              }
            }
          }
        }
      }
    }
  }

  /**
   * Checks whether the given name is defined in the namespace for the part.  A part is an
   * ELEMENT or a TYPE.
   * 
   * @param namespace The namespace to check.
   * @param name The name to check.
   * @param part The part to check, either ELEMENT or TYPE.
   * @param partObject The object representing the given part.
   * @return True if the part element of type is defined, false otherwise.
   */
  protected boolean checkPartConstituent(
    String namespace,
    String name,
    int part,
    Part partObject,
    IWSDL11ValidationInfo valInfo)
  {

    boolean partvalid = false;
    // First take care of the situation where it's from the schema namespace.
    // The 1999, 2000 and 2001 schema namespaces are all accepted.
    if (namespace.equals(Constants.NS_URI_XSD_2001)
      || namespace.equals(Constants.NS_URI_XSD_1999)
      || namespace.equals(Constants.NS_URI_XSD_2000))
    {
      SchemaAttributeTable xsdTable = new SchemaAttributeTable();
      if (xsdTable.containsSymbol(name))
      {
        partvalid = true;
      }
    }
    // check inline and imported schema
    else
    {
      XSModel[] schemas = valInfo.getSchemas();
      int numSchemas = schemas.length;
      //Iterator schemasIter = schemas.iterator();
      for (int i = 0; i < numSchemas; i++)
      {
        XSModel schema = schemas[i];
        if (schema != null)
        {
          if (part == ELEMENT && schema.getElementDeclaration(name, namespace) != null)
          {
            partvalid = true;
            break;
          }
          else if (part == TYPE && schema.getTypeDefinition(name, namespace) != null)
          {
            partvalid = true;
            break;
          }
        }
      }
    }
    // If the SOAP encoding namespace hasn't been explicitly imported do so
	// now.
    // Allow the SOAP encoding namespace to be automatically imported but mark
	// it as a warning.
    if (!partvalid && namespace.equals(SOAP_ENCODING_URI))
    {
      try
      {
        XSDValidator xsdVal = new XSDValidator();
        String soapEnc = valInfo.getURIResolver().resolve("", SOAP_ENCODING_URI, null).getPhysicalLocation();
        if(soapEnc != null)
        {
          xsdVal.validate(soapEnc, null, valInfo.getSchemaCache());
          // sanity check in case something goes wrong
          if (xsdVal.isValid())
          {
            XSModel xsModel = xsdVal.getXSModel();

            if (part == ELEMENT && xsModel.getElementDeclaration(name, namespace) != null)
            {
              partvalid = true;
            }
            else if (part == TYPE && xsModel.getTypeDefinition(name, namespace) != null)
            {
              partvalid = true;
            }
            valInfo.addWarning(messagegenerator.getString(_WARN_SOAPENC_IMPORTED_PART, QUOTE + name + QUOTE), partObject);
          }
        }
      }
      catch (Exception e)
      {
        //TODO: log the error message
        //System.out.println(e);
      }
    }
    return partvalid;
  }

}
