/*-------------------------------------------------------------------------------
Copyright (c)2000 TogetherSoft Corporation. Patents pending. All rights reserved.
-------------------------------------------------------------------------------*/

package com.togethersoft.modules.patterns.UNIVERSAL.MEMBER.Property;

import java.util.Enumeration;
import java.util.Vector;

import com.togethersoft.openapi.sci.*;

import com.togethersoft.openapi.sci.enum.SciParameterEnumeration;
import com.togethersoft.openapi.sci.enum.SciOperationEnumeration;
import com.togethersoft.openapi.sci.enum.SciAttributeEnumeration;

import com.togethersoft.openapi.sci.pattern.SciPattern;
import com.togethersoft.openapi.sci.pattern.SciPatternUtil;
import com.togethersoft.openapi.sci.pattern.SciPatternProperty;

import com.togethersoft.openapi.util.propertyMap.Property;
import com.togethersoft.openapi.util.propertyMap.PropertyMap;

import com.togethersoft.openapi.ide.message.IdeMessageManagerAccess;
import com.togethersoft.openapi.ide.message.IdeMessageType;

import com.togethersoft.modules.patterns.UNIVERSAL.PatternBase;
import com.togethersoft.modules.patterns.UNIVERSAL.PatternBaseException;
import com.togethersoft.modules.patterns.UNIVERSAL.PatternUIBuilder;

/**
 * Property pattern
 * @author TogetherSoft
 */
public class Pattern extends PatternBase implements SciPattern {

    private static final String PATTERN_NAME = "Property";

    public Pattern() {
        setPatternDisplayName(PATTERN_NAME);

        setPropertyValue(NAME, PROPERTY.toLowerCase());
        setPropertyValue(TYPE, INT);
        setPropertyValue(GET_METHOD, Boolean.TRUE);
        setPropertyValue(SET_METHOD, Boolean.TRUE);
        setPropertyValue(ATTRIBUTE, Boolean.TRUE);
        setPropertyValue(USE_MY_PREFIX, Boolean.FALSE);
    }

    protected void finalize() throws Throwable {
        super.finalize();

        if (myUIBuilder != null) {
            myUIBuilder.removeAllListenedInspectorProperties();
            myUIBuilder = null;
        }

        myClass = null;
        myGetMethod = null;
        mySetMethod = null;
        myAttribute = null;
    }

    public boolean prepare() {
        try {
            super.prepare();
            notImplementedForIDL();

            if (!(getContainer() instanceof SciClass)) {
                return false;
            }

            myClass = (SciClass) getContainer();
            cannotApplyToInterface(myClass); // [VZ] SCR# 19232 fixed

            myGetMethod = null;
            mySetMethod = null;
            myAttribute = null;

            setPropertyValue(NAME, PROPERTY.toLowerCase());
            setPropertyValue(TYPE, INT);
            setPropertyValue(GET_METHOD, Boolean.TRUE);
            setPropertyValue(SET_METHOD, Boolean.TRUE);
            setPropertyValue(ATTRIBUTE, Boolean.TRUE);
            setPropertyValue(USE_MY_PREFIX, Boolean.FALSE);

            SciElement element = getElement();
            if (element instanceof SciAttribute) {
                myAttribute = (SciAttribute) element;
                String name = myAttribute.getName();
                boolean useMyPrefix = false;
                if (name.startsWith(PREFIX_MY)) {
                    name = SciPatternUtil.decapitalize(name.substring(PREFIX_MY.length()));
                    useMyPrefix = true;
                }

                String type = myAttribute.getType().getCanonicalText();

                setPropertyValue(USE_MY_PREFIX, useMyPrefix ? Boolean.TRUE : Boolean.FALSE);
                setPropertyValue(NAME, name);
                setPropertyValue(TYPE, type);

                myGetMethod = findGetMethod(name, type);
                mySetMethod = findSetMethod(name, type);
            }
            else if (element instanceof SciOperation) {
                SciOperation op = (SciOperation) element;
                String name = null;
                int prefixLen;
                if (op.getName().startsWith(PREFIX_GET)) {
                    prefixLen = PREFIX_GET.length();
                }
                else if (op.getName().startsWith(PREFIX_SET)) {
                    prefixLen = PREFIX_SET.length();
                }
                else if (op.getName().startsWith(PREFIX_IS)) {
                    prefixLen = PREFIX_IS.length();
                }
                else {
                    return false;
                }
                name = SciPatternUtil.decapitalize(op.getName().substring(prefixLen));

                String type = null;
                if (!op.getName().startsWith(PREFIX_SET)) {
                    type = op.getReturnType().getCanonicalText();
                }
                else {
                    SciParameterEnumeration parms = op.getParameterList().parameters();
                    if (!parms.hasMoreElements()) {
                        return false;
                    }
                    type = parms.nextSciParameter().getType().getCanonicalText();
                }

                myGetMethod = findGetMethod(name, type);
                mySetMethod = findSetMethod(name, type);
                if (!element.equals(myGetMethod) && !element.equals(mySetMethod)) {
                    return false;
                }

                setPropertyValue(NAME, name);
                setPropertyValue(TYPE, type);

                myAttribute = findAttribute(name, type, getBooleanPropertyValue(USE_MY_PREFIX));
            }
            else {
                setPropertyValue(NAME, PROPERTY.toLowerCase());
                setPropertyValue(TYPE, INT);
            }

            if (element != null) {
                setPropertyValue(GET_METHOD, myGetMethod != null ? Boolean.TRUE : Boolean.FALSE);
                setPropertyValue(SET_METHOD, mySetMethod != null ? Boolean.TRUE : Boolean.FALSE);
                setPropertyValue(ATTRIBUTE, myAttribute != null ? Boolean.TRUE : Boolean.FALSE);
            }
            else {
                setPropertyValue(GET_METHOD, Boolean.TRUE);
                setPropertyValue(SET_METHOD, Boolean.TRUE);
                setPropertyValue(ATTRIBUTE, myClass.hasProperty(SciProperty.INTERFACE) ? Boolean.FALSE : Boolean.TRUE);
            }

            if (initializeInspector())
                return true;
            else
                return false;
        }
        catch(PatternBaseException e) {
            return false;
        }
    }

    public boolean canApply() {
        try {
            identifierShouldBeCorrect(NAME);

            String type = getStringPropertyValue(TYPE);
            if (type == null || type.length() == 0 || VOID.equals(type)) {
                return false;
            }

            if (!isPureType(type)) {
                throw new PatternBaseException("Property type should be a pure type.");
            }

            boolean attributeFlag = getBooleanPropertyValue(ATTRIBUTE);
            boolean getMethodFlag = getBooleanPropertyValue(GET_METHOD);
            boolean setMethodFlag = getBooleanPropertyValue(SET_METHOD);
            if (!attributeFlag && !getMethodFlag && !setMethodFlag) {
                return false;
            }

            return true;
        }
        catch(PatternBaseException e) {
            return false;
        }
    }

    public void apply() {
        if (!canApply()) {
            return;
        }
        super.apply();

        // clear UI
        myUIBuilder.removeAllListenedInspectorProperties();
        myUIBuilder = null;

        String name = getStringPropertyValue(NAME);
        String type = getStringPropertyValue(TYPE);
        String oldAttributeName = (myAttribute != null) ? myAttribute.getName() : null;

        Vector memberVector = new Vector();

        SciAttribute attribute      = null;
        SciOperation getOperation   = null;
        SciOperation setOperation   = null;

        boolean attributeFlag = getBooleanPropertyValue(ATTRIBUTE);
        boolean getMethodFlag = getBooleanPropertyValue(GET_METHOD);
        boolean setMethodFlag = getBooleanPropertyValue(SET_METHOD);
        boolean useMyPrefixFlag = getBooleanPropertyValue(USE_MY_PREFIX);
        boolean booleanPropertyFlag = getLanguageSpecificBooleanStatement().equals(type);

        String attributeName = useMyPrefixFlag ? (PREFIX_MY + capitalize(name)) : name;
        if (myAttribute == null) {
            // create new attribute
            attribute = getFactory().newAttribute();
            attribute.setName(attributeName);
            attribute.getType().setText(type);

            memberVector.addElement(attribute);
        }
        else {
            // correct existing attribute
            if (!myAttribute.getName().equals(attributeName)) {
                myAttribute.setName(attributeName);
            }
            if (!myAttribute.getType().getText().equals(type)) {
                myAttribute.getType().setText(type);
            }

            memberVector.addElement(myAttribute.copy());
        }

        /////////////////////////////////////////////////
        // Create/modify GET method
        /////////////////////////////////////////////////
        if (getMethodFlag) {
            String getName = (booleanPropertyFlag ? PREFIX_IS : PREFIX_GET) + capitalize(name);
            if (myGetMethod == null) {
                // generate new get method
                getOperation = getFactory().newOperation();
                getOperation.setName(getName);
                getOperation.getReturnType().setText(type);
                if (myAttribute != null) {
                    // we don't need operation body at this stage
                }
                else if (myClass.hasProperty(SciProperty.ABSTRACT)) {
                    getOperation.setProperty(SciProperty.ABSTRACT, true);
                }
                else {
                    SciPatternUtil.makeStubImplementation(getOperation);
                }

                memberVector.addElement(getOperation);
            }
            else {
                // correct existing get method
                if (!myGetMethod.getName().equals(getName)) {
                    myGetMethod.setName(getName);
                }

                if (!myGetMethod.getReturnType().getCanonicalText().equals(type)) {
                    myGetMethod.getReturnType().setText(type);
                }

                if (myAttribute != null && oldAttributeName != null && !myAttribute.getName().equals(oldAttributeName)) {
                    // replace old attribute name with new one
                    SciCodeBlock body = myGetMethod.getBody();
                    if (body != null) {
                        String newBody = SciPatternUtil.replace(body.getText(),
                            oldAttributeName, myAttribute.getName(), /*caseSensitive=*/true);
                        try {
                            myGetMethod.setBody(getGenericFactory().newCodeBlock(newBody));
                        }
                        catch (SciGenericFactoryException e) {
                            IdeMessageManagerAccess.printMessage(IdeMessageType.ERROR, CODE_GENERATION_ERROR);
                            return;
                        }
                    }
                }

                memberVector.addElement(myGetMethod.copy());
            }
        }
        else { // delete existing get method
            if (myGetMethod != null) {
                myGetMethod.delete();
                myGetMethod = null;
            }
        }

        /////////////////////////////////////////////////
        // Create/modify SET method
        /////////////////////////////////////////////////
        if (setMethodFlag) {
            String setName = PREFIX_SET + capitalize(name);
            if (mySetMethod == null) {
                // generate new set method
                setOperation = getFactory().newOperation();
                setOperation.setName(setName);
                setOperation.getReturnType().setText(VOID);

                SciParameter parm = getFactory().newParameter();
                parm.setName(name);
                parm.getType().setText(type);
                setOperation.getParameterList().paste(parm, null, false);

                if (myAttribute != null) {
                    // we don't need setOperation body at this stage
                }
                else if (myClass.hasProperty(SciProperty.ABSTRACT)) {
                    setOperation.setProperty(SciProperty.ABSTRACT, true);
                }
                else {
                    SciPatternUtil.makeStubImplementation(setOperation);
                }

                memberVector.addElement(setOperation);
            }
            else {
                // correct existing set method
                if (!mySetMethod.getName().equals(setName)) {
                    mySetMethod.setName(setName);
                }
                mySetMethod.getReturnType().setText(VOID);

                SciParameterEnumeration params = mySetMethod.getParameterList().parameters();
                if (params.hasMoreElements()) {
                    SciType parmType = params.nextSciParameter().getType();
                    if (!parmType.getCanonicalText().equals(type)) {
                        parmType.setText(type);
                    }
                }
                if (myAttribute != null && oldAttributeName != null && !myAttribute.getName().equals(oldAttributeName)) {
                    // making textual replacement!
                    SciCodeBlock body = mySetMethod.getBody();
                    if (body != null) {
                        String newBody = SciPatternUtil.replace(body.getText(),
                            oldAttributeName, myAttribute.getName(), true);
                        try {
                            mySetMethod.setBody(getGenericFactory().newCodeBlock(newBody));
                        }
                        catch (SciGenericFactoryException e) {
                            IdeMessageManagerAccess.printMessage(IdeMessageType.ERROR, CODE_GENERATION_ERROR);
                            return;
                        }
                    }
                }

                memberVector.addElement(mySetMethod.copy());
            }
        }
        else { // delete existing set method
            if (mySetMethod != null) {
                mySetMethod.delete();
                mySetMethod = null;
            }
        }

        boolean tryToKeepAttributeName = (myAttribute != null) ? true : false;
        String propertyName = findGoodPropertyName(myClass, memberVector, tryToKeepAttributeName);

        if (tryToKeepAttributeName && propertyName.startsWith(PREFIX_MY)) {
            propertyName = SciPatternUtil.decapitalize(propertyName.substring(PREFIX_MY.length()));
        }

        attributeName = useMyPrefixFlag ? (PREFIX_MY + capitalize(propertyName)) : propertyName;

        if (myAttribute == null) {
            attribute.setName(attributeName);
            myAttribute = (SciAttribute) myClass.paste(attribute, null, false);
        }
        else {
            myAttribute.setName(attributeName);
        }
        myAttribute.setProperty(SciProperty.PRIVATE, true);

        boolean isPrimitivePropertyType = getLanguageHelper().isPrimitiveType(myAttribute.getType().getReferenceText());
        if (!isPrimitivePropertyType) {
            // create attribute for COMPLEX types as reference
            myAttribute.setType( getLanguageHelper().makeReferenceType(myAttribute.getType()) );
        }

        if (getMethodFlag) {
            String getOperationName = booleanPropertyFlag ? PREFIX_IS : PREFIX_GET;
            getOperationName += capitalize(propertyName);
            if (myGetMethod == null) {
                myGetMethod = SciPatternUtil.createGetMethod(myAttribute);
            }
            myGetMethod.setName(getOperationName);
            myGetMethod.setProperty(SciProperty.PUBLIC, true);

            if (!attributeFlag) { // empty body
                try {
                    String stubBody = "return ";
                    stubBody += isPrimitivePropertyType ? "0" : getLanguageSpecificNullStatement();
                    stubBody += ";";
                    myGetMethod.setBody(getGenericFactory().newCodeBlock(stubBody));
                }
                catch (SciGenericFactoryException e) {
                    IdeMessageManagerAccess.printMessage(IdeMessageType.ERROR, CODE_GENERATION_ERROR);
                    return;
                }
            }
        }

        if (setMethodFlag) {
            String setOperationName = PREFIX_SET + capitalize(propertyName);
            if (mySetMethod == null) {
                mySetMethod = SciPatternUtil.createSetMethod(myAttribute);
            }
            mySetMethod.setName(setOperationName);
            mySetMethod.setProperty(SciProperty.PUBLIC, true);

            if (!attributeFlag) { // empty body
                try {
                    mySetMethod.setBody(getGenericFactory().newCodeBlock(EMPTY_STRING));
                }
                catch (SciGenericFactoryException e) {
                    IdeMessageManagerAccess.printMessage(IdeMessageType.ERROR, CODE_GENERATION_ERROR);
                    return;
                }
            }
        }

        if (!attributeFlag && myAttribute != null) {
            myAttribute.delete();
            myAttribute = null;
        }

        // restore "right" attribute
        if(myAttribute != null) {
            myAttribute.getType().setText( myAttribute.getType().getReferenceText() );
        }

        // Set results
        setPropertyValue(SciPatternProperty.RESULT_ELEMENT, myAttribute);
        setPropertyValue(SciPatternProperty.RESULT_ELEMENTS, null);
        if (myGetMethod != null) {
            addPropertyValue(SciPatternProperty.RESULT_ELEMENTS, myGetMethod);
        }
        if (mySetMethod != null) {
            addPropertyValue(SciPatternProperty.RESULT_ELEMENTS, mySetMethod);
        }
        if (myAttribute != null) {
            addPropertyValue(SciPatternProperty.RESULT_ELEMENTS, myAttribute);
        }

        myClass = null;
        myAttribute = null;
        myGetMethod = null;
        mySetMethod = null;
        memberVector = null;
    }

    private SciAttribute findAttribute(String propertyName, String propertyType, boolean useMyPrefix) {
        if (propertyName.length() == 0) {
            return null;
        }
        String name = propertyName;
        if (useMyPrefix) {
            name = PREFIX_MY + capitalize(name);
        }

        SciAttributeEnumeration enum = myClass.attributes();
        while (enum.hasMoreElements()) {
            SciAttribute attr = enum.nextSciAttribute();
            if (!attr.getName().equals(name)) continue;
            if (!attr.getType().getCanonicalText().equals(propertyType)) continue;

            return attr;
        }
        return null;
    }

    private SciOperation findGetMethod(String propertyName, String propertyType) {
        if (propertyName == null || propertyName.length() == 0) {
            return null;
        }

        String name = (BOOLEAN.equals(propertyType) ? PREFIX_IS : PREFIX_GET) + capitalize(propertyName);
        SciOperationEnumeration enum = myClass.operations();
        while (enum.hasMoreElements()) {
            SciOperation op = enum.nextSciOperation();
            if (!op.getName().equals(name)) continue;
            if (op.getParameterList().parameters().hasMoreElements()) continue;
            if (!op.getReturnType().getCanonicalText().equals(propertyType)) continue;

            return op;
        }
        return null;
    }

    private SciOperation findSetMethod(String propertyName, String propertyType) {
        if (propertyName == null || propertyName.length() == 0) {
            return null;
        }

        String name = PREFIX_SET + capitalize(propertyName);
        SciOperationEnumeration enum = myClass.operations();
        while (enum.hasMoreElements()) {
            SciOperation op = enum.nextSciOperation();
            if (!op.getName().equals(name)) continue;
            SciParameterEnumeration parms = op.getParameterList().parameters();
            if (!parms.hasMoreElements()) continue;
            if (!parms.nextSciParameter().getType().getCanonicalText().equals(propertyType)) continue;
            if (parms.hasMoreElements()) continue;
            if (!op.getReturnType().getCanonicalText().equals(VOID)) continue;

            return op;
        }

        return null;
    }

    private static String capitalize(String name) {
        if (name == null || name.length() == 0) {
            return name;
        }
        return Character.toUpperCase(name.charAt(0)) + name.substring(1);
    }

    protected boolean initializeInspector() {
        try {
            myUIBuilder = null;
            myUIBuilder = createUIBuilder(true);

            Vector inspectorPropertiesVector = new Vector();

            // Create page
            String pageName1 = "Pattern properties";
            if (myUIBuilder.addInspectorPage(pageName1, PatternUIBuilder.UIPresentation.Table) == null) {
                throw new PatternBaseException(CANNOT_CREATE_PATTERN_UI);
            }

            if (myUIBuilder.addPropertyToPage(pageName1, NAME, NAME,
                PatternUIBuilder.PropertyType.String) == null) {
                throw new PatternBaseException(CANNOT_CREATE_PATTERN_UI);
            }
            inspectorPropertiesVector.addElement(NAME);

            if (myUIBuilder.addPropertyToPage(pageName1, TYPE, TYPE,
                PatternUIBuilder.PropertyType.String) == null) {
                throw new PatternBaseException(CANNOT_CREATE_PATTERN_UI);
            }
            inspectorPropertiesVector.addElement(TYPE);

            if (myUIBuilder.addPropertyToPage(pageName1, GET_METHOD, GET_METHOD,
                PatternUIBuilder.PropertyType.Boolean) == null) {
                throw new PatternBaseException(CANNOT_CREATE_PATTERN_UI);
            }
            inspectorPropertiesVector.addElement(GET_METHOD);

            if (myUIBuilder.addPropertyToPage(pageName1, SET_METHOD, SET_METHOD,
                PatternUIBuilder.PropertyType.Boolean) == null) {
                throw new PatternBaseException(CANNOT_CREATE_PATTERN_UI);
            }
            inspectorPropertiesVector.addElement(SET_METHOD);

            if (!myClass.hasProperty(SciProperty.INTERFACE)) {
                if (myUIBuilder.addPropertyToPage(pageName1, ATTRIBUTE, ATTRIBUTE,
                    PatternUIBuilder.PropertyType.Boolean) == null) {
                    throw new PatternBaseException(CANNOT_CREATE_PATTERN_UI);
                }
                inspectorPropertiesVector.addElement(ATTRIBUTE);
                /*
                if (myUIBuilder.addPropertyToPage(pageName1, USE_MY_PREFIX, USE_MY_PREFIX,
                    PatternUIBuilder.PropertyType.Boolean) == null) {
                    throw new PatternBaseException(CANNOT_CREATE_PATTERN_UI);
                }
                inspectorPropertiesVector.addElement(USE_MY_PREFIX);
                */
            }

            myUIBuilder.setCreatedPatternUI();
            myUIBuilder.assignListenedInspectorProperties(inspectorPropertiesVector);
            return true;
        }
        catch (PatternBaseException ex) {
            myUIBuilder = null;
            getIdeInspector().clear();
            return false;
        }
    }

    private String getNameWithoutDigitalSuffix(String name) {
        int last = name.length() - 1;
        while (Character.isDigit(name.charAt(last))) {
            last--;
        }
        return name.substring(0, last + 1);
    }

    private int getDigitalNameSuffix(String name) {
        String pureName = getNameWithoutDigitalSuffix(name);
        if (pureName.equals(name)) {
            return -1;
        }
        else {
            int pureNameLen = pureName.length();
            return Integer.parseInt(name.substring(pureNameLen));
        }
    }

    private String findGoodPropertyName(SciClass targetClass, Vector memberToPasteVector, boolean tryToKeepAttributeName) {
        if (targetClass == null) {
            return null;
        }
        if (memberToPasteVector == null || memberToPasteVector.size() == 0) {
            return null;
        }

        Vector pureNameVector = new Vector(memberToPasteVector.size());
        String nameWithoutDigitalSuffix = null;
        String purePropertyName = null;
        SciMember propertyMember = null;
        boolean targetClassUsesCurrentName = false;

        Enumeration members = memberToPasteVector.elements();
        while (members.hasMoreElements()) {
            Object item = members.nextElement();
            if (item == null) {
                continue;
            }

            if (!(item instanceof SciMember)) {
                return null; // error !
            }
            if (item instanceof SciAttribute) {
                propertyMember = (SciMember) item;
            }

            if (SciUtil.findMemberBySignature(targetClass, (SciMember)item) != null) {
                targetClassUsesCurrentName = true;
            }
            // fill "pure" name Vector
            nameWithoutDigitalSuffix = getNameWithoutDigitalSuffix(((SciMember)item).getName());
            pureNameVector.addElement(nameWithoutDigitalSuffix);

            if (item instanceof SciAttribute) {
                propertyMember = (SciMember) item;
                purePropertyName = nameWithoutDigitalSuffix;
            }
        }

        if (propertyMember == null) {
            return null;
        }

        String goodPropertyName = null;
        if (tryToKeepAttributeName) {
            goodPropertyName = propertyMember.getName();
        }
        else {
            goodPropertyName = getLanguageHelper().inquirePasteName(targetClass, propertyMember);
        }

        if (!targetClassUsesCurrentName) {
            return propertyMember.getName();
        }

        int nameSuffix = getDigitalNameSuffix(goodPropertyName);
        if (nameSuffix == -1) {
            nameSuffix = 0;
        }

        boolean goodNameFound = false;
        boolean memberExists = false;
        boolean firstIteration = true;
        String fullMemberName = null;
        SciMember member = null;

        do {
            memberExists = false;
            for (int i = 0; i < memberToPasteVector.size(); i++) {
                member = (SciMember) memberToPasteVector.elementAt(i);

                fullMemberName = (String)pureNameVector.elementAt(i);
                if (nameSuffix > 0) {
                    fullMemberName += String.valueOf(nameSuffix);
                }
                member.setName(fullMemberName);
                if (!fullMemberName.equals(getLanguageHelper().inquirePasteName(targetClass, member))) {
                    if (tryToKeepAttributeName && firstIteration && (member instanceof SciAttribute)) {
                        continue;
                    }

                    // go to next iteration
                    memberExists = true;
                    break;
                }
            }

            if (memberExists) {
                nameSuffix++;
                firstIteration = false;
                continue;
            }

            goodPropertyName = purePropertyName;
            if (nameSuffix > 0) {
                goodPropertyName += String.valueOf(nameSuffix);
            }
            goodNameFound = true;
        }
        while (!goodNameFound);

        return goodPropertyName;
    }

    private boolean isPureType(String type) {
        if (type.indexOf("&") >= 0 || type.indexOf("*") >= 0) {
            return false;
        }
        else return true;
    }

    private PatternUIBuilder myUIBuilder = null;

    private SciClass        myClass = null;
    private SciAttribute    myAttribute = null;
    private SciOperation    myGetMethod = null;
    private SciOperation    mySetMethod = null;

    private static final String NAME        = "Name";
    private static final String TYPE        = "Type";
    private static final String GET_METHOD  = "Get method";
    private static final String SET_METHOD  = "Set method";

    private static final String USE_MY_PREFIX = "Use \"my\" prefix in attribute name";
}
